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

/**
 * Smoke spec - Documents Hub aggregated view (Wave 11.B rebuild)
 *
 * Exercises the structural layout of the new DocumentsHub:
 *   - FolderTreeSidebar with system-root folders (Clients / Companies / Yachts)
 *   - HubRootView sections ("Signing in progress" + "Recent files")
 *   - Expanding a system root to reveal entity sub-folders
 *   - Selecting an entity sub-folder switches to EntityFolderView which
 *     renders the AggregatedSection blocks
 *
 * Note: This spec intentionally avoids asserting on seeded file/workflow
 * counts - those vary by seed state.  The integration tests (Tasks 8 + 9)
 * already verify service correctness; this spec guards UI-level rendering.
 */

test.describe('Documents hub - aggregated view', () => {
  test.beforeEach(async ({ page }) => {
    await login(page, 'super_admin');
  });

  test('hub root shows Signing-in-progress and Recent-files sections', async ({ page }) => {
    await navigateTo(page, '/documents');
    await page.waitForLoadState('networkidle');

    // HubRootView renders two labelled sections.
    await expect(page.getByText('Signing in progress')).toBeVisible({ timeout: 10_000 });
    await expect(page.getByText('Recent files')).toBeVisible({ timeout: 5_000 });
  });

  test('sidebar shows All-documents and Root pseudo-rows', async ({ page }) => {
    await navigateTo(page, '/documents');
    await page.waitForLoadState('networkidle');

    // FolderTreeSidebar always renders these two pseudo-rows at the top.
    await expect(page.getByRole('button', { name: 'All documents' })).toBeVisible({
      timeout: 10_000,
    });
    await expect(page.getByRole('button', { name: 'Root (no folder)' })).toBeVisible({
      timeout: 5_000,
    });
  });

  test('system-root folders appear in the sidebar with lock icons', async ({ page }) => {
    await navigateTo(page, '/documents');
    await page.waitForLoadState('networkidle');

    // ensureSystemRoots creates Clients / Companies / Yachts on port creation.
    // Each node has systemManaged=true → FolderRow renders a Lock icon beside
    // the name. We assert text presence; the SVG lock icon is decoration only
    // and aria-labeled "System folder" by the component.
    for (const rootName of ['Clients', 'Companies', 'Yachts']) {
      await expect(page.getByText(rootName)).toBeVisible({ timeout: 10_000 });
    }
    // At least one system-folder lock icon should be in the sidebar.
    const lockIcons = page.locator('aside [aria-label="System folder"]');
    await expect(lockIcons.first()).toBeVisible({ timeout: 5_000 });
  });

  test('clicking a system root selects it and breadcrumb updates', async ({ page }) => {
    await navigateTo(page, '/documents');
    await page.waitForLoadState('networkidle');

    // Click the Clients system root folder button (the label button inside FolderRow).
    // The chevron button and the label button are siblings - we target the button
    // that contains the text "Clients".
    const clientsBtn = page
      .locator('aside button')
      .filter({ hasText: /^Clients$/ })
      .first();
    await expect(clientsBtn).toBeVisible({ timeout: 10_000 });
    await clientsBtn.click();

    // The breadcrumb (nav[aria-label="breadcrumb"]) should now show "Clients".
    await expect(page.getByRole('navigation', { name: /breadcrumb/i })).toContainText('Clients', {
      timeout: 10_000,
    });
  });

  test('entity sub-folder view renders Signing-in-progress and Files sections', async ({
    page,
  }) => {
    // Create a fresh client via the API so we have a guaranteed entity with a
    // folder. ensureEntityFolder is called by the createClient service hook.
    // page.request shares the browser context cookie jar (session cookie from
    // login()) - the bare `request` fixture is an isolated API context that
    // does not carry the session cookie and would 401.
    const res = await page.request.post('/api/v1/clients', {
      data: {
        firstName: 'HubAgg',
        lastName: `Smoke${Date.now()}`,
        email: `hubagg${Date.now()}@e2e.test`,
      },
    });
    // A non-2xx here means smoke setup is broken (port cookie / seed) or the
    // clients API regressed. Fail loud rather than skip green - a silent skip
    // masked an infra failure for weeks in the audit window. Playwright doesn't
    // expose vitest's `expect.fail`, so we throw a plain Error which the
    // runner promotes to a failing test the same way.
    if (!res.ok()) {
      throw new Error(
        `Client create returned ${res.status()} ${await res.text()} - entity sub-folder assertion cannot proceed`,
      );
    }
    const { data: client } = (await res.json()) as {
      data: { id: string; firstName: string; lastName: string };
    };

    // Navigate to the documents hub.
    await navigateTo(page, '/documents');
    await page.waitForLoadState('networkidle');

    // Expand the Clients system root by clicking its chevron (Expand button).
    // The Expand chevron is the first button sibling inside the FolderRow div.
    // It is aria-labeled "Expand" when collapsed.
    const expandBtn = page.locator('aside').getByRole('button', { name: 'Expand' }).first();
    await expect(expandBtn).toBeVisible({ timeout: 10_000 });
    await expandBtn.click();

    // The entity folder is named "<FirstName> <LastName>".
    const entityFolderBtn = page
      .locator('aside button')
      .filter({ hasText: `${client.firstName} ${client.lastName}` })
      .first();

    if (!(await entityFolderBtn.isVisible({ timeout: 8_000 }).catch(() => false))) {
      // ensureEntityFolder may not have run yet (async post-create); reload to
      // pick up the folder tree refresh.
      await navigateTo(page, '/documents');
      await page.waitForLoadState('networkidle');
      // Re-expand.
      const expandBtn2 = page.locator('aside').getByRole('button', { name: 'Expand' }).first();
      await expandBtn2.click();
    }

    await expect(entityFolderBtn).toBeVisible({ timeout: 10_000 });
    await entityFolderBtn.click();

    // EntityFolderView renders two AggregatedSection blocks with these headings.
    await expect(page.getByText('Signing in progress')).toBeVisible({ timeout: 10_000 });
    await expect(page.getByText('Files')).toBeVisible({ timeout: 5_000 });

    // TODO(Task 19 verification): assert SigningDetailsDialog trigger once
    // a signed-file fixture exists in the smoke seed. The button is only
    // rendered when files[].signedFromDocumentId is non-null (Task 15 fix-up).
    const detailsButton = page.getByRole('button', { name: /view signing details/i });
    if ((await detailsButton.count()) > 0) {
      await detailsButton.first().click();
      await expect(page.getByRole('dialog', { name: /Signing details/i })).toBeVisible();
    }
  });
});
