import { screen, waitFor } from "@testing-library/react";
import { describe, expect, it, vi, beforeEach } from "vitest";
import CashReconciliationReport from "./CashReconciliationReport";
import { renderWithQueryClient as render } from "./test-utils";
import { ReportsAPI } from "@/apis/ReportsAPI";

vi.mock("@/apis/ReportsAPI", () => ({
  ReportsAPI: { getCashReconciliation: vi.fn() },
}));

const dateRange = { startDate: "2026-08-01", endDate: "2026-08-31" };

describe("CashReconciliationReport", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("muestra el loader mientras carga", () => {
    ReportsAPI.getCashReconciliation.mockReturnValue(new Promise(() => {}));
    render(<CashReconciliationReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(document.querySelector(".animate-spin")).toBeTruthy();
  });

  it("muestra vacío cuando no hay sesiones", async () => {
    ReportsAPI.getCashReconciliation.mockResolvedValue([]);
    render(<CashReconciliationReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(await screen.findByText(/No hay sesiones de caja en este período/i)).toBeInTheDocument();
  });

  it("no consulta cuando falta companyId", () => {
    render(<CashReconciliationReport companyId={undefined} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(ReportsAPI.getCashReconciliation).not.toHaveBeenCalled();
  });

  it("renderiza efectivo, máquina de tránsito y diferencia", async () => {
    const onDataReady = vi.fn();
    ReportsAPI.getCashReconciliation.mockResolvedValue([
      {
        id: 1,
        session_number: "CS-1",
        seller_name: "Cajero Uno",
        cash_sales_total: 5000,
        electronic_sales_total: 3000,
        expected_cash: 15000,
        declared_cash: 15000,
        difference: 0,
      },
    ]);

    render(<CashReconciliationReport companyId={1} dateRange={dateRange} onDataReady={onDataReady} />);

    expect(await screen.findByText("CS-1")).toBeInTheDocument();
    expect(screen.getByText("Cajero Uno")).toBeInTheDocument();
    expect(screen.getByText("Máquina de tránsito")).toBeInTheDocument();
    await waitFor(() => expect(onDataReady).toHaveBeenCalled());
  });

  it("muestra guion cuando no hay declarado ni diferencia", async () => {
    ReportsAPI.getCashReconciliation.mockResolvedValue([
      {
        id: 2,
        session_number: "CS-OPEN",
        seller_name: null,
        cash_sales_total: 0,
        electronic_sales_total: 0,
        expected_cash: 1000,
        declared_cash: null,
        difference: null,
      },
    ]);

    render(<CashReconciliationReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(await screen.findByText("CS-OPEN")).toBeInTheDocument();
    expect(screen.getAllByText("—").length).toBeGreaterThan(0);
  });
});
