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

function generateApiKey(): string {
  const bytes = randomBytes(32);
  return `lh_sk_${bytes.toString("base64url")}`;
}

export async function GET() {
  const session = await auth();

  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const user = await db.user.findUnique({
      where: { id: session.user.id },
      select: { plan: true },
    });
    const plan = (user?.plan ?? "free") as keyof typeof API_KEY_LIMITS;
    const limit = API_KEY_LIMITS[plan] ?? 2;

    const keys = await db.apiKey.findMany({
      where: { userId: session.user.id, revokedAt: null },
      select: {
        id: true,
        name: true,
        prefix: true,
        lastUsed: true,
        expiresAt: true,
        createdAt: true,
      },
      orderBy: { createdAt: "desc" },
    });

    return NextResponse.json({ keys, limit });
  } catch {
    return NextResponse.json(
      { error: "Failed to fetch API keys" },
      { status: 500 },
    );
  }
}

export async function POST(req: NextRequest) {
  const session = await auth();

  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

    if (!name || typeof name !== "string" || name.trim().length === 0) {
      return NextResponse.json(
        { error: "Name is required" },
        { status: 400 },
      );
    }

    if (name.length > 64) {
      return NextResponse.json(
        { error: "Name must be 64 characters or less" },
        { status: 400 },
      );
    }

    // Check key limit based on plan
    const existingCount = await db.apiKey.count({
      where: { userId: session.user.id, revokedAt: null },
    });

    const user = await db.user.findUnique({
      where: { id: session.user.id },
      select: { plan: true },
    });

    const plan = (user?.plan ?? "free") as keyof typeof API_KEY_LIMITS;
    const limit = API_KEY_LIMITS[plan] ?? 2;

    if (existingCount >= limit) {
      return NextResponse.json(
        { error: `API key limit reached (${limit} keys on ${user?.plan ?? "free"} plan)` },
        { status: 403 },
      );
    }

    const key = generateApiKey();
    const prefix = key.substring(0, 12) + "...";

    const apiKey = await db.apiKey.create({
      data: {
        userId: session.user.id,
        name: name.trim(),
        key,
        prefix,
      },
    });

    // Track key_created event for FAE (First Activation Event) instrumentation.
    // FAE = first API call through proxy. Key creation is a prerequisite step.
    // Wrapped in try/catch: UserEvent model requires `prisma migrate dev` — safe to skip if not yet applied.
    try {
      await db.userEvent.create({
        data: {
          userId: session.user.id,
          event: "key_created",
          metadata: JSON.stringify({ keyId: apiKey.id, keyName: name.trim() }),
        },
      });
    } catch (err) {
      logger.error({ err, action: "keys_api" }, "Failed to record key_created event");
    }

    // Return full key only on creation — never again
    return NextResponse.json(
      {
        id: apiKey.id,
        name: apiKey.name,
        key,
        prefix: apiKey.prefix,
        createdAt: apiKey.createdAt,
      },
      { status: 201 },
    );
  } catch {
    return NextResponse.json(
      { error: "Failed to create API key" },
      { status: 500 },
    );
  }
}
