import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, fireEvent } from '@testing-library/react';
import { Routes, Route } from 'react-router-dom';
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 { useAuthStore } from '../stores/authStore';
import ServiceDetailPage from './ServiceDetailPage';

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

const ITEM = {
  uuid: 'it1',
  name: 'سرم ۵۰۰cc',
  section_uuid: 'sec1',
  section_name: 'تزریقات',
  price_rials: 8_500_000,
  active: true,
  bookable: true,
  duration_minutes: 30,
  insurance_covered: true,
  staff: { uuid: 'st1', full_name: 'مریم امینی' },
  staff_members: [{ uuid: 'st1', full_name: 'مریم امینی' }],
  created_at: 1_700_000_000,
  updated_at: 1_800_000_000,
};

const mockApi = (item: unknown = ITEM, notFound = false) => {
  get.mockImplementation((url: string) => {
    if (url.includes('/subscription/my')) return Promise.resolve({ success: true, data: {
      subscription: null, used_trial: false,
      effective_plan: { name: 'professional', level: 2, max_secretaries: 10, features: { services: true } },
    } });
    if (url.includes('/payment/config')) return Promise.resolve({ success: true, data: { test_mode: true, gateways: [] } });
    if (url.includes('/service-item/')) {
      return notFound ? Promise.reject(new Error('یافت نشد')) : Promise.resolve({ success: true, data: item });
    }
    if (url.includes('/tariffs')) return Promise.resolve({ success: true, data: {
      current_year: 1404, default_price_rials: 8_500_000,
      data: [
        { uuid: 't1', year: 1404, price_rials: 8_500_000, is_active: true },
        { uuid: 't2', year: 1403, price_rials: 7_000_000, is_active: false },
      ],
    } });
    if (url.includes('/tenant-insurances')) return Promise.resolve({ data: { data: [
      { uuid: 'ins1', insurance_name: 'بیمه ایران', insurance_kind: 'basic', coverage_percent: 70 },
    ] } });
    return Promise.resolve({ success: true, data: [] });
  });
};

beforeEach(() => {
  useAuthStore.setState({ primaryRole: 'doctor' });
  get.mockReset();
  mockApi();
});

// صفحه uuid را از useParams می‌گیرد، پس به یک Route واقعی نیاز دارد.
const render = () =>
  renderWithProviders(
    <Routes>
      <Route path="/admin/clinic-services/:uuid" element={<ServiceDetailPage />} />
    </Routes>,
    { route: '/admin/clinic-services/it1' },
  );

describe('ServiceDetailPage (جزئیات سرویس)', () => {
  it('اطلاعات پایه سرویس را با breadcrumb نمایش می‌دهد', async () => {
    render();

    expect(await screen.findByRole('heading', { name: 'سرم ۵۰۰cc' })).toBeInTheDocument();
    expect(screen.getByText('سرویس‌ها')).toBeInTheDocument();
    expect(screen.getAllByText('تزریقات').length).toBeGreaterThan(0);
    expect(screen.getByText('مریم امینی')).toBeInTheDocument();
    expect(screen.getByText('۳۰ دقیقه')).toBeInTheDocument();
    expect(screen.getByText('تحت پوشش')).toBeInTheDocument();
  });

  it('تاریخ ایجاد و آخرین ویرایش را شمسی نشان می‌دهد', async () => {
    render();

    expect(await screen.findByText('تاریخ ایجاد')).toBeInTheDocument();
    expect(screen.getByText('آخرین ویرایش')).toBeInTheDocument();
    // سال شمسی معادل ۱۷۰۰۰۰۰۰۰۰ ⇒ ۱۴۰۲
    expect(screen.getByText(/۱۴۰۲/)).toBeInTheDocument();
  });

  it('تب تعرفه‌ها فهرست سال‌ها را با نشان «سال جاری» می‌آورد', async () => {
    render();
    fireEvent.click(await screen.findByText('تعرفه‌ها'));

    expect(await screen.findByText('سال جاری')).toBeInTheDocument();
    expect(screen.getByText('۱۴۰۴')).toBeInTheDocument();
    expect(screen.getByText('۱۴۰۳')).toBeInTheDocument();
  });

  it('تب بیمه‌ها قراردادها و درصد پوشش را می‌آورد', async () => {
    render();
    fireEvent.click(await screen.findByText('بیمه‌ها'));

    expect(await screen.findByText('بیمه ایران')).toBeInTheDocument();
    expect(screen.getByText(/پوشش ۷۰٪/)).toBeInTheDocument();
  });

  it('سرویس ناموجود → پیام خطا و دکمه بازگشت', async () => {
    mockApi(null, true);
    render();

    expect(await screen.findByText('سرویس یافت نشد')).toBeInTheDocument();
    expect(screen.getByText('بازگشت به سرویس‌ها')).toBeInTheDocument();
  });

  it('دکمه ویرایش، فرم مشترک سرویس را باز می‌کند', async () => {
    render();
    fireEvent.click(await screen.findByText('ویرایش'));

    expect(await screen.findByText('ویرایش سرویس')).toBeInTheDocument();
    // تنظیمات بیمه نباید در فرم باشد
    expect(screen.queryByText('این خدمت شامل بیمه می‌شود')).not.toBeInTheDocument();
  });

  it('سرویس غیرفعال نشان «غیرفعال» و دکمه فعال‌کردن دارد', async () => {
    mockApi({ ...ITEM, active: false });
    render();

    expect(await screen.findByText('غیرفعال')).toBeInTheDocument();
    expect(screen.getByText('فعال‌کردن')).toBeInTheDocument();
  });
});
