import { Page, expect } from "@playwright/test"
import { selectOption, comboboxByLabel } from "../support/ui"

// Locators verified against Frontend/erp-system/app/dashboard/stock/transfers/new/page.tsx,
// .../transfers/[id]/page.tsx, and .../stock/adjustments/new/page.tsx.
// Every page here intermittently throws a real React hydration error (#418) that blanks a
// random subset of Select triggers' placeholder text for that page's lifetime, without
// affecting their sibling <Label> or role="combobox" attribute (support/ui.ts has the full
// writeup). Triggers are located via comboboxByLabel() (label + role, no name lookup) instead
// of getByRole("combobox", { name }); the row-scoped item combo has no adjacent label and is
// instead found by position (it's the first combobox in the row).
export class StockTransferNewPage {
  constructor(private readonly page: Page) {}

  async goto() {
    await this.page.goto("/dashboard/stock/transfers/new")
  }

  async fill(opts: { fromWarehouse: string; toWarehouse: string; item: string; qty: number }) {
    await selectOption(this.page, comboboxByLabel(this.page, "From warehouse"), opts.fromWarehouse)
    await selectOption(this.page, comboboxByLabel(this.page, "To warehouse"), opts.toWarehouse)

    const row = this.page.locator("table tbody tr").first()
    await selectOption(this.page, row.getByRole("combobox").first(), opts.item)
    // The Qty <Input type="number"> carries no accessible name - it's the only number input in the row.
    await row.locator('input[type="number"]').fill(String(opts.qty))
  }

  async submit() {
    await this.page.getByRole("button", { name: /create transfer/i }).click()
  }
}

export class StockTransferDetailPage {
  constructor(private readonly page: Page) {}

  async gotoById(transferId: number) {
    await this.page.goto(`/dashboard/stock/transfers/${transferId}`)
  }

  /**
   * TransferStatusBadge renders the raw enum literal ("Draft" | "InTransit" | "Received") -
   * exact match, since "Received" is also a substring of the post-receive success panel's
   * heading ("Received — destination layers created").
   */
  async expectStatus(status: "Draft" | "InTransit" | "Received") {
    await expect(this.page.getByText(status, { exact: true })).toBeVisible()
  }

  async dispatch() {
    await this.page.getByRole("button", { name: /^dispatch$/i }).click()
  }

  async receive() {
    await this.page.getByRole("button", { name: /^receive$/i }).click()
  }
}

export class StockAdjustmentNewPage {
  constructor(private readonly page: Page) {}

  async goto() {
    await this.page.goto("/dashboard/stock/adjustments/new")
  }

  async fill(opts: { warehouse: string; reasonCode: string; item: string; qtyDelta: number }) {
    await selectOption(this.page, comboboxByLabel(this.page, "Warehouse"), opts.warehouse)
    await selectOption(this.page, comboboxByLabel(this.page, "Reason code"), opts.reasonCode)

    const row = this.page.locator("table tbody tr").first()
    await selectOption(this.page, row.getByRole("combobox").first(), opts.item)
    await row.getByPlaceholder(/e\.g\. -15 or 50/i).fill(String(opts.qtyDelta))
  }

  async submit() {
    await this.page.getByRole("button", { name: /post adjustment/i }).click()
  }

  async expectPosted() {
    await expect(this.page.getByRole("button", { name: /new adjustment/i })).toBeVisible()
  }
}
