import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import React from "react";
import { ToastContext, type ToastContextValue } from "@/hooks/useToast";

vi.mock("next/navigation", () => ({
  useRouter: () => ({
    push: vi.fn(),
    back: vi.fn(),
  }),
}));

vi.mock("@/lib/userId", () => ({
  getUserId: vi.fn().mockReturnValue("user-1"),
  getCachedPreferences: vi.fn().mockReturnValue({}),
}));

vi.mock("@/lib/sceneConfig", () => ({
  SCENES: ["eat", "drinks"],
  getSceneConfig: vi.fn().mockReturnValue({
    key: "eat",
    label: "餐厅",
    emoji: "🍜",
    verb: "吃",
    poiTypes: "050000",
    defaultImage: "",
    hotTags: ["火锅", "日料", "烧烤"],
    priceOptions: [{ label: "不限", value: "any" }],
    tagLabel: "口味",
    tagPlaceholder: "想吃什么？",
    loadingText: "正在搜索...",
    emptyError: "没找到",
    subtitle: "一起选餐厅",
    inviteText: "邀请你",
    shareTitle: "分享",
    shareText: "一起来",
    qrSubtitle: "扫码加入",
  }),
}));

vi.mock("@/hooks/useGeolocation", () => ({
  useGeolocation: vi.fn().mockReturnValue({
    status: "success",
    coords: { lat: 31.2, lng: 121.4 },
    locationName: "上海",
    retry: vi.fn(),
  }),
}));

vi.mock("@/lib/room", () => ({
  joinRoom: vi.fn().mockResolvedValue(undefined),
}));

const mockFetch = vi.fn().mockResolvedValue({
  ok: true,
  json: () => Promise.resolve({ suggestions: [] }),
});
vi.stubGlobal("fetch", mockFetch);

import PanicPage from "./page";
import { joinRoom } from "@/lib/room";

const toastCtx: ToastContextValue = { show: vi.fn() };

function renderPage() {
  return render(
    React.createElement(
      ToastContext.Provider,
      { value: toastCtx },
      React.createElement(PanicPage),
    ),
  );
}

beforeEach(() => {
  vi.clearAllMocks();
});

describe("PanicPage", () => {
  it("renders page title", () => {
    renderPage();
    expect(screen.getByText("极速救场")).toBeInTheDocument();
  });

  it("renders location search input", () => {
    renderPage();
    expect(screen.getByPlaceholderText(/搜索位置/)).toBeInTheDocument();
  });

  it("renders distance options", () => {
    renderPage();
    expect(screen.getByText("1km")).toBeInTheDocument();
    expect(screen.getByText("3km")).toBeInTheDocument();
    expect(screen.getByText("5km")).toBeInTheDocument();
  });

  it("renders scene selector with labels", () => {
    renderPage();
    expect(screen.getAllByText("餐厅").length).toBeGreaterThanOrEqual(1);
  });

  it("normalizes room code as 6-char alphanumeric when joining", async () => {
    renderPage();
    const input = screen.getByPlaceholderText("输入 6 位房间号");
    fireEvent.change(input, { target: { value: "ab12-cd!" } });
    expect(input).toHaveValue("AB12CD");

    const submitButton = screen.getByLabelText("加入房间");
    expect(submitButton).not.toBeDisabled();

    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(vi.mocked(joinRoom)).toHaveBeenCalledWith("AB12CD", "user-1");
    });
  });
});
