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_RESTAURANT } from "@/__tests__/helpers/fixtures";
import { ApiError } from "@/lib/api";

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

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

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

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

describe("GET /api/user/achievements", () => {
  it("returns 401 when not authenticated", async () => {
    vi.mocked(getAuthUserId).mockRejectedValueOnce(new ApiError("请先登录", 401));
    const req = createRequest("/api/user/achievements");
    const res = await GET(req, mockCtx);
    expect(res.status).toBe(401);
  });

  it("returns stats and records", async () => {
    prismaMock.decision.findMany.mockResolvedValue([
      {
        id: "dec-1",
        userId: "user-1",
        roomId: "room-1",
        restaurantName: "测试餐厅",
        restaurantData: JSON.stringify(TEST_RESTAURANT),
        matchType: "unanimous",
        participants: 2,
        createdAt: new Date("2025-01-01"),
      },
    ] as never);

    prismaMock.weekendPlan.findMany.mockResolvedValue([
      {
        id: "plan-1",
        planData: JSON.stringify({
          days: [{ date: "周六", items: [{ activity: "逛公园" }] }],
        }),
        status: "completed",
        roomId: "bb-room-1",
        createdAt: new Date("2025-01-01"),
      },
    ] as never);

    prismaMock.blindBoxRoom.findMany.mockResolvedValue([
      { id: "bb-room-1", name: "周末", code: "ABC123" },
    ] as never);

    const req = createRequest("/api/user/achievements");
    const res = await GET(req, mockCtx);
    const { status, data } = await parseJsonResponse(res);

    expect(status).toBe(200);
    expect(data.stats.totalDecisions).toBe(1);
    expect(data.stats.totalContracts).toBe(1);
    expect(data.stats.completedContracts).toBe(1);
    expect(data.stats.completionRate).toBe(100);
    expect(data.decisions).toHaveLength(1);
    expect(data.contracts).toHaveLength(1);
    expect(data.contracts[0].roomName).toBe("周末");
  });
});
