/**
 * US-30 — SOC role has zero access to the export feature.
 *
 * AC-30.1: SOC login → Export button absent from DOM (not just hidden).
 * AC-30.2: Direct API call with SOC Bearer → 403.
 * AC-30.3: Direct API call without token → 401.
 */
import { test, expect } from '@playwright/test';
import {
  adminToken,
  createEngagement,
  deleteEngagement,
  deleteUserByUsername,
  ensureUser,
  login,
  type Engagement,
} from '../fixtures/api';
import { seedTokenInStorage } from '../fixtures/auth';

const SOC_USER = 'us30-soc';
const ADMIN_USER = 'us30-admin';
const PASS = 'us30-pass-strong!';

const BASE_URL = process.env.MIMIC_BASE_URL ?? 'http://localhost:5000';

test.describe('US-30 — SOC zero access to export', () => {
  let socTok: string;
  let adminTok: string;
  let engagement: Engagement;

  test.beforeAll(async () => {
    await ensureUser(SOC_USER, PASS, 'soc');
    await ensureUser(ADMIN_USER, PASS, 'admin');
    socTok = (await login(SOC_USER, PASS)).token;
    adminTok = (await login(ADMIN_USER, PASS)).token;

    engagement = await createEngagement(adminTok, {
      name: 'US30 RBAC Engagement',
      start_date: '2026-01-01',
    });
  });

  test.afterAll(async () => {
    try {
      await deleteEngagement(adminTok, engagement.id);
      const rootTok = await adminToken();
      for (const u of [SOC_USER, ADMIN_USER]) await deleteUserByUsername(rootTok, u);
    } catch { /* noop */ }
  });

  // AC-30.1 — SOC: Export button absent from DOM
  test('AC-30.1 — SOC login: Export dropdown is NOT attached to the DOM', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, socTok);
    await page.goto(`/engagements/${engagement.id}`);

    // Wait for the page to fully load (engagement header should be visible)
    await expect(page.locator('h1, h2').first()).toBeVisible({ timeout: 10_000 });

    // The export dropdown wrapper must not be in the DOM at all
    await expect(
      page.locator('[data-testid="export-dropdown"]'),
    ).not.toBeAttached();
  });

  // AC-30.2 — SOC Bearer token → 403
  test('AC-30.2 — SOC Bearer: GET /api/engagements/<id>/export?format=md → 403', async ({
    request,
  }) => {
    const response = await request.get(
      `${BASE_URL}/api/engagements/${engagement.id}/export?format=md`,
      {
        headers: { Authorization: `Bearer ${socTok}` },
      },
    );
    expect(response.status()).toBe(403);
  });

  // AC-30.3 — No token → 401
  test('AC-30.3 — No token: GET /api/engagements/<id>/export?format=md → 401', async ({
    request,
  }) => {
    const response = await request.get(
      `${BASE_URL}/api/engagements/${engagement.id}/export?format=md`,
    );
    expect(response.status()).toBe(401);
  });
});
