import { describe, it, expect, beforeEach, vi } from 'vitest';
import { renderHook, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import React from 'react';

vi.mock('../lib/api', () => ({
  api: { get: vi.fn() },
  ApiError: class extends Error {},
}));

import { api } from '../lib/api';
import { usePayments, usePatientInvoices } from './useMyPayments';

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

function wrapper({ children }: { children: React.ReactNode }) {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  return <QueryClientProvider client={qc}>{children}</QueryClientProvider>;
}

beforeEach(() => {
  get.mockReset();
  get.mockResolvedValue({ success: true, data: [], meta: { totalRecords: 0, totalPages: 0, currentPage: 1 } });
});

describe('useMyPayments', () => {
  it('builds the list URL with all active filters', async () => {
    renderHook(() => usePayments({ page: 2, national_code: '1744', status: 'paid', from: 100, to: 200 }), { wrapper });
    await waitFor(() => expect(get).toHaveBeenCalled());
    const url = get.mock.calls[0][0] as string;
    expect(url).toContain('/api/v1/my/billing/payments?');
    expect(url).toContain('page=2');
    expect(url).toContain('national_code=1744');
    expect(url).toContain('status=paid');
    expect(url).toContain('from=100');
    expect(url).toContain('to=200');
  });

  it('omits empty filters from the list URL', async () => {
    renderHook(() => usePayments({ page: 1 }), { wrapper });
    await waitFor(() => expect(get).toHaveBeenCalled());
    const url = get.mock.calls[0][0] as string;
    expect(url).not.toContain('national_code=');
    expect(url).not.toContain('status=');
  });

  it('does not fetch invoices until a patient uuid is provided', async () => {
    const { rerender } = renderHook(({ uuid }: { uuid?: string }) => usePatientInvoices(uuid, 1), {
      wrapper, initialProps: { uuid: undefined as string | undefined },
    });
    expect(get).not.toHaveBeenCalled();

    rerender({ uuid: 'abc' });
    await waitFor(() => expect(get).toHaveBeenCalled());
    expect(get.mock.calls[0][0]).toContain('/api/v1/my/billing/patients/abc/invoices');
  });
});
