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

vi.mock('../lib/api', () => ({ api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), delete: vi.fn() } }));

const DOCTOR = {
  id: '1',
  uuid: 'doc-1',
  name: 'پزشک دعوت‌شده',
  gender: null,
  degree: null,
  img: [],
  specialties: [],
  active: false,          // نوبت‌دهی آنلاینِ خودِ پزشک خاموش است
};

/** پاسخ‌ها بر اساس مسیر تفکیک می‌شوند، چون سه کوئری موازی می‌روند. */
function mockApi({ doctors = [DOCTOR], total = 1, permissions = [] as any[], failDoctors = false } = {}) {
  (api.get as any).mockImplementation((url: string) => {
    if (url.includes('/doctor-permissions')) return Promise.resolve({ data: permissions });
    if (url.includes('/invitations')) return Promise.resolve({ data: [] });
    if (url.includes('/doctor-list/')) {
      return failDoctors
        ? Promise.reject(new Error('boom'))
        : Promise.resolve({ data: doctors, meta: { totalRecords: total, totalPages: 1, currentPage: 1 } });
    }
    return Promise.resolve({ data: [] });
  });
}

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

  it('صفحه و سقف را به سرور می‌فرستد — وگرنه backend سر ۱۰ پزشک بی‌صدا می‌برد', async () => {
    mockApi();
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    await waitFor(() => expect(api.get).toHaveBeenCalled());
    const listCall = (api.get as any).mock.calls.find((c: any[]) => c[0].includes('/doctor-list/'));
    expect(listCall[0]).toContain('page=1');
    expect(listCall[0]).toContain('limit=10');
  });

  it('شمارندهٔ تب از meta می‌آید، نه از طول صفحهٔ جاری', async () => {
    mockApi({ doctors: [DOCTOR], total: 25 });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText(/پزشکان \(۲۵\)/)).toBeInTheDocument();
  });

  it('«نوبت‌دهی آنلاین» و «دسترسی در کلینیک» دو ستون جدا هستند', async () => {
    mockApi();
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('دسترسی در کلینیک')).toBeInTheDocument();
    expect(screen.getByText('نوبت‌دهی آنلاین')).toBeInTheDocument();
  });

  it('شمار مجوزها زیر همان بجِ دسترسی می‌آید، نه در ستون جدا', async () => {
    mockApi({
      permissions: [{
        doctor_uuid: 'doc-1',
        active: true,
        permissions: { resources: { appointments: { view: true, create: false } } },
      }],
    });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('۱ از ۲ مجوز')).toBeInTheDocument();
    expect(screen.queryByText('مجوزها')).not.toBeInTheDocument();
  });

  it('پزشکِ بدون ردیف مجوز، «پیش‌فرض» و دسترسی فعال می‌گیرد', async () => {
    mockApi({ permissions: [] });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('پیش‌فرض')).toBeInTheDocument();
  });

  it('ردیف مجوزِ خاموش، «غیرفعال» نشان می‌دهد و شمار مجوزها را می‌آورد', async () => {
    mockApi({
      permissions: [{
        doctor_uuid: 'doc-1',
        active: false,
        permissions: { resources: { appointments: { view: true, create: false } } },
      }],
    });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('۱ از ۲ مجوز')).toBeInTheDocument();
    // دو «غیرفعال»: یکی دسترسیِ کلینیک، یکی نوبت‌دهی آنلاین. پیش از این یک بج جای
    // هر دو می‌نشست و همین ابهام، پزشکِ سالم را «غیرفعال» نشان می‌داد.
    expect(screen.getAllByText('غیرفعال')).toHaveLength(2);
  });

  it('دسترسیِ فعال با نوبت‌دهیِ خاموش قاطی نمی‌شود', async () => {
    mockApi({
      permissions: [{
        doctor_uuid: 'doc-1',
        active: true,
        permissions: { resources: { appointments: { view: true } } },
      }],
    });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    // دسترسی فعال است…
    expect(await screen.findByText('فعال')).toBeInTheDocument();
    // …ولی نوبت‌دهی آنلاینِ خودِ پزشک همچنان خاموش.
    expect(screen.getByText('غیرفعال')).toBeInTheDocument();
  });

  it('خطای فهرست، پیام خطا می‌دهد نه حالت خالی', async () => {
    mockApi({ failDoctors: true });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('فهرست پزشکان بارگذاری نشد')).toBeInTheDocument();
    expect(screen.queryByText('هیچ پزشکی به این کلینیک متصل نیست')).not.toBeInTheDocument();
  });

  it('فهرست خالی، پیام خالی می‌دهد', async () => {
    mockApi({ doctors: [], total: 0 });
    renderWithProviders(<ClinicDoctorsManager clinicUuid="cl-1" />);

    expect(await screen.findByText('هیچ پزشکی به این کلینیک متصل نیست')).toBeInTheDocument();
  });
});
