<script lang="ts">
  import cx from "classnames"
  import {removeUndefined} from "@welshman/lib"
  import {deriveProfile, deriveProfileDisplay} from "@welshman/app"
  import {getColor, getBlobVariant} from "@app/theme"
  import ImageIcon from "@lib/components/ImageIcon.svelte"

  type Props = {
    pubkey?: string
    class?: string
    size?: number
    url?: string
    shape?: "blob" | "circle"
    style?: string
  }

  const {pubkey, url, size = 7, shape = "blob", style = "", ...props}: Props = $props()

  const profile = deriveProfile(pubkey, removeUndefined([url]))
  const display = deriveProfileDisplay(pubkey)

  // Organic, hand-drawn-feeling mask. The variant is stable per pubkey so a
  // person's silhouette never changes; `shape="circle"` opts back into a disc.
  const shapeClass =
    shape === "circle"
      ? "rounded-full"
      : ["avatar-blob", "avatar-blob-2", "avatar-blob-3"][getBlobVariant(pubkey) - 1]

  const color = getColor(pubkey)
  const px = $derived(size * 4)
  const initial = $derived([...($display || "")].find(c => c.trim()) || "?")
</script>

{#if $profile?.picture}
  <ImageIcon {size} alt="" {style} class={cx(props.class, shapeClass)} src={$profile.picture} />
{:else}
  <!-- Fallback: a subtle gradient derived from the pubkey + the person's initial. -->
  <div
    class={cx(
      props.class,
      shapeClass,
      "font-display flex shrink-0 items-center justify-center font-bold text-white uppercase select-none",
    )}
    style="width:{px}px;height:{px}px;font-size:{px *
      0.45}px;background-image:linear-gradient(135deg,{color},color-mix(in oklab,{color},#000 28%));{style}">
    {initial}
  </div>
{/if}
