import { render, screen, fireEvent, cleanup } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";

import {
  TerminalSessionTabs,
  type TerminalSessionInfo,
} from "./terminal-session-tabs";

const mockSessions: TerminalSessionInfo[] = [
  { id: "s1", name: "Session 1", status: "connected" },
  { id: "s2", name: "Session 2", status: "connecting" },
  { id: "s3", name: "Session 3", status: "disconnected" },
];

afterEach(() => {
  cleanup();
});

describe("TerminalSessionTabs", () => {
  it("renders all tabs", () => {
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={vi.fn()}
      />
    );

    expect(screen.getByText("Session 1")).toBeInTheDocument();
    expect(screen.getByText("Session 2")).toBeInTheDocument();
    expect(screen.getByText("Session 3")).toBeInTheDocument();
    expect(screen.getByRole("button", { name: /new session/i })).toBeInTheDocument();
  });

  it("clicking a tab calls onSelect", () => {
    const onSelect = vi.fn();
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={onSelect}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={vi.fn()}
      />
    );

    fireEvent.click(screen.getAllByText("Session 2")[0]);
    expect(onSelect).toHaveBeenCalledWith("s2");
  });

  it("close button calls onClose after confirmation", () => {
    const onClose = vi.fn();
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={onClose}
        onCreate={vi.fn()}
        onRename={vi.fn()}
      />
    );

    const closeButton = screen.getByLabelText("Close session Session 1");
    // First click shows confirm
    fireEvent.click(closeButton);
    expect(screen.getByText("Close?")).toBeInTheDocument();

    // Click confirm text
    fireEvent.click(screen.getByText("Close?"));
    expect(onClose).toHaveBeenCalledWith("s1");
  });

  it("double-click enables rename and Enter commits", () => {
    const onRename = vi.fn();
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={onRename}
      />
    );

    fireEvent.doubleClick(screen.getAllByText("Session 1")[0]);
    const input = screen.getByLabelText("Rename session");
    expect(input).toBeInTheDocument();

    fireEvent.change(input, { target: { value: "Renamed" } });
    fireEvent.keyDown(input, { key: "Enter" });
    expect(onRename).toHaveBeenCalledWith("s1", "Renamed");
  });

  it("double-click enables rename and Escape cancels", () => {
    const onRename = vi.fn();
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={onRename}
      />
    );

    fireEvent.doubleClick(screen.getAllByText("Session 1")[0]);
    const input = screen.getByLabelText("Rename session");
    fireEvent.change(input, { target: { value: "Renamed" } });
    fireEvent.keyDown(input, { key: "Escape" });
    expect(onRename).not.toHaveBeenCalled();
    expect(screen.getByText("Session 1")).toBeInTheDocument();
  });

  it("plus button is disabled at 5 sessions", () => {
    const fiveSessions: TerminalSessionInfo[] = Array.from({ length: 5 }, (_, i) => ({
      id: `s${i + 1}`,
      name: `Session ${i + 1}`,
      status: "connected",
    }));

    render(
      <TerminalSessionTabs
        sessions={fiveSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={vi.fn()}
      />
    );

    const newButton = screen.getByRole("button", { name: /new session/i });
    expect(newButton).toBeDisabled();
  });

  it("status dot reflects connection state", () => {
    render(
      <TerminalSessionTabs
        sessions={mockSessions}
        activeSessionId="s1"
        onSelect={vi.fn()}
        onClose={vi.fn()}
        onCreate={vi.fn()}
        onRename={vi.fn()}
      />
    );

    const tabs = screen.getAllByRole("tab");
    expect(tabs).toHaveLength(3);
    expect(tabs[0].querySelector(".connected")).toBeInTheDocument();
    expect(tabs[1].querySelector(".connecting")).toBeInTheDocument();
    expect(tabs[2].querySelector(".disconnected")).toBeInTheDocument();
  });
});
