import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import crypto from "node:crypto";
import { verifyToken } from "@/lib/auth/jwt";
import { hashPassword } from "@/lib/auth/password";
import { validateUsername } from "@/lib/auth/validation";
import { findByUsername } from "@/lib/db/repos/usersRepo";
import { createApiKey } from "@/lib/db/repos/apiKeysRepo";
import { createDefaults } from "@/lib/db/repos/rateLimitRepo";
import { getPackageById, assignPackage } from "@/lib/db/repos/packagesRepo";
import { getConsistentMachineId } from "@/shared/utils/machineId";

export const dynamic = "force-dynamic";

async function requireAdmin() {
  const cookieStore = await cookies();
  const token = cookieStore.get("auth_token")?.value;
  if (!token) return null;
  const payload = await verifyToken(token);
  if (!payload || payload.role !== "admin") return null;
  return payload;
}

function generatePassword(length = 16) {
  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
  const bytes = crypto.randomBytes(length);
  let result = "";
  for (let i = 0; i < length; i++) {
    result += chars[bytes[i] % chars.length];
  }
  return result;
}

// POST /api/users/create-with-key — Admin: create user + API key atomically
export async function POST(request) {
  try {
    const admin = await requireAdmin();
    if (!admin) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    const body = await request.json();
    const {
      username,
      password,
      packageId,
      rtkEnabled = false,
      cavemanEnabled = false,
      cavemanLevel = null,
    } = body || {};

    // Validate username
    const userCheck = validateUsername(username);
    if (!userCheck.valid) {
      return NextResponse.json({ error: userCheck.error }, { status: 400 });
    }

    // Check uniqueness
    const existing = await findByUsername(userCheck.value);
    if (existing) {
      return NextResponse.json({ error: "Username already taken" }, { status: 409 });
    }

    // Auto-generate password if not provided
    let plainPassword = password || null;
    if (!plainPassword) {
      plainPassword = generatePassword(16);
    }

    // Validate package if provided
    let pkg = null;
    if (packageId) {
      pkg = await getPackageById(packageId);
      if (!pkg) {
        return NextResponse.json({ error: "Package not found" }, { status: 400 });
      }
    }

    // Hash password
    const passwordHash = hashPassword(plainPassword);

    // Get machine ID
    const machineId = await getConsistentMachineId();
    
    // Generate user ID
    const userId = crypto.randomUUID();
    const now = new Date().toISOString();

    // We'll use direct SQL for user creation to ensure it works
    const { getAdapter } = await import("@/lib/db/driver.js");
    const db = await getAdapter();

    // Create user directly with SQL
    await db.run(
      `INSERT INTO users(id, username, password_hash, role, is_active, is_approved, created_at) VALUES(?, ?, ?, 'user', 1, 1, ?)`,
      [userId, userCheck.value, passwordHash, now]
    );

    const user = {
      id: userId,
      username: userCheck.value,
      role: "user",
      is_active: true,
      is_approved: true,
      created_at: now,
    };

    // Create API key with per-key RTK/Caveman settings
    const apiKey = await createApiKey(
      `${userCheck.value}-default`,
      userId,
      machineId,
      "Auto-generated on account creation",
      { rtkEnabled, cavemanEnabled, cavemanLevel }
    );

    // Create rate limits (from package if provided, else defaults)
    await createDefaults(userId, packageId || null);

    // Assign package if provided
    let userPackage = null;
    if (packageId && pkg) {
      userPackage = await assignPackage(userId, packageId);
    }

    return NextResponse.json({
      user,
      apiKey: {
        id: apiKey.id,
        key: apiKey.key,
        name: apiKey.name,
        machineId: apiKey.machineId,
        userId: apiKey.userId,
        comment: apiKey.comment,
        rtkEnabled: apiKey.rtkEnabled,
        cavemanEnabled: apiKey.cavemanEnabled,
        cavemanLevel: apiKey.cavemanLevel,
      },
      plainPassword,
    }, { status: 201 });
  } catch (error) {
    console.error("[create-with-key] error:", error);
    return NextResponse.json({ error: "Failed to create user with key: " + error.message }, { status: 500 });
  }
}
