import { describe, it, expect, afterEach, vi } from 'vitest';
import { screen, fireEvent, waitFor } from '@testing-library/react';
import { EngagementCreateDialog } from './EngagementCreateDialog';
import { installFetchMock, renderWithProviders } from '@/test/testUtils';

describe('EngagementCreateDialog', () => {
  let fetchMock: ReturnType<typeof installFetchMock>;

  afterEach(() => {
    fetchMock?.restore();
  });

  it('rejects empty name client-side without calling the backend', () => {
    fetchMock = installFetchMock([]);
    renderWithProviders(<EngagementCreateDialog onClose={vi.fn()} />);
    fireEvent.click(screen.getByRole('button', { name: /arm engagement/i }));
    expect(screen.getByText(/nom requis/i)).toBeInTheDocument();
    expect(fetchMock.calls).toHaveLength(0);
  });

  it('maps 422 Pydantic errors to per-field messages', async () => {
    fetchMock = installFetchMock([
      {
        status: 422,
        body: {
          detail: [
            {
              loc: ['body', 'name'],
              msg: 'String should have at least 3 characters',
              type: 'string_too_short',
            },
          ],
        },
      },
    ]);
    renderWithProviders(<EngagementCreateDialog onClose={vi.fn()} />);

    fireEvent.change(screen.getByLabelText(/engagement name/i), { target: { value: 'AB' } });
    fireEvent.click(screen.getByRole('button', { name: /arm engagement/i }));

    await waitFor(() => {
      expect(screen.getByText(/at least 3 characters/i)).toBeInTheDocument();
    });
  });

  it('invalidates the engagements query and closes on success', async () => {
    const onClose = vi.fn();
    fetchMock = installFetchMock([
      {
        status: 201,
        body: {
          id: 'eng_new',
          name: 'OPERATION ZETA',
          client_name: null,
          description: null,
          status: 'planning',
          c2_type: null,
          start_date: null,
          end_date: null,
          created_at: '2026-05-23T08:00:00Z',
        },
      },
    ]);
    renderWithProviders(<EngagementCreateDialog onClose={onClose} />);

    fireEvent.change(screen.getByLabelText(/engagement name/i), {
      target: { value: 'OPERATION ZETA' },
    });
    fireEvent.click(screen.getByRole('button', { name: /arm engagement/i }));

    await waitFor(() => {
      expect(onClose).toHaveBeenCalledTimes(1);
    });
    expect(fetchMock.calls[0]?.url).toBe('/api/v1/engagements');
    expect(fetchMock.calls[0]?.init?.method).toBe('POST');
  });
});
