import { createHmac, timingSafeEqual } from "node:crypto";

const SESSION_DURATION_SECONDS = 30 * 24 * 60 * 60;

function sessionSecret() {
  const secret = (process.env.PORTAL_SESSION_SECRET || process.env.PORTAL_API_SECRET || "").trim();
  if (!secret) throw new Error("Configuration serveur manquante : PORTAL_SESSION_SECRET");
  return secret;
}

function signature(token: string, expiresAt: number) {
  return createHmac("sha256", sessionSecret())
    .update(`${token}.${expiresAt}`)
    .digest("base64url");
}

export function clientSessionCookieName(token: string) {
  return `enrgetic_session_${createHmac("sha256", sessionSecret()).update(token).digest("hex").slice(0, 16)}`;
}

export function createClientSession(token: string) {
  const expiresAt = Math.floor(Date.now() / 1000) + SESSION_DURATION_SECONDS;
  return {
    name: clientSessionCookieName(token),
    value: `${expiresAt}.${signature(token, expiresAt)}`,
    options: {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "lax" as const,
      path: "/",
      maxAge: SESSION_DURATION_SECONDS,
    },
  };
}

export function hasValidClientSession(request: Request, token: string) {
  const name = clientSessionCookieName(token);
  const rawCookie = request.headers.get("cookie") || "";
  const encodedValue = rawCookie
    .split(";")
    .map((part) => part.trim())
    .find((part) => part.startsWith(`${name}=`))
    ?.slice(name.length + 1);

  if (!encodedValue) return false;
  let value = encodedValue;
  try { value = decodeURIComponent(encodedValue); } catch { return false; }
  const [rawExpiry, suppliedSignature, extra] = value.split(".");
  if (!rawExpiry || !suppliedSignature || extra) return false;

  const expiresAt = Number(rawExpiry);
  if (!Number.isInteger(expiresAt) || expiresAt <= Math.floor(Date.now() / 1000)) return false;

  const expected = Buffer.from(signature(token, expiresAt));
  const supplied = Buffer.from(suppliedSignature);
  return expected.length === supplied.length && timingSafeEqual(expected, supplied);
}

export function verificationRequiredResponse() {
  return {
    ok: false,
    verificationRequired: true,
    error: "Vérification requise.",
  };
}
