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

vi.mock("@/apis/ReportsAPI", () => ({
  ReportsAPI: { getNewIncorporations: vi.fn(), getNewIncorporationCustomers: 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 summary = {
  totals: { count: 3, web_count: 1, seller_count: 2, with_purchase_count: 1, variation_percent: 50 },
  comparison: { from: "2026-07-01", to: "2026-07-31", totals: { count: 2 }, variation_percent: 50 },
  rows: [
    {
      seller_key: "1",
      seller_id: 1,
      seller_name: "Ejecutiva Rosa",
      new_customers_count: 2,
      with_purchase_count: 1,
      share_percent: 66.67,
      variation_percent: 100,
    },
    {
      seller_key: "web",
      seller_id: null,
      seller_name: "Web",
      new_customers_count: 1,
      with_purchase_count: 0,
      share_percent: 33.33,
      variation_percent: null,
    },
  ],
};

describe("IncorporationsReport", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    ReportsAPI.getNewIncorporationCustomers.mockResolvedValue({
      rows: [],
      meta: { total: 0, page: 1, per_page: 10 },
    });
  });

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

  it("muestra vacío cuando no hay incorporaciones", async () => {
    ReportsAPI.getNewIncorporations.mockResolvedValue({
      totals: { count: 0, web_count: 0, seller_count: 0, with_purchase_count: 0 },
      rows: [],
      comparison: null,
    });
    render(<IncorporationsReport companyId={1} dateRange={dateRange} onDataReady={vi.fn()} />);
    expect(await screen.findByText(/No hay incorporaciones en este período/i)).toBeInTheDocument();
  });

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

  it("agrupa por ejecutiva y canal Web con KPIs", async () => {
    const onDataReady = vi.fn();
    ReportsAPI.getNewIncorporations.mockResolvedValue(summary);

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

    expect(await screen.findByText("Ejecutiva Rosa")).toBeInTheDocument();
    expect(screen.getByText("Web")).toBeInTheDocument();
    expect(screen.getByText("Total incorporaciones")).toBeInTheDocument();
    expect(screen.getByText("Canal web")).toBeInTheDocument();
    await waitFor(() => expect(onDataReady).toHaveBeenCalled());
  });

  it("al hacer clic en una fila carga el detalle de clientes", async () => {
    const user = userEvent.setup();
    ReportsAPI.getNewIncorporations.mockResolvedValue(summary);
    ReportsAPI.getNewIncorporationCustomers.mockResolvedValue({
      rows: [
        {
          id: 10,
          name: "Ana Web",
          tax_id: "22222222-2",
          incorporation_date: "2026-08-12",
          seller_name: "Web",
          referred_by_name: "Socio Referente",
          last_sale_at: null,
          lifetime_purchase_total: 0,
          has_purchase: false,
        },
      ],
      meta: { total: 1, page: 1, per_page: 10 },
    });

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

    await screen.findByText("Ejecutiva Rosa");
    await user.click(screen.getByText("Web"));

    expect(await screen.findByText("Clientes de Web")).toBeInTheDocument();
    expect(await screen.findByText("Ana Web")).toBeInTheDocument();
    expect(screen.getByText("Socio Referente")).toBeInTheDocument();
    await waitFor(() => {
      expect(ReportsAPI.getNewIncorporationCustomers).toHaveBeenCalledWith(
        1,
        "2026-08-01",
        "2026-08-31",
        "web",
        "",
        1,
        10,
      );
    });
  });
});
