import { NextRequest, NextResponse } from "next/server";
import { getAdminSession, getClientMetadata } from "@/lib/admin/auth";
import { db, verifyPassword } from "@/lib/admin/db";

export const dynamic = "force-dynamic";

/**
 * POST /api/admin/auth/pin/setup
 * Sets or updates the administrator's 4-digit screen lock PIN.
 */
export async function POST(req: NextRequest) {
  try {
    const ctx = await getAdminSession(req);
    if (!ctx) {
      return NextResponse.json(
        { error: "Unauthorized. Please sign in to configure your PIN." },
        { status: 401 }
      );
    }

    const body = await req.json().catch(() => ({}));
    const pin = typeof body.pin === "string" ? body.pin.trim() : "";
    const confirmPin = typeof body.confirmPin === "string" ? body.confirmPin.trim() : "";
    const currentPassword =
      typeof body.currentPassword === "string"
        ? body.currentPassword
        : typeof body.password === "string"
        ? body.password
        : "";

    // If user already had a PIN, require current password for security confirmation
    const user = await db.getUserById(ctx.user.id);
    if (!user) {
      return NextResponse.json({ error: "User account not found." }, { status: 404 });
    }

    // If session is locked, we strictly REQUIRE account password verification
    if (ctx.session.isLocked) {
      if (!currentPassword) {
        return NextResponse.json(
          { error: "Admin session is locked. Administrator account password is required to reset your PIN." },
          { status: 423 }
        );
      }
      const valid = verifyPassword(currentPassword, user.passwordHash, user.passwordSalt);
      if (!valid) {
        return NextResponse.json(
          { error: "Incorrect administrator password." },
          { status: 401 }
        );
      }
    } else if (user.pinHash && currentPassword) {
      const valid = verifyPassword(currentPassword, user.passwordHash, user.passwordSalt);
      if (!valid) {
        return NextResponse.json(
          { error: "Incorrect administrator password." },
          { status: 400 }
        );
      }
    }

    if (!/^\d{4}$/.test(pin)) {
      return NextResponse.json(
        { error: "Screen lock PIN must consist of exactly 4 numeric digits (0-9)." },
        { status: 400 }
      );
    }

    if (pin !== confirmPin) {
      return NextResponse.json(
        { error: "PIN and confirmation PIN do not match." },
        { status: 400 }
      );
    }

    // Disallow trivially weak PINs
    const weakPins = ["0000", "1111", "2222", "3333", "4444", "5555", "6666", "7777", "8888", "9999", "1234", "4321"];
    if (weakPins.includes(pin)) {
      return NextResponse.json(
        { error: "Please select a more secure PIN (avoid sequential or repeated digits like 1234 or 0000)." },
        { status: 400 }
      );
    }

    await db.setUserPin(user.id, pin);

    const { ip } = getClientMetadata(req);
    await db.logSecurityEvent({
      actorId: user.id,
      actorName: user.name,
      actorEmail: user.email,
      actorLevel: user.level,
      targetUserId: user.id,
      targetUserEmail: user.email,
      targetUserName: user.name,
      action: user.pinHash ? "PIN_CHANGED" : "PIN_SETUP",
      details: {
        note: user.pinHash ? "Updated screen lock PIN." : "Established initial 4-digit screen lock PIN.",
      },
      ipAddress: ip,
    });

    if (ctx.session.isLocked) {
      await db.unlockSession(ctx.session.tokenHash);
      await db.logSecurityEvent({
        actorId: user.id,
        actorName: user.name,
        actorEmail: user.email,
        actorLevel: user.level,
        targetUserId: user.id,
        targetUserEmail: user.email,
        targetUserName: user.name,
        action: "SESSION_UNLOCKED",
        details: { method: "PASSWORD_PIN_RESET" },
        ipAddress: ip,
      });
    }

    return NextResponse.json({
      success: true,
      isLocked: false,
      message: "Screen lock PIN saved and session unlocked successfully.",
    });
  } catch (err: any) {
    console.error("[POST /api/admin/auth/pin/setup] Error:", err);
    return NextResponse.json(
      { error: err.message || "Failed to set screen lock PIN." },
      { status: 500 }
    );
  }
}
