import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { DraftGridSection } from "~/components/draft/DraftGridSection";

const draftSlots = [
  { id: "slot-1", draftOrder: 1, team: { id: "team-1", name: "Alpha", logoUrl: null } },
  { id: "slot-2", draftOrder: 2, team: { id: "team-2", name: "Bravo", logoUrl: null } },
];

const ownerMap = { "team-1": "Alpha", "team-2": "Bravo" };

const draftGrid = [
  [
    { pickNumber: 1, round: 1, pickInRound: 1, teamId: "team-1", pick: { participant: { name: "Player A" }, sport: { name: "NFL" } } },
    { pickNumber: 2, round: 1, pickInRound: 2, teamId: "team-2" },
  ],
];

const baseProps = {
  draftSlots,
  draftGrid,
  currentPick: 2,
  teamTimers: {} as Record<string, number | undefined>,
  autodraftStatus: {} as Record<string, { isEnabled: boolean; mode: "next_pick" | "while_on"; queueOnly: boolean }>,
  connectedTeams: new Set(["team-1", "team-2"]),
  isCommissioner: false,
  ownerMap,
  seasonStatus: "draft" as const,
  draftPaused: false,
};

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

  describe("Team header context menus", () => {
    it("shows no header context menu for non-commissioner", () => {
      render(<DraftGridSection {...baseProps} />);
      fireEvent.contextMenu(screen.getAllByText("Alpha")[0]);
      expect(screen.queryByText("Adjust Time Bank...")).not.toBeInTheDocument();
      expect(screen.queryByText("Set Autodraft...")).not.toBeInTheDocument();
    });

    it("shows Adjust Time Bank and Set Autodraft for commissioner on right-click", () => {
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onAdjustTimeBankOpen={vi.fn()}
          onSetAutodraftOpen={vi.fn()}
        />
      );
      fireEvent.contextMenu(screen.getAllByText("Alpha")[0]);
      expect(screen.getByText("Adjust Time Bank...")).toBeInTheDocument();
      expect(screen.getByText("Set Autodraft...")).toBeInTheDocument();
    });

    it("calls onAdjustTimeBankOpen with correct teamId", async () => {
      const user = userEvent.setup();
      const onAdjustTimeBankOpen = vi.fn();
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onAdjustTimeBankOpen={onAdjustTimeBankOpen}
        />
      );
      fireEvent.contextMenu(screen.getAllByText("Bravo")[0]);
      await user.click(screen.getByText("Adjust Time Bank..."));
      expect(onAdjustTimeBankOpen).toHaveBeenCalledWith("team-2");
    });

    it("calls onSetAutodraftOpen with correct teamId", async () => {
      const user = userEvent.setup();
      const onSetAutodraftOpen = vi.fn();
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onSetAutodraftOpen={onSetAutodraftOpen}
        />
      );
      fireEvent.contextMenu(screen.getAllByText("Alpha")[0]);
      await user.click(screen.getByText("Set Autodraft..."));
      expect(onSetAutodraftOpen).toHaveBeenCalledWith("team-1");
    });
  });

  describe("Current cell context menu", () => {
    it("shows no context menu for non-commissioner on current cell", () => {
      render(
        <DraftGridSection
          {...baseProps}
          onForceAutopick={vi.fn()}
          onForceManualPickOpen={vi.fn()}
        />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #2"));
      expect(screen.queryByText("Force Auto Pick")).not.toBeInTheDocument();
    });

    it("shows Force Auto Pick and Force Manual Pick for commissioner", () => {
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onForceAutopick={vi.fn()}
          onForceManualPickOpen={vi.fn()}
        />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #2"));
      expect(screen.getByText("Force Auto Pick")).toBeInTheDocument();
      expect(screen.getByText("Force Manual Pick")).toBeInTheDocument();
    });

    it("shows no force-pick menu when callbacks absent even for commissioner", () => {
      render(<DraftGridSection {...baseProps} isCommissioner />);
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #2"));
      expect(screen.queryByText("Force Auto Pick")).not.toBeInTheDocument();
    });

    it("calls onForceAutopick with correct args", async () => {
      const user = userEvent.setup();
      const onForceAutopick = vi.fn();
      render(
        <DraftGridSection {...baseProps} isCommissioner onForceAutopick={onForceAutopick} />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #2"));
      await user.click(screen.getByText("Force Auto Pick"));
      expect(onForceAutopick).toHaveBeenCalledWith(2, "team-2");
    });

    it("calls onForceManualPickOpen with correct args", async () => {
      const user = userEvent.setup();
      const onForceManualPickOpen = vi.fn();
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onForceManualPickOpen={onForceManualPickOpen}
        />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #2"));
      await user.click(screen.getByText("Force Manual Pick"));
      expect(onForceManualPickOpen).toHaveBeenCalledWith(2, "team-2");
    });
  });

  describe("Picked cell context menu", () => {
    it("shows Replace Pick and Roll Back for commissioner on a picked cell", () => {
      render(
        <DraftGridSection
          {...baseProps}
          isCommissioner
          onReplacePick={vi.fn()}
          onRollbackToPick={vi.fn()}
        />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #1"));
      expect(screen.getByText("Replace Pick")).toBeInTheDocument();
      expect(screen.getByText("Roll Back to This Pick")).toBeInTheDocument();
    });

    it("shows no context menu on picked cell for non-commissioner", () => {
      render(
        <DraftGridSection
          {...baseProps}
          onReplacePick={vi.fn()}
          onRollbackToPick={vi.fn()}
        />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #1"));
      expect(screen.queryByText("Replace Pick")).not.toBeInTheDocument();
    });

    it("calls onReplacePick with correct args", async () => {
      const user = userEvent.setup();
      const onReplacePick = vi.fn();
      render(
        <DraftGridSection {...baseProps} isCommissioner onReplacePick={onReplacePick} />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #1"));
      await user.click(screen.getByText("Replace Pick"));
      expect(onReplacePick).toHaveBeenCalledWith(1, "team-1");
    });

    it("calls onRollbackToPick with correct pickNumber", async () => {
      const user = userEvent.setup();
      const onRollbackToPick = vi.fn();
      render(
        <DraftGridSection {...baseProps} isCommissioner onRollbackToPick={onRollbackToPick} />
      );
      fireEvent.contextMenu(screen.getByTitle("Overall Pick #1"));
      await user.click(screen.getByText("Roll Back to This Pick"));
      expect(onRollbackToPick).toHaveBeenCalledWith(1);
    });
  });
});
