import { fireEvent, screen } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderWithProviders } from "test-utils";

const useChatInputLlmProfileStateMock = vi.fn();

vi.mock("#/hooks/use-chat-input-llm-profile-state", () => ({
  useChatInputLlmProfileState: () => useChatInputLlmProfileStateMock(),
}));

// eslint-disable-next-line import/first
import { ChatInputLlmProfilePicker } from "#/components/features/chat/components/chat-input-llm-profile-picker";

const PROFILES = [
  {
    name: "Fast",
    model: "openai/gpt-4o-mini",
    base_url: null,
    api_key_set: true,
  },
  {
    name: "Smart",
    model: "anthropic/claude-opus",
    base_url: null,
    api_key_set: true,
  },
];

const selectProfile = vi.fn();

function state(overrides = {}) {
  return {
    profiles: PROFILES,
    currentProfileName: "Fast",
    currentProfileModel: "openai/gpt-4o-mini",
    isLoading: false,
    isSwitching: false,
    canSwitchProfile: true,
    selectProfile,
    ...overrides,
  };
}

describe("ChatInputLlmProfilePicker", () => {
  beforeEach(() => {
    selectProfile.mockReset();
    useChatInputLlmProfileStateMock.mockReset();
    useChatInputLlmProfileStateMock.mockReturnValue(state());
  });

  it("renders nothing while loading or when there are no profiles", () => {
    useChatInputLlmProfileStateMock.mockReturnValue(
      state({ profiles: [], isLoading: false }),
    );
    const { container } = renderWithProviders(<ChatInputLlmProfilePicker />);
    expect(container).toBeEmptyDOMElement();
  });

  it("labels the pill with the current profile name", () => {
    renderWithProviders(<ChatInputLlmProfilePicker />);
    expect(screen.getByTestId("chat-input-llm-profile")).toHaveTextContent(
      "Fast",
    );
  });

  it("live-switches to the picked profile", () => {
    renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));
    fireEvent.click(screen.getByTestId("chat-input-llm-profile-option-Smart"));

    expect(selectProfile).toHaveBeenCalledWith("Smart");
  });

  it("does not switch when the current profile is re-selected", () => {
    renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));
    fireEvent.click(screen.getByTestId("chat-input-llm-profile-option-Fast"));

    expect(selectProfile).not.toHaveBeenCalled();
  });

  it("names the current profile without selectable options when switching is unavailable", () => {
    useChatInputLlmProfileStateMock.mockReturnValue(
      state({ canSwitchProfile: false }),
    );

    renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));

    expect(
      screen.getByTestId("chat-input-llm-profile-current"),
    ).toHaveTextContent("Fast");
    expect(
      screen.queryByTestId("chat-input-llm-profile-option-Smart"),
    ).not.toBeInTheDocument();
  });

  it("labels a free OpenHands route in the profile menu", () => {
    useChatInputLlmProfileStateMock.mockReturnValue(
      state({
        profiles: [
          {
            name: "Free",
            model: "openhands/glm-5.2",
            base_url: null,
            api_key_set: true,
          },
        ],
        currentProfileName: "Free",
        currentProfileModel: "openhands/glm-5.2",
      }),
    );

    renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));

    expect(screen.getByText("OpenHands GLM-5.2 (free)")).toBeInTheDocument();
  });

  it("labels a free OpenHands route in the read-only profile menu", () => {
    useChatInputLlmProfileStateMock.mockReturnValue(
      state({
        canSwitchProfile: false,
        currentProfileModel: "openhands/glm-5.2",
      }),
    );

    renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));

    expect(
      screen.getByTestId("chat-input-llm-profile-current"),
    ).toHaveTextContent("OpenHands GLM-5.2 (free)");
  });

  it("links to the LLM profiles settings page", () => {
    const { container } = renderWithProviders(<ChatInputLlmProfilePicker />);
    fireEvent.click(screen.getByTestId("chat-input-llm-profile"));

    expect(
      container.ownerDocument.querySelector('a[href="/settings/llm"]'),
    ).not.toBeNull();
  });
});
