import { test, expect } from '@playwright/test';

import { getPortId, login, navigateTo, waitForSheet } from './helpers';

const RES_CLIENT_NAME = `E2E Res Client ${Date.now()}`;
const RES_CLIENT_EMAIL = `e2e-res-${Date.now()}@test.example`;

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

  test('residential clients page loads with empty state or table', async ({ page }) => {
    await navigateTo(page, '/residential/clients');
    await expect(page.getByRole('heading', { name: /residential clients/i })).toBeVisible({
      timeout: 10_000,
    });
    // Either table or empty state should render - both ok.
    const hasTableOrEmpty = await Promise.race([
      page
        .locator('table')
        .first()
        .isVisible({ timeout: 5_000 })
        .catch(() => false),
      page
        .getByRole('button', { name: /new/i })
        .first()
        .isVisible({ timeout: 5_000 })
        .catch(() => false),
    ]);
    expect(hasTableOrEmpty).toBeTruthy();
  });

  test('create a residential client via UI', async ({ page }) => {
    await navigateTo(page, '/residential/clients');
    await page.locator('main').getByRole('button', { name: /^new$/i }).first().click();
    await waitForSheet(page);

    const sheet = page.locator('[role="dialog"]');
    await sheet.locator('#rc-name').fill(RES_CLIENT_NAME);
    await sheet.locator('#rc-email').fill(RES_CLIENT_EMAIL);

    await sheet.getByRole('button', { name: /create|save/i }).click();
    await expect(sheet).not.toBeVisible({ timeout: 30_000 });
    await page.waitForTimeout(1500);

    // Reload list and confirm row is present.
    await navigateTo(page, '/residential/clients');
    await expect(page.getByText(RES_CLIENT_NAME).first()).toBeVisible({ timeout: 30_000 });
  });

  test('residential interests page loads', async ({ page }) => {
    await navigateTo(page, '/residential/interests');
    await expect(page.getByRole('heading', { name: /residential interests/i })).toBeVisible({
      timeout: 10_000,
    });
  });

  test('residential nav section is visible in sidebar', async ({ page }) => {
    await navigateTo(page, '/dashboard');
    // Both residential links should appear for super_admin.
    await expect(page.getByRole('link', { name: /residential clients/i }).first()).toBeVisible({
      timeout: 10_000,
    });
    await expect(page.getByRole('link', { name: /residential interests/i }).first()).toBeVisible({
      timeout: 10_000,
    });
  });

  test('create a residential interest via API and see it on the interests list', async ({
    page,
  }) => {
    const portId = await getPortId(page);
    const stamp = Date.now();

    // 1) Create a residential client via the v1 API.
    const clientRes = await page.request.post('/api/v1/residential/clients', {
      data: {
        fullName: `E2E Res ${stamp}`,
        email: `e2e-res-${stamp}@test.example`,
        phone: '+1-555-0199',
      },
      headers: { 'Content-Type': 'application/json', 'x-port-id': portId },
    });
    expect(clientRes.status()).toBe(201);
    const clientBody = await clientRes.json();
    const residentialClientId = clientBody.data?.id ?? clientBody.id;
    expect(residentialClientId).toBeTruthy();

    // 2) Create a residential interest tied to that client.
    const interestRes = await page.request.post('/api/v1/residential/interests', {
      data: {
        residentialClientId,
        preferences: `2BR oceanview, budget €${stamp}`,
        notes: `Smoke interest ${stamp}`,
        source: 'manual',
      },
      headers: { 'Content-Type': 'application/json', 'x-port-id': portId },
    });
    expect(interestRes.status()).toBe(201);
    const interestBody = await interestRes.json();
    const residentialInterestId = interestBody.data?.id ?? interestBody.id;
    expect(residentialInterestId).toBeTruthy();

    // 3) Confirm it shows up on the residential interests list page.
    //    The list renders preferences/notes (not the client name), so match
    //    against the unique stamp embedded in the preferences string.
    await navigateTo(page, '/residential/interests');
    await expect(page.getByText(new RegExp(String(stamp))).first()).toBeVisible({
      timeout: 15_000,
    });
  });

  test('residential interest detail page renders for a freshly-created interest', async ({
    page,
  }) => {
    const portId = await getPortId(page);
    const stamp = Date.now();

    const clientRes = await page.request.post('/api/v1/residential/clients', {
      data: {
        fullName: `E2E ResDetail ${stamp}`,
        email: `e2e-res-detail-${stamp}@test.example`,
      },
      headers: { 'Content-Type': 'application/json', 'x-port-id': portId },
    });
    expect(clientRes.status()).toBe(201);
    const clientId = (await clientRes.json()).data?.id;

    const interestRes = await page.request.post('/api/v1/residential/interests', {
      data: { residentialClientId: clientId, preferences: 'penthouse, sea view', source: 'manual' },
      headers: { 'Content-Type': 'application/json', 'x-port-id': portId },
    });
    expect(interestRes.status()).toBe(201);
    const interestId = (await interestRes.json()).data?.id;

    // Navigate to the detail route - the page should render the standard
    // residential-interest detail layout (eyebrow + client name h1 + sections).
    await navigateTo(page, `/residential/interests/${interestId}`);
    await expect(page.getByText('Residential interest', { exact: true }).first()).toBeVisible({
      timeout: 15_000,
    });
    await expect(page.getByRole('heading', { name: /E2E ResDetail/ }).first()).toBeVisible({
      timeout: 5_000,
    });
  });

  test('public residential inquiry endpoint accepts a submission', async ({ page }) => {
    // Direct API call to the public endpoint - confirms wiring without UI.
    // Public endpoint takes portId via query string (no auth, but the helper
    // resolves the port ID for us via the admin API).
    const portId = await getPortId(page);
    const res = await page.request.post(
      `/api/public/residential-inquiries?portId=${encodeURIComponent(portId)}`,
      {
        data: {
          firstName: `Public${Date.now()}`,
          lastName: 'Smoke',
          email: `public-res-${Date.now()}@test.example`,
          phone: '+1-555-0100',
          notes: 'Smoke test inquiry',
        },
        headers: { 'Content-Type': 'application/json' },
      },
    );
    // 201 success, 429 if rate-limit hit (also acceptable as proof endpoint exists).
    expect([201, 429]).toContain(res.status());
  });
});
