import { bytesToHex } from '@/lib/encoding';
import { captureCaught } from '@/lib/observability';

/**
 * Gravatar integration — SHA256 email hash + avatar URL builder + existence probe.
 *
 * Gravatar's current standard is the SHA256 hex digest of the lowercased, trimmed
 * email (MD5 is deprecated). All helpers are Worker-safe (Web Crypto, fetch).
 */

/** SHA256 hex hash of a normalized email, per gravatar.com spec. */
export async function gravatarHash(email: string): Promise<string> {
  const normalized = email.trim().toLowerCase();
  const bytes = new TextEncoder().encode(normalized);
  const digest = await crypto.subtle.digest('SHA-256', bytes);
  return bytesToHex(digest);
}

/**
 * Build a gravatar avatar URL.
 * @param hash sha256 hex from {@link gravatarHash}
 * @param size pixel size (`s` param)
 * @param fallback `d` param — `'404'` for the existence probe, `'mp'` (mystery person)
 *   for graceful render fallback so a transient miss degrades to a default image.
 */
export function gravatarUrl(hash: string, size: number, fallback: '404' | 'mp' = 'mp'): string {
  return `https://www.gravatar.com/avatar/${hash}?s=${size}&d=${fallback}`;
}

/**
 * Server-side existence probe. Fails closed (available:false) on any network error
 * or timeout. Never expose the email to the client — return only the hash + boolean.
 */
export async function probeGravatar(
  email: string,
  timeoutMs = 3000,
): Promise<{ available: boolean; hash: string }> {
  const hash = await gravatarHash(email);
  try {
    const ctrl = new AbortController();
    const timer = setTimeout(() => ctrl.abort(), timeoutMs);
    const res = await fetch(gravatarUrl(hash, 80, '404'), {
      method: 'GET',
      signal: ctrl.signal,
    });
    clearTimeout(timer);
    return { available: res.status === 200, hash };
  } catch (err) {
    captureCaught(err, {
      scope: 'lib.avatar.gravatar.probeGravatar',
      severity: 'warning',
    });
    return { available: false, hash };
  }
}
