import "server-only";
import { createHmac, scryptSync, timingSafeEqual } from "node:crypto";
import { cookies } from "next/headers";

const COOKIE_NAME = "nbe_admin";
const SESSION_SECONDS = 60 * 60 * 8;

function signature(expires: string) {
  const secret = process.env.ADMIN_SESSION_SECRET;
  const username = process.env.ADMIN_USERNAME;
  if (!secret || !username) return "";
  return createHmac("sha256", secret).update(`${username}:${expires}`).digest("hex");
}

export function localAdminConfigured() {
  return Boolean(process.env.ADMIN_USERNAME && process.env.ADMIN_PASSWORD_HASH && process.env.ADMIN_SESSION_SECRET);
}

export function verifyLocalAdmin(username: string, password: string) {
  const stored = process.env.ADMIN_PASSWORD_HASH;
  if (!stored || username !== process.env.ADMIN_USERNAME) return false;
  const [salt, expectedHex] = stored.split(":");
  if (!salt || !expectedHex) return false;
  const actual = scryptSync(password, salt, 64);
  const expected = Buffer.from(expectedHex, "hex");
  return actual.length === expected.length && timingSafeEqual(actual, expected);
}

export async function createLocalAdminSession() {
  const expires = String(Math.floor(Date.now() / 1000) + SESSION_SECONDS);
  (await cookies()).set(COOKIE_NAME, `${expires}.${signature(expires)}`, {
    httpOnly: true,
    sameSite: "strict",
    secure: process.env.NEXT_PUBLIC_SITE_URL?.startsWith("https://") ?? false,
    path: "/",
    maxAge: SESSION_SECONDS,
  });
}

export async function isLocalAdmin() {
  if (!localAdminConfigured()) return false;
  const value = (await cookies()).get(COOKIE_NAME)?.value;
  if (!value) return false;
  const [expires, supplied] = value.split(".");
  if (!expires || !supplied || Number(expires) <= Date.now() / 1000) return false;
  const expected = signature(expires);
  const a = Buffer.from(supplied); const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

export async function clearLocalAdminSession() {
  (await cookies()).delete(COOKIE_NAME);
}
