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 { Routes, Route } from 'react-router-dom';
import { api } from '../lib/api';
import PatientPackageLedgerPage from './PatientPackageLedgerPage';

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

const ledger = {
  package: {
    uuid: 'pp1',
    package_uuid: 'p1',
    package_name: '۶ جلسه لیزر',
    patient_uuid: 'pat1',
    session_count: 6,
    price_paid_rials: 25_000_000,
    purchased_at: 1_700_000_000,
    valid_to: null,
    expired: false,
    balance: 5,
  },
  rows: [
    {
      uuid: 'l1', kind: 'purchase', delta: 6, appointment_uuid: null, service_uuid: null,
      service_name: null, reason: 'خرید پکیج', created_by: 'u1', created_at: 1_700_000_000,
      running_balance: 6,
    },
    {
      uuid: 'l2', kind: 'consume', delta: -1, appointment_uuid: 'a1', service_uuid: 's1',
      service_name: 'لیزر', reason: null, created_by: null, created_at: 1_700_100_000,
      running_balance: 5,
    },
  ],
};

function renderPage() {
  return renderWithProviders(
    <Routes>
      <Route path="/admin/patient-package/:patientPackageUuid/ledger" element={<PatientPackageLedgerPage />} />
    </Routes>,
    { route: '/admin/patient-package/pp1/ledger' },
  );
}

describe('PatientPackageLedgerPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    get.mockResolvedValue({ success: true, data: ledger });
  });

  /** ماندهٔ هر ردیف باید دیده شود — همان چیزی که یک شمارنده نمی‌تواند نشان دهد. */
  it('shows every ledger row with its running balance', async () => {
    renderPage();

    await waitFor(() => expect(screen.getByText('خرید')).toBeInTheDocument());
    expect(screen.getByText('مصرف در نوبت')).toBeInTheDocument();
    expect(screen.getByText('+6')).toBeInTheDocument();
    expect(screen.getByText('-1')).toBeInTheDocument();
  });

  it('summarises the balance against the purchased session count', async () => {
    renderPage();

    await waitFor(() => expect(screen.getByText(/از 6 جلسه/)).toBeInTheDocument());

    // عدد مانده در همان جمله می‌آید؛ «۵ از ۶» یعنی یک جلسه مصرف شده.
    expect(screen.getByText(/از 6 جلسه/).parentElement).toHaveTextContent('5');
  });
});
