// ─────────────────────────────────────────────────────────────────────────────
// Avatar generation from user initials
//
// Falls back to an inline SVG data-URI when no uploaded avatar exists.
// The SVG renders the user's initials on a coloured square.
// ─────────────────────────────────────────────────────────────────────────────

// ── Helpers ──────────────────────────────────────────────────────────────────

/**
 * Strip characters that could break SVG rendering or introduce XSS from a name.
 *
 * Allows letters, digits, spaces, hyphens, apostrophes and periods. Caps length
 * at 50 characters.
 *
 * @param name - Raw display name.
 * @returns    Sanitised, truncated name.
 */
function sanitizeName(name: string): string {
  return name.replace(/[^a-zA-Z0-9\s\-'.-]/g, "").slice(0, 50)
}

/**
 * Extract up to two uppercase initials from a name.
 *
 * "john doe"      → "JD"
 * "  alice   bob  " → "AB"
 * "ed"            → "E"
 *
 * @param name - Display name (will be sanitised internally).
 * @returns    Uppercase initials, max 2 characters.
 */
export function getInitials(name: string): string {
  return sanitizeName(name)
    .split(/\s+/)
    .filter(Boolean)
    .map((n) => n[0])
    .join("")
    .toUpperCase()
    .slice(0, 2)
}

// ── SVG generation ───────────────────────────────────────────────────────────

/**
 * Build a `data:image/svg+xml` URI containing initials on a coloured background.
 *
 * The text is horizontally centred at 62.5 % of the height with a font size of
 * 37.5 % of the canvas size.
 *
 * @param name - Display name whose initials will be rendered.
 * @param bg   - Hex colour **without** the `#` prefix (default `"1d4ed8"`).
 * @param size - Side length of the square SVG in px (default `128`).
 * @returns    A data-URI string usable as an `<img src="…">`.
 */
export function avatarSvgUrl(name: string, bg = "1d4ed8", size = 128): string {
  const initials = getInitials(name)
  const fontSize = Math.round(size * 0.375)
  const y = Math.round(size * 0.625)
  return `data:image/svg+xml,${encodeURIComponent(
    `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect width="${size}" height="${size}" fill="#${bg}"/><text x="${Math.round(size / 2)}" y="${y}" font-size="${fontSize}" fill="white" text-anchor="middle" font-family="Arial,Helvetica,sans-serif">${initials}</text></svg>`
  )}`
}

// ── Public API ───────────────────────────────────────────────────────────────

/**
 * Return the user's uploaded avatar URL, or generate an initials SVG data-URI.
 *
 * @param name      - Display name (used as fallback source for initials).
 * @param avatarUrl - Existing avatar URL or `null`/`undefined`.
 * @param bg        - Hex background colour for the fallback SVG (default `"1d4ed8"`).
 * @param size      - Side length for the fallback SVG (default `128`).
 * @returns         The avatar URL to use.
 */
export function getAvatarUrl(name: string, avatarUrl: string | null | undefined, bg = "1d4ed8", size = 128): string {
  return avatarUrl || avatarSvgUrl(name, bg, size)
}
