import { createHmac } from 'node:crypto';

const MUTATING = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);

function engineBearerToken(): string | undefined {
  const raw = process.env['SCRIBA_ENGINE_API_KEY']?.trim() || process.env['SCRIBA_API_KEY']?.trim();
  if (!raw) return undefined;

  const first = raw.split(',').map((s) => s.trim()).find(Boolean);
  if (!first) return undefined;

  const sep = first.indexOf(':');
  if (sep > 0) {
    const secret = first.slice(sep + 1).trim();
    return secret || first;
  }
  return first;
}

/** First secret when SCRIBA_WEBHOOK_SECRET is "old,new" comma list (NEXT §6.4 outbound signing uses one active secret). */
function primaryWebhookSecret(): string | undefined {
  const raw = process.env['SCRIBA_WEBHOOK_SECRET']?.trim();
  if (!raw) return undefined;
  const parts = raw.split(',').map((s) => s.trim()).filter(Boolean);
  return parts[parts.length - 1] ?? raw;
}

/**
 * Headers added to scriba-engine requests from `/api/engine/*`.
 * Never rely on browser-provided Authorization for engine auth — use server env only.
 */
export function buildEngineUpstreamHeaders(
  method: string,
  opts: {
    rawBody?: string;
    jsonBody?: Record<string, unknown>;
  } = {},
): Record<string, string> {
  const m = method.toUpperCase();
  const headers: Record<string, string> = {};

  const apiKey = engineBearerToken();
  if (apiKey) {
    headers['Authorization'] = `Bearer ${apiKey}`;
  }

  if (!MUTATING.has(m)) {
    return headers;
  }

  const secret = primaryWebhookSecret();
  let bodyRaw = opts.rawBody;
  if (bodyRaw === undefined && opts.jsonBody !== undefined) {
    bodyRaw = JSON.stringify(opts.jsonBody);
  }

  if (secret && typeof bodyRaw === 'string') {
    const ts = Math.floor(Date.now() / 1000);
    const sig = createHmac('sha256', secret).update(`${ts}.${bodyRaw}`).digest('hex');
    headers['X-Scriba-Timestamp'] = String(ts);
    headers['X-Scriba-Signature'] = `sha256=${sig}`;
  }

  return headers;
}
