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

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

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

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

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

  it("consulta el año/mes derivado del inicio del rango, sin desfase de timezone", async () => {
    ReportsAPI.getCommissions.mockResolvedValue([]);
    render(<CommissionsReport companyId={7} dateRange={dateRange} onDataReady={vi.fn()} />);

    await waitFor(() => expect(ReportsAPI.getCommissions).toHaveBeenCalledWith(7, 2026, 8));
  });

  it("muestra mensaje cuando no hay comisiones en el período", async () => {
    ReportsAPI.getCommissions.mockResolvedValue([]);
    render(<CommissionsReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);

    expect(await screen.findByText(/No hay comisiones en este período/i)).toBeInTheDocument();
  });

  it("renderiza el detalle real por vendedor, usando seller_code cuando falta el nombre", async () => {
    const onDataReady = vi.fn();
    ReportsAPI.getCommissions.mockResolvedValue([
      {
        idseller: 1,
        seller_name: "Vendedor Uno",
        seller_code: "SLR-1",
        level: 1,
        group_volume: 100000,
        applied_percentage: 6,
        commission_amount: 6000,
      },
      {
        idseller: 2,
        seller_name: null,
        seller_code: "SLR-2",
        level: 2,
        group_volume: 50000,
        applied_percentage: 4,
        commission_amount: 2000,
      },
    ]);

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

    expect(await screen.findByText("Vendedor Uno")).toBeInTheDocument();
    expect(screen.getByText("SLR-2")).toBeInTheDocument();
    expect(screen.getAllByText("$8,000").length).toBeGreaterThan(0);

    await waitFor(() => expect(onDataReady).toHaveBeenCalled());
    const payload = onDataReady.mock.calls[0][0];
    expect(payload.fileName).toBe("comisiones");
    expect(payload.data).toHaveLength(2);
  });

  it("usa fallbacks a 0 cuando faltan nombre, código, volumen, % o comisión", async () => {
    ReportsAPI.getCommissions.mockResolvedValue([
      {
        idseller: 99,
        seller_name: null,
        seller_code: null,
        level: null,
        group_volume: null,
        applied_percentage: null,
        commission_amount: null,
      },
    ]);

    render(<CommissionsReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);

    expect(await screen.findByText("Vendedor #99")).toBeInTheDocument();
    expect(screen.getAllByText("$0").length).toBeGreaterThan(0);
    expect(screen.getByText("0%")).toBeInTheDocument();
  });

  it("no consulta la API cuando no hay companyId", () => {
    render(<CommissionsReport companyId={undefined} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(ReportsAPI.getCommissions).not.toHaveBeenCalled();
  });
});
