import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, waitFor } 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 {},
}));

vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));

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

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

const invoice = {
  base_rials: 10_000_000,
  items_rials: 2_000_000,
  discount_rials: 1_200_000,
  insurance_base_rials: 2_160_000,
  insurance_supplementary_rials: 0,
  tax_rials: 432_000,
  final_rials: 9_072_000,
  deposit_rials: 1_425_600,
  created_at: 1_700_000_000,
  breakdown: { discounts: [{ label: 'تخفیف درصدی', rials: 1_200_000 }], sources: {} },
};

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

  it('lays out the chain down to the final amount', async () => {
    get.mockResolvedValue({ success: true, data: invoice });
    renderWithProviders(<AppointmentInvoiceCard appointmentUuid="a1" />, { route: '/admin/appointments/a1' });

    await waitFor(() => expect(screen.getByText('فاکتور')).toBeInTheDocument());
    expect(screen.getByText('قیمت پایه')).toBeInTheDocument();
    expect(screen.getByText('مبلغ نهایی')).toBeInTheDocument();
    expect(screen.getByText('بیعانه')).toBeInTheDocument();
  });

  /** ردیف صفر نباید جا بگیرد — فاکتور شلوغ خوانده نمی‌شود. */
  it('hides zero rows', async () => {
    get.mockResolvedValue({ success: true, data: invoice });
    renderWithProviders(<AppointmentInvoiceCard appointmentUuid="a1" />, { route: '/admin/appointments/a1' });

    await waitFor(() => expect(screen.getByText('فاکتور')).toBeInTheDocument());
    expect(screen.queryByText('سهم بیمهٔ تکمیلی')).not.toBeInTheDocument();
  });

  /** ⭐ نبودِ فاکتور خطا نیست: نوبتِ ثبت‌نهایی‌نشده فاکتوری ندارد. */
  it('treats a missing invoice as a normal state', async () => {
    get.mockRejectedValue(new Error('not found'));
    renderWithProviders(<AppointmentInvoiceCard appointmentUuid="a1" />, { route: '/admin/appointments/a1' });

    await waitFor(() =>
      expect(screen.getByText('برای این نوبت فاکتوری ثبت نشده است.')).toBeInTheDocument(),
    );
  });

  it('says the snapshot does not follow later price changes', async () => {
    get.mockResolvedValue({ success: true, data: invoice });
    renderWithProviders(<AppointmentInvoiceCard appointmentUuid="a1" />, { route: '/admin/appointments/a1' });

    await waitFor(() =>
      expect(screen.getByText(/تغییر بعدی تعرفه این فاکتور را عوض نمی‌کند/)).toBeInTheDocument(),
    );
  });
});
