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

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

vi.mock("recharts", () => ({
  ResponsiveContainer: ({ children }) => <div data-testid="chart">{children}</div>,
  BarChart: ({ children }) => <div>{children}</div>,
  Bar: () => null,
  XAxis: () => null,
  YAxis: () => null,
  CartesianGrid: () => null,
  Tooltip: () => null,
}));

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

const emptyReport = {
  invoices: [],
  by_category: [],
  totals: { invoices_count: 0, total_amount: 0, paid_amount: 0, balance: 0 },
};

describe("SupplierInvoicesReport", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    ReportsAPI.getSupplierInvoices.mockResolvedValue(emptyReport);
  });

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

  it("muestra vacío cuando no hay facturas", async () => {
    render(<SupplierInvoicesReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(await screen.findByText(/No hay facturas de proveedores en este período/i)).toBeInTheDocument();
  });

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

  it("renderiza facturas, estado, vencido y totales por categoría", async () => {
    const onDataReady = vi.fn();
    ReportsAPI.getSupplierInvoices.mockResolvedValue({
      invoices: [
        {
          id: 1,
          invoice_number: "FAC-1",
          invoice_date: "2026-08-10",
          due_date: "2020-01-01",
          supplier_name: "Lab Test",
          cost_category: "laboratorio",
          total_amount: 11900,
          paid_amount: 1900,
          balance: 10000,
          status: "partial",
        },
      ],
      by_category: [{ cost_category: "laboratorio", invoices_count: 1, total_amount: 11900, paid_amount: 1900, balance: 10000 }],
      totals: { invoices_count: 1, total_amount: 11900, paid_amount: 1900, balance: 10000 },
    });

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

    expect(await screen.findByText("FAC-1")).toBeInTheDocument();
    expect(screen.getAllByText("Laboratorio").length).toBeGreaterThan(0);
    expect(screen.getByText("Parcial")).toBeInTheDocument();
    expect(screen.getByText("Vencido")).toBeInTheDocument();
    expect(screen.getByText("16%")).toBeInTheDocument();
    await waitFor(() => expect(onDataReady).toHaveBeenCalled());
  });

  it("filtra el listado por folio o proveedor", async () => {
    const user = userEvent.setup();
    ReportsAPI.getSupplierInvoices.mockResolvedValue({
      invoices: [
        {
          id: 1,
          invoice_number: "FAC-1",
          invoice_date: "2026-08-10",
          due_date: "2026-09-10",
          supplier_name: "Lab Test",
          cost_category: "laboratorio",
          total_amount: 11900,
          paid_amount: 11900,
          balance: 0,
          status: "paid",
        },
        {
          id: 2,
          invoice_number: "FAC-2",
          invoice_date: "2026-08-11",
          due_date: "2026-09-11",
          supplier_name: "Franco Cosméticos",
          cost_category: "franco",
          total_amount: 5000,
          paid_amount: 0,
          balance: 5000,
          status: "pending",
        },
      ],
      by_category: [],
      totals: { invoices_count: 2, total_amount: 16900, paid_amount: 11900, balance: 5000 },
    });

    render(<SupplierInvoicesReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    await screen.findByText("FAC-1");

    await user.type(screen.getByPlaceholderText(/Buscar folio o proveedor/i), "Franco");
    expect(screen.queryByText("FAC-1")).not.toBeInTheDocument();
    expect(screen.getByText("FAC-2")).toBeInTheDocument();
  });

  it("filtra por categoría de costo", async () => {
    const user = userEvent.setup();
    render(<SupplierInvoicesReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    await screen.findByText(/No hay facturas de proveedores/i);

    await user.click(screen.getByRole("combobox"));
    await user.click(await screen.findByRole("option", { name: "Franco" }));

    await waitFor(() =>
      expect(ReportsAPI.getSupplierInvoices).toHaveBeenCalledWith(1, "2026-08-01", "2026-08-31", "franco"),
    );
  });
});
