import { requireAuth, type JWTContents } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { getPersona } from "@/lib/personas";
import { getUserTier, DAILY_LIMITS } from "@/lib/tiers";
import { generateAIReply } from "@/lib/ai-server";

export const runtime = "nodejs";

export async function POST(request: Request) {
  try {
    const user = await requireAuth(request);
    if (!user) {
      return Response.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await request.json();
    const { messages, personaId } = body as {
      messages?: { role: string; content: string }[];
      personaId?: string;
    };

    if (!messages || !Array.isArray(messages) || messages.length === 0) {
      return Response.json({ error: "messages array is required" }, { status: 400 });
    }

    if (!personaId || typeof personaId !== "string") {
      return Response.json({ error: "personaId is required" }, { status: 400 });
    }

    // Verify persona exists
    const persona = getPersona(personaId);
    if (!persona) {
      return Response.json({ error: "Invalid persona" }, { status: 400 });
    }

    // Get user from DB to check limits
    const dbUser = await prisma.user.findUnique({
      where: { id: user.userId },
    });

    if (!dbUser) {
      return Response.json({ error: "User not found" }, { status: 404 });
    }

    const tier = getUserTier(dbUser.isPremium, dbUser.isPro);
    const limits = DAILY_LIMITS[tier];

    // Check persona access for this tier
    if (!limits.personas.includes(personaId)) {
      const tierName = tier.charAt(0).toUpperCase() + tier.slice(1);
      return Response.json(
        {
          error: `This persona requires ${tier === "free" ? "Premium" : "Pro"} subscription`,
          tier,
          requiredTier: tier === "free" ? "premium" : "pro",
        },
        { status: 403 }
      );
    }

    // Check daily message limit
    const now = new Date();
    let dailyMsgCount = dbUser.dailyMsgCount;
    let dailyMsgResetAt = dbUser.dailyMsgResetAt;

    // Reset count if a new day
    if (!dailyMsgResetAt || now.getTime() - dailyMsgResetAt.getTime() > 24 * 60 * 60 * 1000) {
      dailyMsgCount = 0;
      dailyMsgResetAt = now;
    }

    if (limits.msgs !== Infinity && dailyMsgCount >= limits.msgs) {
      return Response.json(
        {
          error: "Daily message limit reached",
          count: dailyMsgCount,
          limit: limits.msgs,
          resetAt: dailyMsgResetAt.toISOString(),
        },
        { status: 429 }
      );
    }

    // Determine the user's last message for context
    const lastUserMessage = messages[messages.length - 1]?.content || "";

    // Get recent history from DB for context (up to 10 recent messages)
    const recentHistory = await prisma.chatHistory.findMany({
      where: { userId: user.userId },
      orderBy: { createdAt: "desc" },
      take: 10,
    });
    const historyContext = recentHistory
      .reverse()
      .map((h) => ({ role: h.role, content: h.content }));

    // Save user message(s) to ChatHistory
    for (const msg of messages) {
      if (msg.role === "user") {
        await prisma.chatHistory.create({
          data: {
            userId: user.userId,
            role: "user",
            content: msg.content,
            metadata: JSON.stringify({ personaId }),
          },
        });
      }
    }

    // Generate AI response (tries LLM first, falls back to keyword rules)
    const aiContent = await generateAIReply(personaId, lastUserMessage, historyContext);

    // Save AI response to ChatHistory
    const aiMessage = await prisma.chatHistory.create({
      data: {
        userId: user.userId,
        role: "assistant",
        content: aiContent,
        metadata: JSON.stringify({ personaId }),
      },
    });

    // Update daily message count
    const newCount = dailyMsgCount + messages.filter((m) => m.role === "user").length;
    await prisma.user.update({
      where: { id: user.userId },
      data: {
        dailyMsgCount: newCount,
        dailyMsgResetAt: dailyMsgResetAt,
      },
    });

    let updatedUser: any = { dailyMsgCount: newCount };
    if (newCount >= limits.msgs - 2 && limits.msgs !== Infinity) {
      updatedUser.limitWarning = true;
      updatedUser.limitRemaining = limits.msgs - newCount;
    }

    return Response.json({
      message: {
        role: "assistant",
        content: aiContent,
        createdAt: aiMessage.createdAt.toISOString(),
        id: aiMessage.id,
      },
      daily: {
        count: newCount,
        limit: limits.msgs,
        resetAt: dailyMsgResetAt.toISOString(),
      },
      user: updatedUser,
    });
  } catch (error) {
    console.error("Chat send error:", error);
    return Response.json({ error: "Internal server error" }, { status: 500 });
  }
}
