import { NextRequest, NextResponse } from "next/server";
import { db, verifyPassword } from "@/lib/admin/db";
import {
  createAdminSession,
  setSessionCookie,
  getClientMetadata,
} from "@/lib/admin/auth";
import { bootstrapMainAdmin } from "@/lib/admin/bootstrap";
import { checkRateLimit, resetRateLimit } from "@/lib/admin/rate-limiter";

export async function POST(req: NextRequest) {
  try {
    const { ip, userAgent } = getClientMetadata(req);
    const clientKey = ip || "unknown-client";

    // Rate limiting: 5 attempts per 15 minutes per IP
    const rateLimit = checkRateLimit(clientKey, 5, 15 * 60 * 1000);
    if (!rateLimit.allowed) {
      return NextResponse.json(
        {
          error: `Too many login attempts. Please try again in ${rateLimit.retryAfterSeconds} seconds.`,
        },
        {
          status: 429,
          headers: {
            "Retry-After": String(rateLimit.retryAfterSeconds || 60),
          },
        }
      );
    }

    // Ensure primary Main Admin is provisioned if first run
    await bootstrapMainAdmin();

    const body = await req.json();
    const email = typeof body.email === "string" ? body.email.trim().toLowerCase() : "";
    const password = typeof body.password === "string" ? body.password : "";

    if (!email || !password) {
      return NextResponse.json(
        { error: "Email and password are required." },
        { status: 400 }
      );
    }

    const user = await db.getUserByEmail(email);

    if (!user) {
      await db.logSecurityEvent({
        actorId: "ANONYMOUS",
        actorName: "Unauthenticated Client",
        actorEmail: email,
        actorLevel: "SYSTEM",
        targetUserId: null,
        targetUserEmail: email,
        targetUserName: null,
        action: "LOGIN_FAILURE",
        details: { reason: "User not found" },
        ipAddress: ip,
      });

      return NextResponse.json(
        { error: "Invalid email or password." },
        { status: 401 }
      );
    }

    // Check account status
    if (user.status !== "ACTIVE") {
      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: "LOGIN_FAILURE",
        details: { reason: `Account is ${user.status}` },
        ipAddress: ip,
      });

      return NextResponse.json(
        { error: `Account is ${user.status.toLowerCase()}. Contact the Main Administrator.` },
        { status: 403 }
      );
    }

    // Verify password
    const valid = verifyPassword(password, user.passwordHash, user.passwordSalt);
    if (!valid) {
      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: "LOGIN_FAILURE",
        details: { reason: "Password mismatch" },
        ipAddress: ip,
      });

      return NextResponse.json(
        { error: "Invalid email or password." },
        { status: 401 }
      );
    }

    // Network Security check (Part 9-17)
    const { getNetworkSecurity } = await import("@/lib/admin/network-security");
    const netSec = await getNetworkSecurity(ip || "127.0.0.1", req);
    if (netSec.isBlocked) {
      const { location } = getClientMetadata(req);
      await db.createAuditLog({
        action: "NETWORK_SECURITY_BLOCKED",
        status: "FAILURE",
        userId: user.id,
        targetType: "SESSION",
        targetId: null,
        details: {
          reason: netSec.blockReason || "Anonymized network connection detected",
          signals: {
            vpn: netSec.isVpn,
            proxy: netSec.isProxy,
            tor: netSec.isTor,
            relay: netSec.isRelay,
          },
          provider: netSec.provider,
          ip: netSec.ip,
          asn: netSec.asn,
        },
        location,
        networkSecurity: netSec,
        ipAddress: ip,
        userAgent,
      });

      return NextResponse.json(
        {
          code: "NETWORK_BLOCKED",
          error:
            "Admin access blocked: For security reasons, Quto AI does not allow administrator access through VPN, proxy, Tor, or anonymized network connections. Please disable your VPN/proxy and sign in again.",
          network: {
            isVpn: netSec.isVpn,
            isProxy: netSec.isProxy,
            isTor: netSec.isTor,
            isRelay: netSec.isRelay,
            reason: netSec.blockReason,
          },
        },
        { status: 403 }
      );
    }

    // Check if user has 2FA enabled
    if (user.twoFactorEnabled) {
      const trustedDeviceCookie = req.cookies.get("quto_trusted_device")?.value;
      let isTrusted = false;
      if (trustedDeviceCookie) {
        isTrusted = await db.verifyTrustedDevice(user.id, trustedDeviceCookie);
      }

      if (!isTrusted) {
        const { create2FATempToken } = await import("@/lib/admin/totp");
        const tempToken = create2FATempToken(user.id);

        return NextResponse.json({
          requires2FA: true,
          tempToken,
          email: user.email,
          name: user.name,
        });
      }
    }

    // Create session & set cookie
    const { location: loginLoc } = getClientMetadata(req);
    const { rawToken } = await createAdminSession(user.id, {
      ip,
      userAgent,
      location: loginLoc,
      networkSecurity: netSec,
    });
    await setSessionCookie(rawToken);

    // Reset rate limiter on successful login
    resetRateLimit(clientKey);

    // Update lastLoginAt
    await db.updateUser(user.id, { lastLoginAt: new Date().toISOString() });

    // Audit log
    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: "LOGIN_SUCCESS",
      details: { role: user.role, level: user.level },
      ipAddress: ip,
    });

    return NextResponse.json({
      ok: true,
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
        level: user.level,
        role: user.role,
        passwordChangeRequired: user.passwordChangeRequired,
      },
      requiresPasswordChange: user.passwordChangeRequired,
    });
  } catch (error) {
    console.error("[api/admin/auth/login] Error:", error);
    return NextResponse.json(
      { error: "An unexpected error occurred during authentication." },
      { status: 500 }
    );
  }
}
