/**
 * US-12 — simulation delete (RBAC + cascade + confirm modal).
 * Covers AC-12.1 → AC-12.4.
 */
import { test, expect } from '@playwright/test';
import {
  adminToken,
  createEngagement,
  deleteEngagement,
  deleteUserByUsername,
  ensureUser,
  login,
  makeClient,
} from '../fixtures/api';
import { seedTokenInStorage } from '../fixtures/auth';

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

interface Simulation {
  id: number;
  engagement_id: number;
  name: string;
  status: string;
  [key: string]: unknown;
}

async function createSimulation(
  token: string,
  engagementId: number,
  name = 'US-12 sim',
): Promise<Simulation> {
  const client = makeClient(token);
  const r = await client.post(`/engagements/${engagementId}/simulations`, { name });
  if (r.status !== 201) {
    throw new Error(`create simulation failed: ${r.status} ${JSON.stringify(r.data)}`);
  }
  return r.data as Simulation;
}

test.describe('US-12 — simulation delete', () => {
  let redteamToken: string;
  let socToken: string;
  let engagementId: number;

  test.beforeAll(async () => {
    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;
    const eng = await createEngagement(redteamToken, {
      name: 'US-12 Test Engagement',
      start_date: '2026-01-01',
    });
    engagementId = eng.id;
  });

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

  test('AC-12.1 — DELETE /api/simulations/<sid> (redteam) → 204, then 404', async () => {
    const sim = await createSimulation(redteamToken, engagementId, 'AC-12.1 to delete');
    const client = makeClient(redteamToken);

    const rDel = await client.delete(`/simulations/${sim.id}`);
    expect(rDel.status).toBe(204);

    const rGet = await client.get(`/simulations/${sim.id}`);
    expect(rGet.status).toBe(404);
  });

  test('AC-12.2 — soc → 403 on DELETE', async () => {
    const sim = await createSimulation(redteamToken, engagementId, 'AC-12.2 soc blocked');
    const socClient = makeClient(socToken);

    const r = await socClient.delete(`/simulations/${sim.id}`);
    expect(r.status).toBe(403);

    // Clean up
    const rtClient = makeClient(redteamToken);
    await rtClient.delete(`/simulations/${sim.id}`);
  });

  test('AC-12.3 — cascade: deleting engagement deletes its simulations', async () => {
    const adminTok = await adminToken();
    const adminClient = makeClient(adminTok);

    // Create a fresh engagement with simulations
    const eng = await createEngagement(redteamToken, {
      name: 'US-12 cascade test',
      start_date: '2026-01-01',
    });
    const s1 = await createSimulation(redteamToken, eng.id, 'cascade sim 1');
    const s2 = await createSimulation(redteamToken, eng.id, 'cascade sim 2');

    // Delete the engagement
    await deleteEngagement(redteamToken, eng.id);

    // Simulations must be gone
    const rS1 = await adminClient.get(`/simulations/${s1.id}`);
    expect(rS1.status).toBe(404);
    const rS2 = await adminClient.get(`/simulations/${s2.id}`);
    expect(rS2.status).toBe(404);
  });

  test('AC-12.4 — delete button visible for redteam, confirmation modal, deletes and redirects', async ({
    page,
    context,
  }) => {
    const sim = await createSimulation(redteamToken, engagementId, 'AC-12.4 UI delete');

    await seedTokenInStorage(context, redteamToken);
    await page.goto(`/engagements/${engagementId}/simulations/${sim.id}/edit`);

    // Delete button is visible for redteam
    const deleteBtn = page.getByRole('button', { name: /supprimer/i });
    await expect(deleteBtn).toBeVisible();

    // SOC should NOT see delete button
    await seedTokenInStorage(context, socToken);
    await page.goto(`/engagements/${engagementId}/simulations/${sim.id}/edit`);
    await expect(page.getByRole('button', { name: /supprimer/i })).toHaveCount(0);

    // Back to redteam — click delete, confirm modal appears
    await seedTokenInStorage(context, redteamToken);
    await page.goto(`/engagements/${engagementId}/simulations/${sim.id}/edit`);
    await page.getByRole('button', { name: /supprimer/i }).click();

    // Confirmation dialog must appear
    const dialog = page.getByRole('dialog');
    await expect(dialog).toBeVisible();
    await expect(dialog.getByText(/supprimer la simulation/i)).toBeVisible();

    // Confirm deletion
    await dialog.getByRole('button', { name: /supprimer/i }).click();

    // Should navigate back to engagement detail
    await page.waitForURL(new RegExp(`/engagements/${engagementId}$`));

    // Simulation no longer in list
    await expect(page.getByRole('row', { name: /AC-12.4 UI delete/i })).toHaveCount(0);
  });
});
