import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { TrayPopover } from "@/components/TrayPopover";
import { makeFocusItem } from "../helpers/fixtures";

describe("TrayPopover", () => {
  describe("with focus item", () => {
    it("shows 'THE ONE THING' header", () => {
      const item = makeFocusItem({ title: "Review MR !847" });
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByText("THE ONE THING")).toBeInTheDocument();
    });

    it("shows focus item title", () => {
      const item = makeFocusItem({ title: "Fix auth bug" });
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByText("Fix auth bug")).toBeInTheDocument();
    });

    it("shows project path", () => {
      const item = makeFocusItem({ project: "platform/core" });
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByText(/platform\/core/)).toBeInTheDocument();
    });

    it("shows type badge", () => {
      const item = makeFocusItem({ type: "mr_review" });
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByText(/review/i)).toBeInTheDocument();
    });

    it("shows Start button", () => {
      const item = makeFocusItem();
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByRole("button", { name: /start/i })).toBeInTheDocument();
    });

    it("shows Defer button", () => {
      const item = makeFocusItem();
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByRole("button", { name: /defer/i })).toBeInTheDocument();
    });

    it("shows Skip button", () => {
      const item = makeFocusItem();
      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByRole("button", { name: /skip/i })).toBeInTheDocument();
    });
  });

  describe("empty state", () => {
    it("shows empty message when no focus item", () => {
      render(<TrayPopover focusItem={null} queueCount={0} inboxCount={0} />);

      expect(screen.getByText(/nothing focused/i)).toBeInTheDocument();
    });

    it("does not show action buttons when empty", () => {
      render(<TrayPopover focusItem={null} queueCount={0} inboxCount={0} />);

      expect(screen.queryByRole("button", { name: /start/i })).not.toBeInTheDocument();
      expect(screen.queryByRole("button", { name: /defer/i })).not.toBeInTheDocument();
      expect(screen.queryByRole("button", { name: /skip/i })).not.toBeInTheDocument();
    });
  });

  describe("counts", () => {
    it("shows queue count", () => {
      render(<TrayPopover focusItem={null} queueCount={4} inboxCount={0} />);

      expect(screen.getByText("Queue: 4")).toBeInTheDocument();
    });

    it("shows inbox count", () => {
      render(<TrayPopover focusItem={null} queueCount={0} inboxCount={3} />);

      expect(screen.getByText("Inbox: 3")).toBeInTheDocument();
    });

    it("shows both counts", () => {
      render(<TrayPopover focusItem={null} queueCount={5} inboxCount={2} />);

      expect(screen.getByText("Queue: 5")).toBeInTheDocument();
      expect(screen.getByText("Inbox: 2")).toBeInTheDocument();
    });
  });

  describe("full window link", () => {
    it("shows keyboard shortcut hint", () => {
      render(<TrayPopover focusItem={null} queueCount={0} inboxCount={0} />);

      // Should show some reference to opening full window
      expect(screen.getByText(/full window/i)).toBeInTheDocument();
    });
  });

  describe("actions", () => {
    it("calls onStart when Start clicked", async () => {
      const user = userEvent.setup();
      const onStart = vi.fn();
      const item = makeFocusItem();

      render(
        <TrayPopover
          focusItem={item}
          queueCount={0}
          inboxCount={0}
          onStart={onStart}
        />
      );

      await user.click(screen.getByRole("button", { name: /start/i }));
      expect(onStart).toHaveBeenCalledTimes(1);
    });

    it("calls onDefer with duration when Defer clicked", async () => {
      const user = userEvent.setup();
      const onDefer = vi.fn();
      const item = makeFocusItem();

      render(
        <TrayPopover
          focusItem={item}
          queueCount={0}
          inboxCount={0}
          onDefer={onDefer}
        />
      );

      await user.click(screen.getByRole("button", { name: /defer/i }));
      expect(onDefer).toHaveBeenCalledWith("1h");
    });

    it("calls onSkip when Skip clicked", async () => {
      const user = userEvent.setup();
      const onSkip = vi.fn();
      const item = makeFocusItem();

      render(
        <TrayPopover
          focusItem={item}
          queueCount={0}
          inboxCount={0}
          onSkip={onSkip}
        />
      );

      await user.click(screen.getByRole("button", { name: /skip/i }));
      expect(onSkip).toHaveBeenCalledTimes(1);
    });

    it("calls onOpenFull when full window link clicked", async () => {
      const user = userEvent.setup();
      const onOpenFull = vi.fn();

      render(
        <TrayPopover
          focusItem={null}
          queueCount={0}
          inboxCount={0}
          onOpenFull={onOpenFull}
        />
      );

      await user.click(screen.getByText(/full window/i));
      expect(onOpenFull).toHaveBeenCalledTimes(1);
    });
  });

  describe("relative time", () => {
    beforeEach(() => {
      vi.useFakeTimers();
      vi.setSystemTime(new Date("2026-02-26T12:00:00Z"));
    });

    afterEach(() => {
      vi.useRealTimers();
    });

    it("shows age for items", () => {
      const item = makeFocusItem({
        updatedAt: new Date("2026-02-24T12:00:00Z").toISOString(), // 2 days ago
      });

      render(<TrayPopover focusItem={item} queueCount={0} inboxCount={0} />);

      expect(screen.getByText(/2d/)).toBeInTheDocument();
    });
  });
});
