import { test } from '@/manager/modules/invoice/invoice-fixtures';
import { getCustomerDisplayName } from '@/manager/modules/customer/customer-utils';
import { toInvoiceCreateTotalsSummary } from '@/manager/modules/invoice/invoice-mappers';
import { formatCurrency } from '@/shared/utils/formatters';
import { expect } from '@/shared/utils/matchers';
import { readPdfText, toPdfText } from '@/shared/utils/pdf-utils';
import { pollOrSkip } from '@/shared/utils/poll-utils';

test.describe.configure({ mode: 'default', timeout: 120_000 });

test('downloads the invoice pdf from the list', async ({
  page,
  setupInvoiceCreateData,
  createInvoice,
  invoiceListPage,
}) => {
  const data = await setupInvoiceCreateData({ numberOfProducts: 1 });
  const customerName = getCustomerDisplayName(data.customer);
  // The storeroom Stripe account renders its documents in German, so the PDF total is German-formatted.
  const amount = formatCurrency(toInvoiceCreateTotalsSummary(data).totalInclVat, data.location.currency, 'de-DE');

  const invoice = await createInvoice(data);

  await invoiceListPage.goto();

  await test.step('apply filter', () => invoiceListPage.searchTextField.fill(invoice.number));

  // Unlike the credit-note list there is no pdf-readiness indicator to gate on (the download action is always
  // in the row menu), so the poll waits for the invoice row itself. The applied filter persists across reloads
  // (grid filters live in localStorage), so the row under test stays the only one.
  await test.step('wait for the invoice to appear in the list', () =>
    pollOrSkip(
      async () => {
        await invoiceListPage.reload();
        await expect(invoiceListPage.dataTable.getRows()).toHaveCount(1);
      },
      { timeout: 60_000, reason: 'invoice did not appear in the list within 60s — test-env queue backlog (KIN-4692)' }
    ));

  const download = await test.step('download invoice pdf', async () => {
    // The action fetches a signed Kinnovis storage link and opens it in a new tab that immediately turns into a
    // file download and closes itself — Chromium attributes that download to the opener page, so listen there.
    const [invoicePdfDownload] = await Promise.all([
      page.waitForEvent('download'),
      invoiceListPage.clickDownloadInvoicePdfAction(0),
    ]);

    return invoicePdfDownload;
  });

  await test.step('verify invoice pdf contents', async () => {
    const pdfText = await readPdfText(await download.path());

    expect(pdfText).toContain(toPdfText(invoice.number));
    expect(pdfText).toContain(toPdfText(customerName));
    expect(pdfText).toContain(toPdfText(amount));
  });
});

test('downloads the invoice pdf from the details page', async ({
  page,
  setupInvoiceCreateData,
  createInvoice,
  invoiceDetailsPage,
}) => {
  const data = await setupInvoiceCreateData({ numberOfProducts: 1 });
  const customerName = getCustomerDisplayName(data.customer);
  // The storeroom Stripe account renders its documents in German, so the PDF total is German-formatted.
  const amount = formatCurrency(toInvoiceCreateTotalsSummary(data).totalInclVat, data.location.currency, 'de-DE');

  const invoice = await createInvoice(data);

  await invoiceDetailsPage.goto(invoice.id);

  const download = await test.step('download invoice pdf', async () => {
    // The action fetches a signed Kinnovis storage link and opens it in a new tab that immediately turns into a
    // file download and closes itself — Chromium attributes that download to the opener page, so listen there.
    const [invoicePdfDownload] = await Promise.all([
      page.waitForEvent('download'),
      invoiceDetailsPage.clickDownloadInvoicePdfAction(),
    ]);

    return invoicePdfDownload;
  });

  await test.step('verify invoice pdf contents', async () => {
    const pdfText = await readPdfText(await download.path());

    expect(pdfText).toContain(toPdfText(invoice.number));
    expect(pdfText).toContain(toPdfText(customerName));
    expect(pdfText).toContain(toPdfText(amount));
  });
});
