import { test, expect } from '@playwright/test';
import { login, navigateTo, apiHeaders, PORT_SLUG } from './helpers';

test.describe('Invoicing', () => {
  test.beforeEach(async ({ page }) => {
    await login(page, 'super_admin');
  });

  test('navigate to invoices page', async ({ page }) => {
    await navigateTo(page, '/invoices');
    await page.waitForLoadState('networkidle');

    const heading = page.getByText(/invoices/i).first();
    await expect(heading).toBeVisible({ timeout: 10_000 });
  });

  test('create a new invoice with 3 line items', async ({ page }) => {
    // Seed a client via API to pick in the billing-entity picker.
    const clientName = `Invoice Test Client ${Date.now()}`;
    const createRes = await page.request.post('/api/v1/clients', {
      headers: await apiHeaders(page),
      data: {
        fullName: clientName,
        contacts: [{ channel: 'email', value: 'billing@test.com', isPrimary: true }],
      },
    });
    expect(createRes.ok(), `client create returned ${createRes.status()}`).toBe(true);

    await navigateTo(page, '/invoices');
    await page.waitForLoadState('networkidle');

    const newBtn = page
      .getByRole('link', { name: /new invoice/i })
      .first()
      .or(page.getByRole('button', { name: /new invoice/i }).first());
    await newBtn.first().click();

    await page.waitForURL(`**/${PORT_SLUG}/invoices/new**`, { timeout: 10_000 });

    // Step 1: pick the client in the OwnerPicker. The trigger renders as a
    // button with role="combobox" and the placeholder "Select owner..." while
    // empty.
    const ownerTrigger = page.locator('button[role="combobox"]:has-text("Select owner")').first();
    await expect(ownerTrigger).toBeVisible({ timeout: 5_000 });
    await ownerTrigger.click();
    const searchInput = page.getByPlaceholder(/search clients/i);
    await expect(searchInput).toBeVisible({ timeout: 5_000 });
    await searchInput.fill(clientName);
    await page.waitForTimeout(500); // let the debounced query fire
    await page.getByRole('option', { name: clientName }).first().click();

    await page.fill('#billingEmail', 'billing@test.com');

    const dueDate = new Date();
    dueDate.setDate(dueDate.getDate() + 30);
    await page.fill('#dueDate', dueDate.toISOString().split('T')[0]!);

    await page.getByRole('button', { name: /next/i }).click();
    await page.waitForTimeout(1000);

    for (let i = 0; i < 3; i++) {
      await page.getByRole('button', { name: /add line item/i }).click();
      await page.waitForTimeout(300);
    }

    await page.locator('input[name="lineItems.0.description"]').fill('Berth Rental - Annual');
    await page.locator('input[name="lineItems.0.quantity"]').fill('1');
    await page.locator('input[name="lineItems.0.unitPrice"]').fill('50000');

    await page.locator('input[name="lineItems.1.description"]').fill('Utilities Package');
    await page.locator('input[name="lineItems.1.quantity"]').fill('12');
    await page.locator('input[name="lineItems.1.unitPrice"]').fill('150');

    await page.locator('input[name="lineItems.2.description"]').fill('Maintenance Fee');
    await page.locator('input[name="lineItems.2.quantity"]').fill('4');
    await page.locator('input[name="lineItems.2.unitPrice"]').fill('500');

    await expect(page.getByText(/53[,.]?800/).first()).toBeVisible({ timeout: 5_000 });

    await page.getByRole('button', { name: /^next$/i }).click();
    const createBtn = page.getByRole('button', { name: /create invoice/i });
    await expect(createBtn).toBeVisible({ timeout: 10_000 });

    await expect(page.getByText(/53[,.]?800/).first()).toBeVisible();

    await createBtn.click();

    await page.waitForURL(
      (url) => url.pathname.includes('/invoices') && !url.pathname.includes('/new'),
      { timeout: 15_000 },
    );
  });

  test('invoice shows as Draft', async ({ page }) => {
    await navigateTo(page, '/invoices');
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(2000);

    await expect(page.getByText(/draft/i).first()).toBeVisible({ timeout: 10_000 });
  });

  test('invoice detail page loads', async ({ page }) => {
    await navigateTo(page, '/invoices');
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(2000);

    // Click into the first invoice
    const invoiceLink = page.locator('table a, table [role="link"]').first();
    if (await invoiceLink.isVisible({ timeout: 5_000 }).catch(() => false)) {
      await invoiceLink.click();
      await page.waitForTimeout(3000);

      const url = page.url();
      expect(url.includes('/invoices/')).toBeTruthy();
    } else {
      // Try clicking the first row
      const row = page.locator('table tbody tr').first();
      if (await row.isVisible({ timeout: 3_000 }).catch(() => false)) {
        await row.click();
        await page.waitForTimeout(3000);
      }
    }
  });
});
