<script lang="ts">
  import { commands } from "$lib/api/bindings";
  import { auth } from "$lib/stores/auth";
  import { get } from "svelte/store";

  interface Props {
    itemId: string;
    imageType?: string;
    tag?: string | null;
    maxWidth?: number;
    maxHeight?: number;
    class?: string;
    alt?: string;
    /**
     * Called once the bitmap is decoded, with its intrinsic pixel size. Lets a
     * layout that sizes boxes from artwork (the mosaic) use the shape the image
     * actually has rather than the one its item type suggests.
     * TRACES: UR-075 | DR-174
     */
    onNaturalSize?: (width: number, height: number) => void;
  }

  let {
    itemId,
    imageType = "Primary",
    tag,
    maxWidth,
    maxHeight,
    class: className = "",
    alt = "",
    onNaturalSize,
  }: Props = $props();

  let imageUrl = $state<string | null>(null);
  let loading = $state(true);
  let error = $state(false);
  let lastLoadKey = "";

  async function loadImage() {
    if (!itemId) {
      loading = false;
      return;
    }

    try {
      loading = true;
      error = false;

      // Get repository handle from auth store
      const authState = get(auth);
      if (!authState.isAuthenticated) {
        throw new Error("Not authenticated");
      }
      const repository = auth.getRepository();
      const repositoryHandle = repository.getHandle();

      // Call Rust to get image as base64 data URL
      const dataUrl = await commands.imageGetUrl(repositoryHandle, {
        itemId,
        imageType,
        maxWidth,
        maxHeight,
        tag,
      });

      // Use data URL directly
      imageUrl = dataUrl;
      error = false;
    } catch (e) {
      error = true;
      imageUrl = null;
    } finally {
      loading = false;
    }
  }

  // Only reload when the image identity changes (not on parent re-renders)
  $effect(() => {
    const loadKey = `${itemId}|${imageType}|${tag || ""}`;
    if (loadKey !== lastLoadKey) {
      lastLoadKey = loadKey;
      imageUrl = null;
      loadImage();
    }
  });
</script>

{#if loading}
  <div class="{className} bg-gray-700 animate-pulse" aria-busy="true" aria-label="Loading image"></div>
{:else if error || !imageUrl}
  <div class="{className} bg-gray-800 flex items-center justify-center">
    <svg class="w-8 h-8 text-gray-600" fill="currentColor" viewBox="0 0 24 24">
      <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
    </svg>
  </div>
{:else}
  <img
    src={imageUrl}
    {alt}
    class={className}
    onload={(e) => {
      const img = e.currentTarget as HTMLImageElement;
      if (img.naturalWidth > 0 && img.naturalHeight > 0) {
        onNaturalSize?.(img.naturalWidth, img.naturalHeight);
      }
    }}
  />
{/if}
