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

vi.mock('../../lib/api', () => ({
  api: { get: vi.fn(() => Promise.resolve({ success: true, data: [] })), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
  ApiError: class extends Error {},
}));

import { api } from '../../lib/api';
import TurnsTimeline from './TurnsTimeline';
import type { TimelineSlot } from './types';
import type { Appointment } from '../../types';

const appt = (over: Partial<Appointment> = {}): Appointment => ({
  uuid: 'ap1', patient_name: 'ساغر صابری', patient_mobile: '09356619438',
  doctor_uuid: 'doc1', doctor_name: 'دکتر محمدی',
  slot_start: 1000, slot_end: 2000, appointment_date: '2024-12-31',
  appointment_time: '08:00', end_time: '08:35', status: 'completed',
  version: 1, created_at: '', service_item: { uuid: 's1', name: 'ویزیت عمومی' },
  ...over,
} as unknown as Appointment);

const occupiedSlot: TimelineSlot = {
  start: 1000, end: 2000, start_time: '08:00', end_time: '08:35',
  is_available: false, appointment: appt(), cancelled_appointment: null,
};
const emptySlot: TimelineSlot = {
  start: Math.floor(Date.now() / 1000) + 3600, end: Math.floor(Date.now() / 1000) + 5400,
  start_time: '09:10', end_time: '10:30', is_available: true, appointment: null, cancelled_appointment: null,
};

describe('TurnsTimeline', () => {
  beforeEach(() => vi.clearAllMocks());

  it('renders an occupied slot card with patient name + service', () => {
    renderWithProviders(<TurnsTimeline slots={[occupiedSlot]} loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.getByText('ساغر صابری')).toBeInTheDocument();
    expect(screen.getByText(/ویزیت عمومی/)).toBeInTheDocument();
  });

  it('renders an empty slot as «افزودن نوبت» and fires onBook on click', () => {
    const onBook = vi.fn();
    renderWithProviders(<TurnsTimeline slots={[emptySlot]} loading={false} queryKey={['x']} onView={vi.fn()} onBook={onBook} />);
    const add = screen.getByText('افزودن نوبت سریع');
    fireEvent.click(add);
    expect(onBook).toHaveBeenCalledWith(emptySlot);
  });

  it('empty_reason=day_off → «این روز شیفت کاری ندارد»', () => {
    renderWithProviders(<TurnsTimeline slots={[]} emptyReason="day_off" loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.getByText('این روز شیفت کاری ندارد')).toBeInTheDocument();
  });

  it('empty_reason=holiday → «این روز تعطیل است»', () => {
    renderWithProviders(<TurnsTimeline slots={[]} emptyReason="holiday" loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.getByText('این روز تعطیل است')).toBeInTheDocument();
  });

  it('خطای API هرگز به «شیفت کاری ندارد» ترجمه نمی‌شود', () => {
    renderWithProviders(<TurnsTimeline slots={[]} errorMessage="دکتر یافت نشد" loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.getByText('خطا در دریافت برنامهٔ این روز')).toBeInTheDocument();
    expect(screen.getByText('دکتر یافت نشد')).toBeInTheDocument();
    expect(screen.queryByText('این روز شیفت کاری ندارد')).toBeNull();
  });

  it('دلیل ناشناخته/غایب → پیام خنثی، نه day_off', () => {
    renderWithProviders(<TurnsTimeline slots={[]} loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.getByText('برنامهٔ این روز در دسترس نیست')).toBeInTheDocument();
    expect(screen.queryByText('این روز شیفت کاری ندارد')).toBeNull();
  });

  it('نوبتِ دارای بیمه، چیپ «نوع خدمت · بیمه» نشان می‌دهد', async () => {
    (api.get as ReturnType<typeof vi.fn>).mockImplementation((url: string) =>
      url === '/api/v1/billing/tenant-insurances'
        ? Promise.resolve({ success: true, data: { data: [{
            insurance_id: 3, insurance_name: 'بیمه ایران', insurance_kind: 'basic', is_active: true,
            coverage_percent: 70, franchise_percent: 0, annual_ceiling_rials: null,
          }] } })
        : Promise.resolve({ success: true, data: [] }),
    );

    const insured: TimelineSlot = {
      ...occupiedSlot,
      appointment: appt({
        insurance_base_id: 3,
        insurance_service_category: 'inpatient',
        insurance_service_category_label: 'خدمات بستری',
      }),
    };

    renderWithProviders(<TurnsTimeline slots={[insured]} loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);

    expect(await screen.findByText('خدمات بستری · بیمه ایران')).toBeInTheDocument();
  });

  it('نوبتِ بدون بیمه چیپی نشان نمی‌دهد', () => {
    renderWithProviders(<TurnsTimeline slots={[occupiedSlot]} loading={false} queryKey={['x']} onView={vi.fn()} onBook={vi.fn()} />);
    expect(screen.queryByText(/بیمه ایران/)).toBeNull();
  });
});
