import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/admin/db";
import {
  createAdminSession,
  setSessionCookie,
  getClientMetadata,
} from "@/lib/admin/auth";
import {
  verify2FATempToken,
  verifyTOTP,
  verifyAndConsumeBackupCode,
} from "@/lib/admin/totp";

export async function POST(req: NextRequest) {
  try {
    const body = await req.json().catch(() => ({}));
    const tempToken = typeof body.tempToken === "string" ? body.tempToken.trim() : "";
    const code = typeof body.code === "string" ? body.code.trim() : "";

    const { ip, userAgent } = getClientMetadata(req);

    if (!tempToken || !code) {
      return NextResponse.json(
        { error: "Authentication challenge token and verification code are required." },
        { status: 400 }
      );
    }

    // Verify signed temp token
    const userId = verify2FATempToken(tempToken);
    if (!userId) {
      return NextResponse.json(
        { error: "2FA challenge session has expired or is invalid. Please log in again." },
        { status: 401 }
      );
    }

    const user = await db.getUserById(userId);
    if (!user || user.status !== "ACTIVE") {
      return NextResponse.json(
        { error: "User account is unavailable or inactive." },
        { status: 403 }
      );
    }

    // Verify 6-digit TOTP code OR backup code
    let valid = false;
    let isBackup = false;

    if (user.twoFactorSecret && /^\d{6}$/.test(code)) {
      valid = verifyTOTP(code, user.twoFactorSecret);
    }

    if (!valid) {
      // Try single-use backup recovery code
      valid = await verifyAndConsumeBackupCode(user, code);
      if (valid) isBackup = true;
    }

    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: "Invalid 2FA code or backup code" },
        ipAddress: ip,
      });

      return NextResponse.json(
        { error: "Invalid verification code or backup code. Please try again." },
        { 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 during 2FA",
          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 }
      );
    }

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

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

    // Handle "Trust this browser for 30 days"
    let trustedDeviceToken: string | null = null;
    if (Boolean(body.trustBrowser)) {
      const crypto = await import("node:crypto");
      trustedDeviceToken = crypto.randomBytes(32).toString("hex");
      await db.createTrustedDevice({
        userId: user.id,
        token: trustedDeviceToken,
        userAgent: userAgent || "",
        ipAddress: ip,
      });
    }

    // 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,
        twoFactorVerified: true,
        method: isBackup ? "BACKUP_CODE" : "TOTP",
        trustedBrowserIssued: Boolean(trustedDeviceToken),
      },
      ipAddress: ip,
    });

    const response = 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,
    });

    if (trustedDeviceToken) {
      response.cookies.set({
        name: "quto_trusted_device",
        value: trustedDeviceToken,
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        sameSite: "lax",
        path: "/",
        maxAge: 30 * 24 * 60 * 60, // 30 days
      });
    }

    return response;
  } catch (error) {
    console.error("[api/admin/auth/2fa/challenge] Error:", error);
    return NextResponse.json(
      { error: "An unexpected error occurred during 2FA verification." },
      { status: 500 }
    );
  }
}
