// Lichte, proportionele login-gate voor het kantoor (één gedeeld wachtwoord,
// geen multi-user account-systeem). Zonder APP_WACHTWOORD/APP_AUTH_SECRET is
// de gate uitgeschakeld (dev-gemak) — net als `heeftPersistenteOpslag()` in
// lib/supabase/server.ts faalt dit nooit hard, het schakelt enkel de
// bescherming uit.

import { createHmac, timingSafeEqual } from "crypto";

export const SESSIE_COOKIE_NAAM = "notary_sessie";
const MARKER = "ingelogd";
const MAX_LEEFTIJD_SECONDEN = 60 * 60 * 24 * 30; // 30 dagen

export function heeftAuthGate(): boolean {
  return Boolean(process.env.APP_WACHTWOORD && process.env.APP_AUTH_SECRET);
}

function signeer(payload: string, secret: string): string {
  return createHmac("sha256", secret).update(payload).digest("hex");
}

/** Genereert een HMAC-signed sessietoken (`payload.signature`). */
export function maakSessieCookie(): string {
  const secret = process.env.APP_AUTH_SECRET;
  if (!secret) throw new Error("APP_AUTH_SECRET ontbreekt — kan geen sessiecookie maken");
  const payload = MARKER;
  const signature = signeer(payload, secret);
  return `${payload}.${signature}`;
}

/** Verifieert de HMAC-signature met constant-time compare. */
export function valideerSessieCookie(token: string | undefined): boolean {
  if (!token) return false;
  const secret = process.env.APP_AUTH_SECRET;
  if (!secret) return false;

  const scheidingsindex = token.lastIndexOf(".");
  if (scheidingsindex === -1) return false;

  const payload = token.slice(0, scheidingsindex);
  const signature = token.slice(scheidingsindex + 1);
  if (payload !== MARKER) return false;

  const verwacht = signeer(payload, secret);

  const a = Buffer.from(signature);
  const b = Buffer.from(verwacht);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

/**
 * Optionele Bearer-token-gate voor de publieke MCP-/AI-agent-endpoint
 * (/api/mcp). Zonder MCP_TOKEN staat de gate UIT en blijft de endpoint open
 * (huidig gedrag) — net als heeftAuthGate() faalt dit nooit hard. Is MCP_TOKEN
 * gezet, dan is een header "Authorization: Bearer <token>" vereist. De externe
 * AI-agent (Claude.ai custom connector, Claude Code, …) stuurt dit token mee.
 */
export function heeftMcpTokenGate(): boolean {
  return Boolean(process.env.MCP_TOKEN);
}

/** Verifieert het Bearer-token met constant-time compare; true wanneer de gate uit staat. */
export function valideerMcpBearer(authorizationHeader: string | null | undefined): boolean {
  const verwacht = process.env.MCP_TOKEN;
  if (!verwacht) return true; // gate uit → open
  if (!authorizationHeader) return false;
  const match = /^Bearer\s+(.+)$/i.exec(authorizationHeader.trim());
  if (!match) return false;

  const a = Buffer.from(match[1]);
  const b = Buffer.from(verwacht);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

/** Constant-time vergelijking van het ingevoerde wachtwoord. */
export function valideerWachtwoord(ingevoerd: string): boolean {
  const verwacht = process.env.APP_WACHTWOORD;
  if (!verwacht) return false;

  const a = Buffer.from(ingevoerd);
  const b = Buffer.from(verwacht);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

export const SESSIE_COOKIE_MAX_AGE = MAX_LEEFTIJD_SECONDEN;
