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

vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
vi.mock('../lib/api', () => ({
  api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
  ApiError: class extends Error {},
}));

import { api } from '../lib/api';
import PatientRecordFormPage from './PatientRecordFormPage';

/** react-select (SearchableSelect) را با placeholder پیدا و گزینه را با متن انتخاب می‌کند. */
async function pickSelect(placeholder: string, optionLabel: string) {
  const ph = await screen.findByText(placeholder);
  const control = ph.closest('div[class*="control"]') as HTMLElement;
  const input = control.querySelector('input') as HTMLInputElement;
  fireEvent.focus(input);
  fireEvent.keyDown(input, { key: 'ArrowDown' });
  fireEvent.click(await screen.findByText(optionLabel));
}

const post = api.post as ReturnType<typeof vi.fn>;
const patch = api.patch as ReturnType<typeof vi.fn>;

beforeEach(() => {
  post.mockReset(); patch.mockReset();
  post.mockResolvedValue({ success: true, data: { uuid: 'new-1' } });
  patch.mockResolvedValue({ success: true, data: {} });
});

describe('PatientRecordFormPage (تشکیل پرونده)', () => {
  it('creates a record then patches the demographic fields', async () => {
    renderWithProviders(<PatientRecordFormPage />, { route: '/admin/patients/new' });

    fireEvent.change(screen.getByPlaceholderText('نام و نام خانوادگی را وارد نمایید'), { target: { value: 'بیمار نمونه' } });
    fireEvent.change(screen.getByPlaceholderText('شماره پرونده'), { target: { value: 'P-1001' } });
    await pickSelect('انتخاب...', 'زن'); // gender = female
    fireEvent.change(screen.getByPlaceholderText('کد ملی را وارد نمایید'), { target: { value: '1234567890' } });
    fireEvent.change(screen.getByPlaceholderText('شماره تماس را وارد نمایید'), { target: { value: '09120000000' } });
    fireEvent.click(screen.getByRole('button', { name: 'ثبت اطلاعات' }));

    await waitFor(() => expect(post).toHaveBeenCalledWith('/api/v1/patient', expect.objectContaining({
      name: 'بیمار نمونه', mobile: '09120000000', national_code: '1234567890', record_number: 'P-1001',
    })));
    await waitFor(() => expect(patch).toHaveBeenCalledWith('/api/v1/patient/new-1', expect.objectContaining({ gender: 'female' })));
  });

  it('blocks submit and shows a validation error for a bad national code', async () => {
    renderWithProviders(<PatientRecordFormPage />, { route: '/admin/patients/new' });

    fireEvent.change(screen.getByPlaceholderText('نام و نام خانوادگی را وارد نمایید'), { target: { value: 'ب' } });
    fireEvent.change(screen.getByPlaceholderText('شماره پرونده'), { target: { value: 'P-1' } });
    await pickSelect('انتخاب...', 'مرد');
    fireEvent.change(screen.getByPlaceholderText('کد ملی را وارد نمایید'), { target: { value: '12' } });
    fireEvent.change(screen.getByPlaceholderText('شماره تماس را وارد نمایید'), { target: { value: '09120000000' } });
    fireEvent.click(screen.getByRole('button', { name: 'ثبت اطلاعات' }));

    expect(await screen.findByText('کد ملی باید ۱۰ رقم باشد')).toBeInTheDocument();
    expect(post).not.toHaveBeenCalled();
  });
});
