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

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 AppointmentFiltersModal, { applyAppointmentFilters, EMPTY_FILTERS } from './AppointmentFiltersModal';
import type { Appointment } from '../types';

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

beforeEach(() => {
  get.mockReset();
  get.mockResolvedValue({ success: true, data: [] });
});

const mk = (over: Partial<Appointment>): Appointment => ({
  uuid: Math.random().toString(36), patient_name: 'x', patient_mobile: '0912',
  doctor_uuid: 'd', doctor_name: 'دکتر', slot_start: 0, slot_end: 0,
  appointment_date: '', appointment_time: '', end_time: '',
  status: 'pending', version: 1, created_at: '', ...over,
});

describe('applyAppointmentFilters', () => {
  const items = [
    mk({ patient_name: 'مریم اسکندری', patient_national_code: '001', status: 'completed', patient_gender: 'female', service_section: { uuid: 's1', name: 'زیبایی' } }),
    mk({ patient_name: 'مازیار عزیزی', patient_national_code: '002', status: 'cancelled_by_user', patient_gender: 'male' }),
    mk({ patient_name: 'پریسا همتی', status: 'salon', patient_gender: 'female' }),
  ];

  it('filters by name, national code, section, status group and gender', () => {
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, name: 'مریم' })).toHaveLength(1);
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, nationalCode: '002' })).toHaveLength(1);
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, sectionUuid: 's1' })).toHaveLength(1);
    // «لغو شده» covers both cancelled_by_* statuses
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, statuses: ['cancelled'] })).toHaveLength(1);
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, statuses: ['salon', 'completed'] })).toHaveLength(2);
    expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, gender: 'female' })).toHaveLength(2);
    expect(applyAppointmentFilters(
      items.map((a, i) => ({ ...a, staff: i === 0 ? { uuid: 'st1', full_name: 'x' } : null })),
      { ...EMPTY_FILTERS, staffUuid: 'st1' },
    )).toHaveLength(1);
    expect(applyAppointmentFilters(items, EMPTY_FILTERS)).toHaveLength(3);
  });
});

describe('AppointmentFiltersModal (فیلترها)', () => {
  it('renders the design controls and applies the chosen filters', () => {
    const onApply = vi.fn();
    renderWithProviders(<AppointmentFiltersModal value={EMPTY_FILTERS} onApply={onApply} onClose={() => {}} />);

    expect(screen.getByText('حذف همه')).toBeInTheDocument();
    expect(screen.getByText('وضعیت نوبت')).toBeInTheDocument();
    expect(screen.getByText('جنسیت')).toBeInTheDocument();

    fireEvent.change(screen.getByPlaceholderText('نام مراجعه کننده را وارد کنید...'), { target: { value: 'مریم' } });
    fireEvent.click(screen.getByLabelText('ویزیت شده'));
    fireEvent.click(screen.getByLabelText('خانم'));
    fireEvent.click(screen.getByText('اعمال تغییرات'));

    expect(onApply).toHaveBeenCalledWith(expect.objectContaining({
      name: 'مریم', statuses: ['completed'], gender: 'female',
    }));
  });

  it('«حذف همه» resets to the empty filter set', () => {
    const onApply = vi.fn();
    renderWithProviders(<AppointmentFiltersModal
      value={{ ...EMPTY_FILTERS, name: 'x', statuses: ['salon'] }} onApply={onApply} onClose={() => {}} />);
    fireEvent.click(screen.getByText('حذف همه'));
    fireEvent.click(screen.getByText('اعمال تغییرات'));
    expect(onApply).toHaveBeenCalledWith(EMPTY_FILTERS);
  });
});
