import { describe, it, expect, vi, beforeEach } from "vitest";
import { prismaMock, resetPrismaMock } from "@/__tests__/helpers/prisma-mock";
import { createRequest, parseJsonResponse } from "@/__tests__/helpers/api-test-utils";
import { TEST_USER, TEST_BLINDBOX_ROOM } from "@/__tests__/helpers/fixtures";
import { ApiError } from "@/lib/api";

vi.mock("@/lib/auth", () => ({
  getAuthUserId: vi.fn().mockResolvedValue("user-1"),
}));

vi.mock("@/lib/blindbox", () => ({
  generateUniqueRoomCode: vi.fn().mockResolvedValue("XYZ789"),
}));

import { POST } from "./route";
import { getAuthUserId } from "@/lib/auth";

const mockCtx = { params: Promise.resolve({}) };

beforeEach(() => {
  resetPrismaMock();
  vi.mocked(getAuthUserId).mockResolvedValue("user-1");
});

describe("POST /api/blindbox/room", () => {
  it("creates a blindbox room", async () => {
    prismaMock.user.findUnique.mockResolvedValue(TEST_USER as never);
    prismaMock.blindBoxRoom.create.mockResolvedValue({
      ...TEST_BLINDBOX_ROOM,
      code: "XYZ789",
    } as never);

    const req = createRequest("/api/blindbox/room", {
      method: "POST",
      body: { name: "周末计划" },
    });
    const res = await POST(req, mockCtx);
    const { status, data } = await parseJsonResponse(res);

    expect(status).toBe(201);
    expect(data.code).toBe("XYZ789");
  });

  it("uses default room name when not provided", async () => {
    prismaMock.user.findUnique.mockResolvedValue(TEST_USER as never);
    prismaMock.blindBoxRoom.create.mockResolvedValue(TEST_BLINDBOX_ROOM as never);

    const req = createRequest("/api/blindbox/room", {
      method: "POST",
      body: {},
    });
    const res = await POST(req, mockCtx);
    expect(res.status).toBe(201);
  });

  it("returns 401 when not authenticated", async () => {
    vi.mocked(getAuthUserId).mockRejectedValueOnce(new ApiError("请先登录", 401));
    const req = createRequest("/api/blindbox/room", {
      method: "POST",
      body: { name: "test" },
    });
    const res = await POST(req, mockCtx);
    expect(res.status).toBe(401);
  });

  it("returns 400 when room name too long", async () => {
    const req = createRequest("/api/blindbox/room", {
      method: "POST",
      body: { name: "a".repeat(31) },
    });
    const res = await POST(req, mockCtx);
    expect(res.status).toBe(400);
  });
});
