import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { logger } from "@/lib/logger";

/**
 * GET /api/token/config — Get Token configuration (admin only).
 * PATCH /api/token/config — Update Token configuration (admin only).
 *
 * Admin = site owner. For now, the first user or users with plan="enterprise".
 * In a real deployment, you'd check a role field.
 */

async function isAdmin(userId: string): Promise<boolean> {
  // Site owner check: first user created, or any enterprise user
  const user = await db.user.findUnique({
    where: { id: userId },
    select: { plan: true, createdAt: true },
  });
  if (!user) return false;
  if (user.plan === "enterprise") return true;

  // First-user check (site owner)
  const firstUser = await db.user.findFirst({
    orderBy: { createdAt: "asc" },
    select: { id: true },
  });
  return firstUser?.id === userId;
}

export async function GET() {
  const session = await auth();
  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!(await isAdmin(session.user.id))) {
    return NextResponse.json({ error: "Admin access required" }, { status: 403 });
  }

  try {
    let config = await db.tokenConfig.findUnique({ where: { id: "singleton" } });
    if (!config) {
      config = await db.tokenConfig.create({ data: { id: "singleton" } });
    }

    return NextResponse.json({ config });
  } catch (err) {
    logger.error({ err, action: "token_config_get_error" }, "Failed to get Token config");
    return NextResponse.json({ error: "Failed to load config" }, { status: 500 });
  }
}

export async function PATCH(req: NextRequest) {
  const session = await auth();
  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!(await isAdmin(session.user.id))) {
    return NextResponse.json({ error: "Admin access required" }, { status: 403 });
  }

  try {
    const body = await req.json();

    // Allowlisted fields
    const allowed = [
      "enabled",
      "chatModel",
      "researchModel",
      "reasoningModel",
      "classificationModel",
      "systemPrompt",
      "maxTokensPerReply",
      "temperature",
      "monthlyBudgetUsd",
    ];

    const updateData: Record<string, unknown> = {};
    for (const key of allowed) {
      if (key in body) {
        updateData[key] = body[key];
      }
    }

    // Validate types
    if ("enabled" in updateData && typeof updateData.enabled !== "boolean") {
      return NextResponse.json({ error: "enabled must be boolean" }, { status: 400 });
    }
    if ("temperature" in updateData) {
      const t = Number(updateData.temperature);
      if (isNaN(t) || t < 0 || t > 2) {
        return NextResponse.json({ error: "temperature must be 0-2" }, { status: 400 });
      }
      updateData.temperature = t;
    }
    if ("maxTokensPerReply" in updateData) {
      const m = Number(updateData.maxTokensPerReply);
      if (isNaN(m) || m < 100 || m > 32000) {
        return NextResponse.json({ error: "maxTokensPerReply must be 100-32000" }, { status: 400 });
      }
      updateData.maxTokensPerReply = m;
    }
    if ("monthlyBudgetUsd" in updateData) {
      const b = Number(updateData.monthlyBudgetUsd);
      if (isNaN(b) || b < 0) {
        return NextResponse.json({ error: "monthlyBudgetUsd must be >= 0" }, { status: 400 });
      }
      updateData.monthlyBudgetUsd = b;
    }

    if (Object.keys(updateData).length === 0) {
      return NextResponse.json({ error: "No valid fields to update" }, { status: 400 });
    }

    // Ensure singleton exists
    await db.tokenConfig.upsert({
      where: { id: "singleton" },
      create: { id: "singleton" },
      update: {},
    });

    const config = await db.tokenConfig.update({
      where: { id: "singleton" },
      data: updateData,
    });

    logger.info(
      { action: "token_config_update", fields: Object.keys(updateData) },
      "Token config updated",
    );

    return NextResponse.json({ config });
  } catch (err) {
    logger.error({ err, action: "token_config_update_error" }, "Failed to update Token config");
    return NextResponse.json({ error: "Failed to update config" }, { status: 500 });
  }
}
