import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireMembership } from "@/lib/blindbox";
import { apiHandler, ApiError, requireUserId } from "@/lib/api";
import { validateIdeaContent, requireString } from "@/lib/validation";
import { tagIdea } from "@/lib/ai";

const TAG_TIMEOUT_MS = 3000;

export const POST = apiHandler(async (req) => {
  const { roomId, userId, content } = await req.json();

  requireUserId(userId);
  requireString(roomId, "roomId");
  const trimmedContent = validateIdeaContent(content);

  await requireMembership(roomId, userId);

  const idea = await prisma.blindBoxIdea.create({
    data: { roomId, userId, content: trimmedContent },
  });

  const tags = await Promise.race([
    tagIdea(trimmedContent),
    new Promise<null>((resolve) => setTimeout(() => resolve(null), TAG_TIMEOUT_MS)),
  ]);

  if (tags) {
    await prisma.blindBoxIdea.update({
      where: { id: idea.id },
      data: {
        category: tags.category,
        timeSlot: tags.timeSlot,
        estimatedMinutes: tags.estimatedMinutes,
        outdoor: tags.outdoor,
        searchQuery: tags.searchQuery,
        searchType: tags.searchType,
      },
    });
  }

  return NextResponse.json(
    { id: idea.id, ...tags && { tags } },
    { status: 201 },
  );
});

export const GET = apiHandler(async (req) => {
  const userId = requireUserId(req.nextUrl.searchParams.get("userId"));
  const roomId = requireString(req.nextUrl.searchParams.get("roomId"), "roomId");

  await requireMembership(roomId, userId);

  const [poolCount, myIdeas, drawn] = await Promise.all([
    prisma.blindBoxIdea.count({
      where: { roomId, status: "in_pool" },
    }),
    prisma.blindBoxIdea.findMany({
      where: { roomId, userId, status: "in_pool" },
      orderBy: { createdAt: "desc" },
      select: {
        id: true,
        content: true,
        createdAt: true,
        category: true,
        timeSlot: true,
        estimatedMinutes: true,
        outdoor: true,
        searchQuery: true,
        searchType: true,
      },
    }),
    prisma.blindBoxIdea.findMany({
      where: { roomId, status: "drawn" },
      orderBy: { createdAt: "desc" },
      include: {
        user: { select: { id: true, username: true, avatar: true } },
        drawnBy: { select: { id: true, username: true, avatar: true } },
      },
    }),
  ]);

  return NextResponse.json({ poolCount, myIdeas, drawn });
});

export const PUT = apiHandler(async (req) => {
  const { ideaId, userId, content } = await req.json();

  requireUserId(userId);
  requireString(ideaId, "ideaId");
  const trimmedContent = validateIdeaContent(content);

  const { count } = await prisma.blindBoxIdea.updateMany({
    where: { id: ideaId, userId, status: "in_pool" },
    data: { content: trimmedContent },
  });

  if (count === 0) throw new ApiError("想法不存在、已被抽中或无权编辑", 404);

  const tags = await Promise.race([
    tagIdea(trimmedContent),
    new Promise<null>((resolve) => setTimeout(() => resolve(null), TAG_TIMEOUT_MS)),
  ]);

  if (tags) {
    await prisma.blindBoxIdea.updateMany({
      where: { id: ideaId, userId, status: "in_pool" },
      data: {
        category: tags.category,
        timeSlot: tags.timeSlot,
        estimatedMinutes: tags.estimatedMinutes,
        outdoor: tags.outdoor,
        searchQuery: tags.searchQuery,
        searchType: tags.searchType,
      },
    });
  }

  return NextResponse.json({ id: ideaId, content: trimmedContent, ...tags && { tags } });
});

export const DELETE = apiHandler(async (req) => {
  const { ideaId, userId } = await req.json();

  requireUserId(userId);
  requireString(ideaId, "ideaId");

  const { count } = await prisma.blindBoxIdea.deleteMany({
    where: { id: ideaId, userId, status: "in_pool" },
  });

  if (count === 0) throw new ApiError("想法不存在、已被抽中或无权删除", 404);

  return NextResponse.json({ deleted: true });
});
