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

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

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

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

vi.mock("@/lib/sceneConfig", () => ({
  getSceneConfig: vi.fn().mockReturnValue({
    label: "吃什么",
    icon: "🍔",
    gradient: "from-orange-500 to-red-500",
    bg: "bg-amber-50",
  }),
}));

vi.mock("@/hooks/useRoomPolling", () => ({
  useRoomPolling: vi.fn().mockReturnValue({
    userCount: 2,
    match: null,
    matchType: null,
    matchLikes: 0,
    runnerUps: [],
    likeCounts: {},
    swipeCounts: {},
    restaurants: [TEST_RESTAURANT, TEST_RESTAURANT_2],
    notFound: false,
    mutate: vi.fn(),
    creatorId: "user-1",
    locked: false,
    users: ["user-1", "user-2"],
    userProfiles: {},
    scene: "eat",
    isLoading: false,
    error: undefined,
  }),
}));

vi.mock("@/components/TopNav", () => ({
  default: ({ roomId }: { roomId: string }) => (
    <nav data-testid="top-nav">{roomId}</nav>
  ),
}));

vi.mock("@/components/SwipeDeck", () => ({
  default: () => <div data-testid="swipe-deck" />,
}));

vi.mock("@/components/Skeleton", () => ({
  SwipeDeckSkeleton: () => <div data-testid="swipe-skeleton" />,
}));

vi.mock("@/components/LeaveConfirmModal", () => ({
  default: () => null,
}));

import RoomPage from "./page";

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

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

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

describe("RoomPage", () => {
  it("renders TopNav with room ID", async () => {
    renderPage();
    await waitFor(() => {
      expect(screen.getByTestId("top-nav")).toBeInTheDocument();
      expect(screen.getByText("ROOM01")).toBeInTheDocument();
    });
  });

  it("renders SwipeDeck when joined", async () => {
    renderPage();
    await waitFor(() => {
      expect(screen.getByTestId("swipe-deck")).toBeInTheDocument();
    });
  });

  it("shows 404 message when room not found", async () => {
    const { useRoomPolling } = await import("@/hooks/useRoomPolling");
    vi.mocked(useRoomPolling).mockReturnValue({
      userCount: 0,
      match: null,
      matchType: null,
      matchLikes: 0,
      runnerUps: [],
      likeCounts: {},
      swipeCounts: {},
      restaurants: [],
      notFound: true,
      mutate: vi.fn(),
      creatorId: "",
      locked: false,
      users: [],
      userProfiles: {},
      scene: "eat",
      isLoading: false,
      error: undefined,
    });

    renderPage();
    await waitFor(() => {
      expect(screen.getByText(/不存在/)).toBeInTheDocument();
    });
  });
});
