import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { KEYS } from "../../data/mock/keys";
import type { ExploreResult, WatchTermSuggestion } from "../../domain/types";
import { I18nProvider } from "../../i18n/I18nContext";
import { ExplorePanel } from "./ExplorePanel";

const backend = vi.hoisted(() => ({
  suggestWatchTerms: vi.fn<(limit?: number) => Promise<WatchTermSuggestion[]>>(),
  exploreOpportunities: vi.fn<(terms: string[]) => Promise<ExploreResult>>(),
}));

vi.mock("../../data/DataContext", () => ({
  useRepos: () => ({
    radar: {
      suggestWatchTerms: backend.suggestWatchTerms,
      exploreOpportunities: backend.exploreOpportunities,
    },
  }),
}));

function renderPanel(onExplored = vi.fn()) {
  return render(
    <I18nProvider>
      <ExplorePanel onExplored={onExplored} />
    </I18nProvider>,
  );
}

describe("ExplorePanel", () => {
  beforeEach(() => {
    backend.suggestWatchTerms.mockReset();
    backend.exploreOpportunities.mockReset();
    localStorage.setItem(
      KEYS.uiPrefs,
      JSON.stringify({ locale: "zh-TW", currency: "TWD", theme: "system" }),
    );
    backend.suggestWatchTerms.mockResolvedValue([
      { term: "保母 求推薦", reason: "常見求助", usage: "include" },
      { term: "到府保母", reason: "到府需求", usage: "include" },
    ]);
  });

  it("loads suggestions as chips and runs explore", async () => {
    backend.exploreOpportunities.mockResolvedValue({
      sweep_id: "s1",
      hit_count: 5,
      judged_count: 4,
      created_count: 2,
      truncated_count: 0,
      credits_used: 3,
    });
    const onExplored = vi.fn();
    renderPanel(onExplored);

    await waitFor(() => expect(backend.suggestWatchTerms).toHaveBeenCalled());
    // pre-filled selected chips (title = remove)
    expect(await screen.findAllByTitle("點一下移除")).toHaveLength(2);

    fireEvent.click(screen.getByRole("button", { name: "開始探索" }));
    await waitFor(() => expect(backend.exploreOpportunities).toHaveBeenCalledTimes(1));
    expect(backend.exploreOpportunities).toHaveBeenCalledWith(
      expect.arrayContaining(["保母 求推薦", "到府保母"]),
    );
    expect(await screen.findByText(/找到 5 則/)).toBeTruthy();
    expect(onExplored).toHaveBeenCalledTimes(1);
  });

  it("blocks long non-Threads terms", async () => {
    backend.suggestWatchTerms.mockResolvedValue([]);
    renderPanel();
    await waitFor(() => expect(backend.suggestWatchTerms).toHaveBeenCalled());

    fireEvent.change(screen.getByLabelText("自己加一組短詞"), {
      target: { value: "台北 婚攝 推薦 價格" },
    });
    fireEvent.click(screen.getByRole("button", { name: "加入" }));
    expect(screen.getByRole("alert").textContent).toMatch(/最多 2 個詞/);
    expect(backend.exploreOpportunities).not.toHaveBeenCalled();
  });

  it("can remove a chip before submit", async () => {
    renderPanel();
    await waitFor(() => expect(screen.getAllByTitle("點一下移除").length).toBe(2));
    fireEvent.click(screen.getAllByTitle("點一下移除")[0]!);
    await waitFor(() => {
      expect(screen.getAllByTitle("點一下移除").length).toBe(1);
    });
  });
});
