import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { screen, waitFor } from '@testing-library/react';
import { Route, Routes } from 'react-router-dom';
import MockAdapter from 'axios-mock-adapter';
import { apiClient } from '@/api/client';
import { EngagementDetailPage } from '@/pages/EngagementDetailPage';
import { renderWithProviders } from './utils';
import type { Engagement } from '@/api/types';

vi.mock('@/api/exports', () => ({
  downloadEngagementExport: vi.fn(),
}));

const ENGAGEMENT: Engagement = {
  id: 1,
  name: 'Test Engagement',
  description: 'A test engagement',
  start_date: '2026-06-01',
  end_date: null,
  status: 'active',
  created_at: '2026-06-01T08:00:00',
  created_by: { id: 1, username: 'alice' },
};

type MockRole = 'admin' | 'redteam' | 'soc';
let mockRole: MockRole = 'admin';

function DetailPage() {
  return (
    <Routes>
      <Route path="/engagements/:id" element={<EngagementDetailPage />} />
    </Routes>
  );
}

vi.mock('@/hooks/useAuth', () => ({
  useAuth: () => ({
    user: { id: 1, username: 'alice', role: mockRole, created_at: '2026-01-01' },
    status: 'authenticated',
    login: vi.fn(),
    logout: vi.fn(),
    isAdmin: mockRole === 'admin',
    isRedteam: mockRole === 'redteam',
    isSoc: mockRole === 'soc',
    canEditEngagements: mockRole === 'admin' || mockRole === 'redteam',
  }),
}));

describe('EngagementDetailPage — RBAC for Export button', () => {
  let mock: MockAdapter;

  beforeEach(() => {
    mock = new MockAdapter(apiClient);
    mock.onGet('/engagements/1').reply(200, ENGAGEMENT);
    mock.onGet('/engagements/1/simulations').reply(200, []);
  });

  afterEach(() => {
    mock.restore();
  });

  it('admin sees Export button', async () => {
    mockRole = 'admin';
    renderWithProviders(<DetailPage />, {
      routerProps: { initialEntries: ['/engagements/1'] },
    });
    await waitFor(() => {
      expect(screen.getByText('Test Engagement')).toBeInTheDocument();
    });
    expect(screen.getByTestId('export-dropdown')).toBeInTheDocument();
  });

  it('redteam sees Export button', async () => {
    mockRole = 'redteam';
    renderWithProviders(<DetailPage />, {
      routerProps: { initialEntries: ['/engagements/1'] },
    });
    await waitFor(() => {
      expect(screen.getByText('Test Engagement')).toBeInTheDocument();
    });
    expect(screen.getByTestId('export-dropdown')).toBeInTheDocument();
  });

  it('soc does NOT see Export button', async () => {
    mockRole = 'soc';
    renderWithProviders(<DetailPage />, {
      routerProps: { initialEntries: ['/engagements/1'] },
    });
    await waitFor(() => {
      expect(screen.getByText('Test Engagement')).toBeInTheDocument();
    });
    expect(screen.queryByTestId('export-dropdown')).toBeNull();
  });
});
