import "server-only";

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

const ADMIN_SESSION_COOKIE = "optrl_admin_session";
const ADMIN_SESSION_TTL_SECONDS = 60 * 60 * 12; // 12h

function safeEqual(a: string, b: string): boolean {
  const ab = Buffer.from(String(a));
  const bb = Buffer.from(String(b));
  if (ab.length !== bb.length) return false;
  return timingSafeEqual(ab, bb);
}

function getSessionSecret(): string {
  const fromEnv = String(process.env.ADMIN_SESSION_SECRET || "").trim();
  if (fromEnv) return fromEnv;
  // Fallback keeps the app operational in local dev if env is missing.
  return "optrl-admin-session-dev-secret";
}

function readCookie(req: Request, name: string): string | null {
  const raw = req.headers.get("cookie") || "";
  if (!raw) return null;
  const parts = raw.split(";");
  for (const p of parts) {
    const [k, ...rest] = p.trim().split("=");
    if (!k || k !== name) continue;
    return decodeURIComponent(rest.join("=") || "");
  }
  return null;
}

function sign(value: string): string {
  return createHmac("sha256", getSessionSecret()).update(value).digest("hex");
}

function parseAndVerifySession(value: string): { id: string; exp: number } | null {
  const [payloadB64, sig] = String(value || "").split(".");
  if (!payloadB64 || !sig) return null;
  const expectedSig = sign(payloadB64);
  if (!safeEqual(sig, expectedSig)) return null;

  try {
    const json = Buffer.from(payloadB64, "base64url").toString("utf8");
    const parsed = JSON.parse(json) as { id?: string; exp?: number };
    const id = String(parsed?.id || "");
    const exp = Number(parsed?.exp || 0);
    if (!id || !Number.isFinite(exp)) return null;
    if (Date.now() >= exp) return null;
    return { id, exp };
  } catch {
    return null;
  }
}

export function createAdminSessionValue(id: string): string {
  const payload = {
    id: String(id || "").trim(),
    exp: Date.now() + ADMIN_SESSION_TTL_SECONDS * 1000,
  };
  const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
  return `${payloadB64}.${sign(payloadB64)}`;
}

export function getAdminSessionCookieName(): string {
  return ADMIN_SESSION_COOKIE;
}

export function getAdminSessionCookieOptions(maxAgeSeconds = ADMIN_SESSION_TTL_SECONDS) {
  return {
    httpOnly: true,
    sameSite: "lax" as const,
    secure: process.env.NODE_ENV === "production",
    path: "/",
    maxAge: Math.max(0, Math.floor(maxAgeSeconds)),
  };
}

export function getAdminSession(req: Request): { id: string; exp: number } | null {
  const value = readCookie(req, ADMIN_SESSION_COOKIE);
  if (!value) return null;
  return parseAndVerifySession(value);
}

export function isAdminAuthorized(req: Request): boolean {
  return Boolean(getAdminSession(req));
}
