/**
 * IP fingerprint guardrail + HMAC IP hashing.
 *
 * Replaces the predictable SHA-256 hash in touch.ts (Wave 2 security debt).
 * Uses HMAC-SHA-256 keyed by PII_KEY (the existing pgcrypto secret used for
 * phone/email encryption) so the hash cannot be reverse-engineered without
 * the key, even if the attacker knows the date and IP.
 *
 * The HMAC input mixes the date-string so a hash leaked from one day cannot
 * be replayed against future traffic.
 *
 * Output shape: 8-byte (16 hex char) prefix — identical to the previous
 * SHA-256 output, so no schema or storage changes are required.
 *
 * Security property improvement over plain SHA-256:
 *   - SHA-256(date:ip) → anyone with the date+ip can reproduce the hash.
 *   - HMAC-SHA-256(PII_KEY, date:ip) → requires the secret key; attacker
 *     knowing date+ip still cannot reproduce the hash without PII_KEY.
 */

import { bytesToHex } from './bytes-to-hex.js'
import type { GuardResult } from './brand-keyword.js'

/**
 * Compute a daily-keyed HMAC of the visitor's IP address.
 *
 * PII_KEY is the existing pgcrypto encryption secret — reused here so we
 * don't need a new CF secret binding.
 *
 * @param ip        - Visitor IP address (from cf-connecting-ip header).
 * @param dateStr   - ISO date string "YYYY-MM-DD" (UTC today).
 * @param secretKey - Host-injected PII_KEY (HMAC-SHA-256 secret).
 * @returns 16-char lowercase hex string (8-byte HMAC prefix).
 */
export async function hashIp(ip: string, dateStr: string, secretKey: string): Promise<string> {
  const keyBytes = new TextEncoder().encode(secretKey)
  const cryptoKey = await crypto.subtle.importKey(
    'raw',
    keyBytes,
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['sign'],
  )
  // Domain-tag prevents cross-domain key reuse: even with PII_KEY, an attacker
  // cannot replay a pgcrypto-domain hash here, nor vice versa.
  const sig = await crypto.subtle.sign(
    'HMAC',
    cryptoKey,
    new TextEncoder().encode(`referrals/ip-hash/v1:${dateStr}:${ip}`),
  )
  return bytesToHex(new Uint8Array(sig).slice(0, 8))
}

/**
 * Evaluate IP fingerprint.
 *
 * Currently a pass-through that returns the HMAC hash for use by callers.
 * Future: detect shared-IP abuse (many distinct link IDs from same IP hash).
 *
 * @param ipHash  - Already-computed HMAC IP hash.
 */
export function evaluateFingerprint(ipHash: string): GuardResult {
  // Hash present and well-formed (16 hex chars) → pass.
  if (ipHash && /^[0-9a-f]{16}$/.test(ipHash)) {
    return { isSuspicious: false, codes: [], setCookie: true }
  }

  // Missing or malformed hash (unexpected — log but don't block).
  return { isSuspicious: false, codes: [], setCookie: true }
}
