import { test } from '@/manager/modules/invoice/invoice-fixtures';
import { toInvoiceCreateTotalsSummary } from '@/manager/modules/invoice/invoice-mappers';
import { expectDataTableChipsColumnToHaveText } from '@/manager/modules/ui/data-table/data-table-assertions';
import {
  invoicePaymentTableColumnTestIds,
  invoiceTableColumnTestIds,
} from '@/manager/modules/ui/data-table/data/data-table-column-test-ids';
import { expectSingleLocatorToHaveText } from '@/manager/shared/utils/expect-utils';
import { formatCurrency } from '@/shared/utils/formatters';
import { expect } from '@/shared/utils/matchers';
import { pollOrSkip } from '@/shared/utils/poll-utils';

test('marks an open invoice as void', async ({ setupInvoiceCreateData, createInvoice, invoiceDetailsPage }) => {
  const data = await setupInvoiceCreateData({ numberOfProducts: 1 });
  const invoice = await createInvoice(data);

  // Voiding writes off the invoice without settling it: the amount due stays the full total (it is not paid),
  // so it must not drop to zero, and the open invoice's outstanding payment charge is cancelled.
  const amountDue = formatCurrency(toInvoiceCreateTotalsSummary(data).totalInclVat, data.location.currency);

  await invoiceDetailsPage.goto(invoice.id);

  await test.step('mark invoice as void', async () => {
    const dialog = await invoiceDetailsPage.openInvoiceMarkAsVoidDialog();
    await dialog.mark();
  });

  await test.step('verify voided invoice on details page', async () => {
    await expectSingleLocatorToHaveText(invoiceDetailsPage.baseStatus, 'voided');
    await expectSingleLocatorToHaveText(invoiceDetailsPage.generalCard.amountDue, amountDue);
  });

  await test.step('verify cancelled payment charge', async () => {
    const payments = invoiceDetailsPage.paymentsCard.dataTable;

    // The payments card fetches once on mount and never polls, so the charge it loaded for the still-open
    // invoice stays stale after the void mutation — reload-poll until it surfaces as cancelled.
    await pollOrSkip(
      async () => {
        await invoiceDetailsPage.reload();
        await expectDataTableChipsColumnToHaveText(payments, invoicePaymentTableColumnTestIds.status, 'cancelled');
      },
      {
        timeout: 30_000,
        reason: 'voided charge did not surface as cancelled within 30s — test-env queue backlog (KIN-4692)',
      }
    );
  });

  await test.step('verify voided invoice on list page', async () => {
    const listPage = await invoiceDetailsPage.returnToInvoiceListPage();

    await listPage.searchTextField.fill(invoice.number);

    await expect(listPage.dataTable.getRows()).toHaveCount(1);
    await expectDataTableChipsColumnToHaveText(listPage.dataTable, invoiceTableColumnTestIds.status, 'voided');
  });
});
