/**
 * Deterministischer Builder für die vier System-Footer-URLs einer Marketing-Mail:
 *   - {{BROWSER_URL}}      → öffentliche Browser-View-Variante der Mail
 *   - {{UNSUBSCRIBE_URL}}  → HMAC-signierte Abmelde-URL (one-click)
 *   - {{IMPRINT_URL}}      → Workspace-Impressum (NOT NULL in workspaces-Tabelle)
 *   - {{PRIVACY_URL}}      → Workspace-Datenschutzerklärung (NOT NULL in workspaces-Tabelle)
 *
 * Wird vom Worker (Send-Zeit) und der Preview (Vorschau-Tab) benutzt. Der Browser-View-
 * und Unsubscribe-Endpoint leben in `src/app/api/track/{view,unsubscribe}/route.ts` und
 * akzeptieren genau das Query-Format, das dieser Helper produziert.
 *
 * Security: Unsubscribe-Token ist HMAC-SHA256 über `${campaignId}:${recipientId}` mit
 * MAILFORGE_UNSUB_SECRET (oder Fallback aus BASE_URL — nicht hochsicher, aber besser
 * als Klartext). Verhindert, dass beliebige Empfänger durch URL-Manipulation abgemeldet
 * werden können. Browser-View braucht keinen Token: das HTML enthält keine Geheimnisse
 * (Empfängername ist in Empfänger-Mailbox sowieso bekannt) und unauthorisierter Zugriff
 * auf einen fremden Campaign-Render hat keinen Schaden-Pfad.
 */

import { createHmac } from 'node:crypto';

const FALLBACK_SECRET = 'mailforge-unsub-fallback-please-set-MAILFORGE_UNSUB_SECRET';

function getSecret(): string {
  return process.env.MAILFORGE_UNSUB_SECRET?.trim() || FALLBACK_SECRET;
}

function getBaseUrl(): string {
  return (process.env.MAILFORGE_BASE_URL?.trim() || 'http://localhost:3000').replace(/\/$/, '');
}

/**
 * Erzeugt einen 16-Byte (32-Hex-Char) HMAC-Token. 128 Bit Output reicht für
 * Anti-Tampering — wir wollen keinen Brute-Force-Schutz für unbedeutende Aktionen,
 * sondern verhindern, dass jemand `?r=other-recipient-id` rät.
 */
export function buildUnsubscribeToken(campaignId: string, recipientId: string): string {
  const h = createHmac('sha256', getSecret());
  h.update(`${campaignId}:${recipientId}`);
  return h.digest('hex').slice(0, 32);
}

export function verifyUnsubscribeToken(
  campaignId: string,
  recipientId: string,
  token: string,
): boolean {
  if (!token || token.length !== 32) return false;
  const expected = buildUnsubscribeToken(campaignId, recipientId);
  // Constant-time-Vergleich gegen Timing-Attacks (overkill für unsub, aber kostet nichts)
  if (expected.length !== token.length) return false;
  let diff = 0;
  for (let i = 0; i < expected.length; i++) diff |= expected.charCodeAt(i) ^ token.charCodeAt(i);
  return diff === 0;
}

export interface FooterUrlContext {
  campaignId: string;
  variantId: string | null;
  recipientId: string;
  brandImprintUrl: string;
  brandPrivacyUrl: string;
}

/**
 * Baut das vollständige Tag-Set für die vier Footer-Tags. Wird vom Worker als
 * Teil von SYSTEM_TAGS gemerged.
 */
export function buildFooterUrlTags(ctx: FooterUrlContext): Record<string, string> {
  const base = getBaseUrl();
  const token = buildUnsubscribeToken(ctx.campaignId, ctx.recipientId);

  const viewQuery = new URLSearchParams({
    c: ctx.campaignId,
    r: ctx.recipientId,
  });
  if (ctx.variantId) viewQuery.set('v', ctx.variantId);

  const unsubQuery = new URLSearchParams({
    c: ctx.campaignId,
    r: ctx.recipientId,
    t: token,
  });

  return {
    BROWSER_URL: `${base}/api/track/view?${viewQuery.toString()}`,
    UNSUBSCRIBE_URL: `${base}/api/track/unsubscribe?${unsubQuery.toString()}`,
    IMPRINT_URL: ctx.brandImprintUrl,
    PRIVACY_URL: ctx.brandPrivacyUrl,
  };
}
