<script lang="ts">
  /**
   * TopBanner: Fullwidth-Banner mit Bild (über /cms-images aufgelöst), optionalem Text
   * und Titel/Subtitle der aktuellen Page (Markdown). Bevorzugt `<picture>` mit AVIF/WebP-Sources
   * und srcset, wenn `responsive` geliefert wird; sonst Fallback auf einzelnes `<img>` (legacy).
   */
  import { marked } from "marked";
  import type { FullwidthBannerEntry } from "$lib/cms";

  marked.setOptions({ gfm: true });

  interface ResponsiveBannerImage {
    sources: { type: string; srcset: string }[];
    fallback: string;
    width: number;
    height: number;
    /** Optionaler LQIP (data-URL) als Unschärfe-Placeholder beim Laden. */
    lqip?: string;
  }

  interface Props {
    banner: FullwidthBannerEntry | null;
    /** Einfache (legacy) einzelne URL(s) — wenn `responsive` fehlt. */
    resolvedImages?: string[];
    /** Bevorzugter Pfad: fertig berechneter `<picture>`-Inhalt fürs erste Banner-Bild. */
    responsive?: ResponsiveBannerImage | null;
    /** `sizes`-Attribut fürs srcset (Default: volle Viewport-Breite). */
    sizes?: string;
    /** Focal-Point als CSS-`object-position` (z. B. "69.5% 40.38%"). */
    focalCss?: string | null;
    /** Headline der Page (Markdown). */
    headline?: string;
    /** Subheadline der Page (Markdown). */
    subheadline?: string;
  }

  let {
    banner = null,
    resolvedImages = [],
    responsive = null,
    sizes = "100vw",
    focalCss = null,
    headline,
    subheadline,
  }: Props = $props();

  const imgStyle = $derived(
    focalCss ? `object-position: ${focalCss};` : undefined,
  );

  /**
   * LQIP: Blurhash-Placeholder als `background-image` auf dem Wrapper.
   * Kein Blur-Filter nötig — der aus 32×32 hochskalierte JPEG ist intrinsisch weich.
   * `background-position` folgt dem Focal, damit der Placeholder identisch zum Image croppt.
   */
  const wrapperStyle = $derived.by(() => {
    const parts: string[] = [];
    if (responsive?.lqip) {
      parts.push(`background-image: url("${responsive.lqip}")`);
      parts.push("background-size: cover");
      parts.push(`background-position: ${focalCss ?? "center"}`);
    }
    return parts.length > 0 ? parts.join("; ") : undefined;
  });

  const headlineHtml = $derived(
    headline?.trim() ? (marked.parseInline(headline) as string) : "",
  );
  const subheadlineHtml = $derived(
    subheadline?.trim() ? (marked.parseInline(subheadline) as string) : "",
  );

  const hasResponsive = $derived(
    responsive != null && responsive.fallback.trim().length > 0,
  );
  const hasImage = $derived(
    hasResponsive || (resolvedImages.length > 0 && Boolean(resolvedImages[0]?.trim())),
  );
  const hasText = $derived(banner?.text != null && banner.text !== "");
  const hasPageTitle = $derived((headline != null && headline !== "") || (subheadline != null && subheadline !== ""));
  const showBanner = $derived(hasImage || hasText || hasPageTitle);
  const altText = $derived(banner?.headline ?? headline ?? "");

  let imgEl = $state<HTMLImageElement | null>(null);
  let imgLoaded = $state(false);

  const currentSrc = $derived(responsive?.fallback ?? resolvedImages[0] ?? "");
  $effect(() => {
    // reset on src change, then probe cache
    void currentSrc;
    imgLoaded = false;
    queueMicrotask(() => {
      if (imgEl?.complete && imgEl.naturalWidth > 0) imgLoaded = true;
    });
  });
</script>

{#if showBanner}
  <div class="w-full">
    {#if hasImage}
      <div
        class="w-full overflow-hidden relative flex justify-center items-center shadow-lg bg-zinc-200"
        style={wrapperStyle}
      >
        {#if hasResponsive && responsive}
          {#key responsive.fallback}
            <picture class="block w-full">
              {#each responsive.sources as s (s.type)}
                <source type={s.type} srcset={s.srcset} sizes={sizes} />
              {/each}
              <img
                src={responsive.fallback}
                alt={altText}
                class="w-full object-cover max-h-[400px] lg:max-h-[600px] max-w-[1920px] aspect-square sm:aspect-video lg:aspect-24/9 text-transparent transition-opacity duration-500"
                class:opacity-0={!imgLoaded}
                class:opacity-100={imgLoaded}
                width={responsive.width}
                height={responsive.height}
                style={imgStyle}
                loading="eager"
                fetchpriority="high"
                decoding="async"
                bind:this={imgEl}
                onload={() => (imgLoaded = true)}
              />
            </picture>
          {/key}
        {:else}
          {#key resolvedImages[0]}
            <img
              src={resolvedImages[0]}
              alt={altText}
              class="w-full object-cover max-h-[400px] lg:max-h-[600px] max-w-[1920px] aspect-square sm:aspect-video lg:aspect-24/9 text-transparent transition-opacity duration-500"
              class:opacity-0={!imgLoaded}
              class:opacity-100={imgLoaded}
              width={1920}
              height={600}
              style={imgStyle}
              loading="eager"
              fetchpriority="high"
              onload={() => (imgLoaded = true)}
            />
          {/key}
        {/if}
        {#if hasPageTitle}
          <div class="absolute inset-0 flex items-center justify-start ">
            <div class="container-custom mx-auto px-6 relative">
              {#if headlineHtml}
                <h1 class="bg-red-400/70 inline-block py-1 px-2 -ml-2 backdrop-blur">{@html headlineHtml}</h1>
              {/if}
              <div></div>
              {#if subheadlineHtml}
                <h2 class="bg-white/50 inline-block py-1 px-2 -ml-2 backdrop-blur font-light! text-xl!">{@html subheadlineHtml}</h2>
              {/if}
            </div>
          </div>
        {/if}
      </div>
    {:else if hasPageTitle}
      <div class="border-b border-zinc-200 container mx-auto px-6 py-4">
        {#if headlineHtml}
          <h1 class="text-2xl font-bold text-zinc-900">{@html headlineHtml}</h1>
        {/if}
        {#if subheadlineHtml}
          <h2 class="text-lg text-zinc-600 mt-1">{@html subheadlineHtml}</h2>
        {/if}
      </div>
    {/if}
    {#if hasText}
      <div class="w-full bg-green-700 text-white text-center py-2 px-4">
        <div class="container mx-auto">
          <div class="text-sm font-medium">{banner!.text}</div>
        </div>
      </div>
    {/if}
  </div>
{/if}
