"use server";

import crypto from "crypto";
import { redirect } from "next/navigation";
import { prisma } from "@/lib/prisma";
import { createAdminSession, destroyAdminSession } from "@/lib/auth";
import { verifyPassword } from "@/lib/password";
import { getClientIp } from "@/lib/client-ip";
import { isRateLimited, recordFailedAttempt, clearAttempts } from "@/lib/rate-limit";

/** Timing-safe equality for the legacy shared password — avoids leaking match length via response time. */
function safeEquals(a: string, b: string): boolean {
  const bufA = Buffer.from(a);
  const bufB = Buffer.from(b);
  if (bufA.length !== bufB.length) return false;
  return crypto.timingSafeEqual(bufA, bufB);
}

const WINDOW_MS = 15 * 60 * 1000;
const MAX_ATTEMPTS = 8;
// The per-IP limiter trusts X-Forwarded-For, which an attacker can freely spoof per request to reset
// their own quota — this global counter is a backstop that can't be evaded that way. Threshold is higher
// since it aggregates every real user's mistakes too, not just one attacker's.
const GLOBAL_IDENTIFIER = "admin-login:global";
const GLOBAL_MAX_ATTEMPTS = 30;

export async function loginAdmin(formData: FormData) {
  const ip = await getClientIp();
  const identifier = `admin-login:${ip}`;
  if (
    (await isRateLimited(identifier, WINDOW_MS, MAX_ATTEMPTS)) ||
    (await isRateLimited(GLOBAL_IDENTIFIER, WINDOW_MS, GLOBAL_MAX_ATTEMPTS))
  ) {
    redirect("/iv-manage-84x2/login?error=2");
  }

  const email = String(formData.get("email") ?? "").trim().toLowerCase();
  const password = String(formData.get("password") ?? "");

  if (!email) {
    // Legacy shared-password login — unchanged behavior.
    if (!password || !safeEquals(password, process.env.ADMIN_PASSWORD ?? "")) {
      await recordFailedAttempt(identifier);
      await recordFailedAttempt(GLOBAL_IDENTIFIER);
      redirect("/iv-manage-84x2/login?error=1");
    }
    await clearAttempts(identifier);
    await createAdminSession();
    redirect("/iv-manage-84x2?success=Logged+in+successfully.");
  }

  const user = await prisma.adminUser.findUnique({ where: { email } });
  if (!user || !user.active || !verifyPassword(password, user.passwordHash, user.passwordSalt)) {
    await recordFailedAttempt(identifier);
    await recordFailedAttempt(GLOBAL_IDENTIFIER);
    redirect("/iv-manage-84x2/login?error=1");
  }
  await clearAttempts(identifier);
  await createAdminSession(user!.id);
  redirect("/iv-manage-84x2?success=Logged+in+successfully.");
}

export async function logoutAdmin() {
  await destroyAdminSession();
  redirect("/iv-manage-84x2/login?success=Logged+out.");
}
