import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
import { TopCountriesBarChart } from "../TopCountriesBarChart";
import * as chartTheme from "../../utils/chartTheme";

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

function wrap(ui: React.ReactElement) {
  return render(
    <FluentProvider theme={webLightTheme}>{ui}</FluentProvider>,
  );
}

describe("TopCountriesBarChart", () => {
  it("shows empty state when countries is empty", () => {
    wrap(<TopCountriesBarChart countries={{}} countryNames={{}} />);
    expect(screen.getByText("No bans in this time range.")).toBeInTheDocument();
    expect(screen.queryByTestId("bar-chart")).not.toBeInTheDocument();
  });

  it("renders bar chart when country data is provided", () => {
    wrap(
      <TopCountriesBarChart
        countries={{ DE: 50, US: 30, FR: 15 }}
        countryNames={{ DE: "Germany", US: "United States", FR: "France" }}
      />,
    );
    expect(screen.getByTestId("bar-chart")).toBeInTheDocument();
  });

  it("memoizes token resolution across rerenders", () => {
    const spy = vi.spyOn(chartTheme, "resolveFluentToken");
    const props = {
      countries: { DE: 50, US: 30, FR: 15 },
      countryNames: { DE: "Germany", US: "United States", FR: "France" },
    };

    const { rerender } = wrap(<TopCountriesBarChart {...props} />);
    expect(spy).toHaveBeenCalledTimes(3);

    rerender(
      <FluentProvider theme={webLightTheme}>
        <TopCountriesBarChart {...props} />
      </FluentProvider>,
    );
    expect(spy).toHaveBeenCalledTimes(3);

    spy.mockRestore();
  });

  it("does not render more than 20 bars (TOP_N limit)", () => {
    // Build 30 countries — only top 20 should appear in the chart
    const countries: Record<string, number> = {};
    const countryNames: Record<string, string> = {};
    for (let i = 0; i < 30; i++) {
      const code = `C${String(i).padStart(2, "0")}`;
      countries[code] = 30 - i;
      countryNames[code] = `Country ${String(i)}`;
    }
    wrap(<TopCountriesBarChart countries={countries} countryNames={countryNames} />);
    // Chart should render (not show empty state) with data present
    expect(screen.getByTestId("bar-chart")).toBeInTheDocument();
  });
});
