/**
 * US-28 — Admin/redteam access templates from the nav.
 * Covers AC-28.1 (Templates link in topbar), AC-28.2 (ProtectedRoute SOC redirect),
 * AC-28.3 (page is always edit-capable, no read-only mode).
 */
import { test, expect } from '@playwright/test';
import {
  adminToken,
  deleteUserByUsername,
  ensureUser,
  login,
} from '../fixtures/api';
import { seedTokenInStorage } from '../fixtures/auth';

const REDTEAM_USER = 'us28-redteam';
const SOC_USER = 'us28-soc';
const PASS = 'us28-pass-strong';

test.describe('US-28 — templates nav', () => {
  let redteamToken: string;
  let socToken: string;
  let adminTok: string;

  test.beforeAll(async () => {
    adminTok = await adminToken();
    await ensureUser(REDTEAM_USER, PASS, 'redteam');
    await ensureUser(SOC_USER, PASS, 'soc');
    redteamToken = (await login(REDTEAM_USER, PASS)).token;
    socToken = (await login(SOC_USER, PASS)).token;
  });

  test.afterAll(async () => {
    try {
      const tok = await adminToken();
      for (const u of [REDTEAM_USER, SOC_USER]) await deleteUserByUsername(tok, u);
    } catch { /* noop */ }
  });

  // AC-28.1 — Templates nav link visible to admin + redteam
  test('AC-28.1 — redteam sees "Templates" link in topbar nav', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, redteamToken);
    await page.goto('/engagements');

    const link = page.getByRole('link', { name: /^templates$/i });
    await expect(link).toBeVisible();
    await expect(link).toHaveAttribute('href', '/admin/templates');
  });

  test('AC-28.1 — admin sees "Templates" link in topbar nav', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, adminTok);
    await page.goto('/engagements');

    await expect(page.getByRole('link', { name: /^templates$/i })).toBeVisible();
  });

  test('AC-28.1 — SOC does NOT see "Templates" link in topbar nav', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, socToken);
    await page.goto('/engagements');

    // Wait for page to fully load before asserting absence
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('link', { name: /^templates$/i })).not.toBeVisible();
  });

  test('AC-28.1 — clicking Templates link navigates to /admin/templates', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, redteamToken);
    await page.goto('/engagements');

    await page.getByRole('link', { name: /^templates$/i }).click();
    await expect(page).toHaveURL(/\/admin\/templates/);
  });

  // AC-28.2 — SOC typing /admin/templates URL directly → redirected
  test('AC-28.2 — SOC direct URL /admin/templates → redirected to /engagements', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, socToken);
    await page.goto('/admin/templates');

    await expect(page).toHaveURL(/\/engagements/, { timeout: 5_000 });
  });

  test('AC-28.2 — SOC direct URL /admin/templates/new → redirected to /engagements', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, socToken);
    await page.goto('/admin/templates/new');

    await expect(page).toHaveURL(/\/engagements/, { timeout: 5_000 });
  });

  // AC-28.3 — Page assumes canEdit=true (form inputs are never disabled for admin/redteam)
  test('AC-28.3 — TemplateFormPage for redteam: name input is editable (no read-only mode)', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, redteamToken);
    await page.goto('/admin/templates/new');

    const nameInput = page.getByLabel(/name/i).first();
    await expect(nameInput).toBeVisible();
    await expect(nameInput).toBeEnabled();

    // Should be able to type
    await nameInput.fill('AC-28.3 editability test');
    await expect(nameInput).toHaveValue('AC-28.3 editability test');
  });

  test('AC-28.3 — admin has same edit access on /admin/templates', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, adminTok);
    await page.goto('/admin/templates');

    // Page loads (not redirected)
    await expect(page).toHaveURL(/\/admin\/templates/);
    await expect(page.getByRole('heading', { name: 'Templates', exact: true })).toBeVisible({ timeout: 5_000 });
    // "New" link in header when templates exist, "New template" in empty state — either is fine
    await expect(page.getByRole('link', { name: /new( template)?/i }).first()).toBeVisible();
  });
});
