import { useEffect, useState } from 'react'
import { cn } from '@/lib/utils'

/** Hash-tinted initial bubble used across every sharing surface
 *  (ShareDialog, NotificationBell, sidebar shared rows). The tint
 *  isn't meaningful — it's just an identity cue so a list of names
 *  feels less anonymous. Using the same hash across components means
 *  a given user's bubble stays the same colour everywhere.
 *
 *  When `imageUrl` is present (Authentik `picture` claim or a Gravatar
 *  URL), an <img> sits on top of the tinted bubble; if the image fails
 *  to load we collapse back to initials, so a broken avatar never
 *  shows up as a white square. */
const PALETTE = [
  'bg-primary/25 text-primary',
  'bg-pick/25 text-pick',
  'bg-blue-500/25 text-blue-300',
  'bg-purple-500/25 text-purple-300',
  'bg-amber-500/25 text-amber-300',
]

export function avatarColor(name: string): string {
  let hash = 0
  for (let i = 0; i < name.length; i++) {
    hash = (hash * 31 + name.charCodeAt(i)) | 0
  }
  return PALETTE[Math.abs(hash) % PALETTE.length]
}

export function Avatar({
  name,
  imageUrl,
  size = 'md',
  className,
}: {
  name: string
  imageUrl?: string | null
  size?: 'xs' | 'sm' | 'md'
  className?: string
}) {
  const initials = name.slice(0, 2).toUpperCase()
  const tint = avatarColor(name)
  const dims =
    size === 'xs'
      ? 'h-4 w-4 text-[8px]'
      : size === 'sm'
        ? 'h-5 w-5 text-[9px]'
        : 'h-8 w-8 text-[11px]'

  // Reset the broken-image flag when the URL changes, e.g. after the
  // user updates their Gravatar or logs in via a different provider.
  const [broken, setBroken] = useState(false)
  useEffect(() => {
    setBroken(false)
  }, [imageUrl])

  const showImage = Boolean(imageUrl) && !broken

  return (
    <span
      className={cn(
        'relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full font-semibold uppercase tracking-wide',
        dims,
        tint,
        className,
      )}
      aria-hidden
    >
      {showImage ? (
        <img
          src={imageUrl!}
          alt=""
          className="h-full w-full object-cover"
          onError={() => setBroken(true)}
          loading="lazy"
          referrerPolicy="no-referrer"
        />
      ) : (
        initials
      )}
    </span>
  )
}
