/**
 * E2E — GST rate selection correctness on the PO line-items editor.
 *
 * Bug covered: GST-0PCT-FALLBACK (fixed 2026-05-26)
 *   `parseFloat('0') || 0.18` is falsy, so selecting 0% GST silently fell back
 *   to 18%. Fixed by changing the expression to an explicit null/empty-string
 *   guard: `row.gstRate !== "" && row.gstRate != null ? parseFloat(row.gstRate) : 0.18`
 *
 * User story: S-01 (create PO, line items with correct GST calculation)
 * Acceptance criterion: selecting any GST rate (0 / 5 / 12 / 18 / 28 %) on a
 *   line item must produce the mathematically correct Grand Total in the footer.
 *
 * Preconditions:
 *   - Dev server running at http://localhost:3000
 *   - Seed data present (at least one vessel and account selectable)
 *   - tech@pelagia.local / tech1234 credentials valid
 */

import { test, expect, type Page } from "@playwright/test";
import { login, fillPoHeader, USERS } from "./helpers/login";

// ── Helpers ──────────────────────────────────────────────────────────────────

/** Selects a GST rate in the first line-item row's GST dropdown. */
async function selectGstRate(page: Page, value: string): Promise<void> {
  const lineItemsSection = page.locator("section").filter({
    has: page.getByRole("heading", { name: /line items/i }),
  });
  const firstRow = lineItemsSection.locator("tbody tr").first();
  // The GST select is the second <select> in the row (first is the UOM select)
  await firstRow.locator("select").nth(1).selectOption(value);
}

/**
 * Reads the Grand Total cell text from the line-items tfoot.
 * The tfoot last row has a label cell containing "Grand Total" and a value cell.
 */
async function getGrandTotal(page: Page): Promise<string> {
  const lineItemsSection = page.locator("section").filter({
    has: page.getByRole("heading", { name: /line items/i }),
  });
  // The last row of the tfoot contains "Grand Total"
  const grandTotalRow = lineItemsSection.locator("tfoot tr").last();
  // The value is the last <td> in that row
  return (await grandTotalRow.locator("td").last().textContent()) ?? "";
}

// ── Test data ─────────────────────────────────────────────────────────────────

const GST_CASES = [
  { label: "0%",  value: "0",    expected: "₹1,000.00" },
  { label: "5%",  value: "0.05", expected: "₹1,050.00" },
  { label: "12%", value: "0.12", expected: "₹1,120.00" },
  { label: "18%", value: "0.18", expected: "₹1,180.00" },
  { label: "28%", value: "0.28", expected: "₹1,280.00" },
] as const;

// ── Tests ─────────────────────────────────────────────────────────────────────

test.describe("GST rate selection — Grand Total correctness (GST-0PCT-FALLBACK)", () => {
  test.beforeEach(async ({ page }) => {
    await login(page, USERS.TECH);
    await page.goto("/po/new");

    // Fill required header fields so the form is valid
    await fillPoHeader(page, `E2E_GST_${Date.now()}`);

    // Fill the first line item: name=Bearing Assembly, qty=1, unitPrice=1000
    const lineItemsSection = page.locator("section").filter({
      has: page.getByRole("heading", { name: /line items/i }),
    });
    const firstRow = lineItemsSection.locator("tbody tr").first();

    await firstRow.getByPlaceholder("Item name *").fill("Bearing Assembly");
    // qty input — the first number input in the row
    await firstRow.locator('input[type="number"]').first().fill("1");
    // unit price input — placeholder "0.00"
    await firstRow.locator('input[placeholder="0.00"]').fill("1000");
  });

  for (const { label, value, expected } of GST_CASES) {
    test(`GST-0PCT-FALLBACK: selecting ${label} GST shows Grand Total ${expected}`, async ({ page }) => {
      await selectGstRate(page, value);

      // The Grand Total footer cell must update reactively — assert with auto-retry
      await expect(async () => {
        const total = await getGrandTotal(page);
        expect(total.trim()).toBe(expected);
      }).toPass({ timeout: 5_000 });
    });
  }
});
