import { SESSION_TTL_SECONDS, type SessionKind } from './session-token';

/** Cookie names (spec: `pr_host`, `pr_admin`). */
export const SESSION_COOKIE: Record<SessionKind, string> = {
  host: 'pr_host',
  admin: 'pr_admin',
};

/** Where each kind signs in. */
export const LOGIN_PATH: Record<SessionKind, string> = {
  host: '/host/login',
  admin: '/admin/login',
};

export interface SessionCookieOptions {
  httpOnly: true;
  sameSite: 'lax';
  secure: boolean;
  path: '/';
  maxAge: number;
}

/**
 * httpOnly (no script access), SameSite=Lax (sent on top-level navigations, not on cross-site
 * POSTs), Secure in production. Max-Age matches the token's own 12 h expiry.
 */
export function sessionCookieOptions(production: boolean = process.env.NODE_ENV === 'production'): SessionCookieOptions {
  return { httpOnly: true, sameSite: 'lax', secure: production, path: '/', maxAge: SESSION_TTL_SECONDS };
}

/**
 * Only same-area relative paths are accepted as a post-login destination, so `?next=` can never
 * send someone to another site (`//evil.example`, `/\evil`, absolute URLs) or across areas.
 */
export function safeNextPath(kind: SessionKind, value: unknown): string {
  const home = kind === 'host' ? '/host' : '/admin';
  if (typeof value !== 'string' || value.length === 0 || value.length > 512) return home;
  if (!value.startsWith(home)) return home;
  if (value.startsWith('//') || value.includes('\\') || /[\u0000-\u001f]/.test(value)) return home;
  const rest = value.slice(home.length);
  if (rest !== '' && !rest.startsWith('/') && !rest.startsWith('?')) return home; // e.g. /hostile
  if (rest.startsWith('/login')) return home;
  return value;
}
