<script lang="ts">
    import { apiBaseURL } from "../config"
    import { currentLanguage, DEFAULT_LANGUAGE } from "../lib/i18n"

    interface Props {
        id: string
        entry?: MedialibEntry | null
        filter?: string | null
        noPlaceholder?: boolean
        caption?: string
        showCaption?: boolean
        minWidth?: number
        widthMultiplier?: number
        lazy?: boolean
        style?: string
    }

    let {
        id,
        entry = null,
        filter = null,
        noPlaceholder = false,
        caption = "",
        showCaption = false,
        minWidth = 0,
        widthMultiplier = 1,
        lazy = false,
        style = "",
    }: Props = $props()

    let imgEl = $state<HTMLImageElement | null>(null)
    let currentFilter = $state<string>("l-webp")
    const effectiveId = $derived(entry?.id || entry?._id || id || "")
    const fileSrc = $derived(resolveFileSrc(entry?.file?.src, entry?.id || entry?._id || effectiveId))

    // Sync explicit filter prop reactively
    $effect(() => {
        if (filter) currentFilter = filter
    })

    function getAutoFilter(imgWidth: number): string {
        const width = minWidth ? Math.max(imgWidth, minWidth) : imgWidth
        const effectiveWidth = width * (widthMultiplier || 1)

        if (effectiveWidth <= 90) return "xs-webp"
        if (effectiveWidth <= 300) return "s-webp"
        if (effectiveWidth <= 600) return "m-webp"
        if (effectiveWidth <= 1200) return "l-webp"
        if (effectiveWidth <= 2000) return "xl-webp"
        return "xxl-webp"
    }

    function isRasterImage(entry: MedialibEntry | null): boolean {
        if (entry?.file?.type?.match(/^image\/(png|jpe?g|webp)/)) return true
        // Fallback: check file extension when MIME type is missing (e.g. public projection)
        if (entry?.file?.src?.match(/\.(jpe?g|png|webp)$/i)) return true
        return false
    }

    function resolveFileSrc(src: string | undefined, entryId: string | undefined): string | null {
        if (!src) return null
        if (/^(https?:)?\/\//.test(src) || src.startsWith("/")) return src
        if (!entryId) return null
        const normalizedApiBase = apiBaseURL.replace(/\/+$/, "")
        return `${normalizedApiBase}/medialib/${entryId}/${src.replace(/^\/+/, "")}`
    }

    // ResizeObserver: only when no explicit filter and raster image
    $effect(() => {
        const el = imgEl
        if (!el || filter || !entry || !isRasterImage(entry)) return
        if (typeof ResizeObserver === "undefined") return

        let maxObservedWidth = 0

        const observer = new ResizeObserver(() => {
            const newWidth = el.clientWidth
            if (newWidth <= maxObservedWidth) return // only scale up
            maxObservedWidth = newWidth
            currentFilter = getAutoFilter(newWidth)
        })
        observer.observe(el)

        return () => observer.disconnect()
    })

    function getSrc(src: string | null, entry: MedialibEntry | null): string {
        if (!src) return "/assets/img/placeholder-image.svg"
        if (!isRasterImage(entry)) return src
        if (filter) return src + `?filter=${filter}`
        return src + `?filter=${currentFilter}`
    }

    function resolveLocalizedText(value: string | LocalizedText | undefined, lang: string): string {
        if (!value) return ""
        if (typeof value === "string") return value

        return value[lang] || value[DEFAULT_LANGUAGE] || Object.values(value).find((entry) => !!entry) || ""
    }
</script>

{#if effectiveId}
    {#if entry && fileSrc}
        {#if showCaption && caption}
            <figure>
                <picture>
                    <img
                        bind:this={imgEl}
                        src={getSrc(fileSrc, entry)}
                        alt={resolveLocalizedText(entry.alt, $currentLanguage)}
                        data-entry-id={id}
                        loading={lazy ? "lazy" : undefined}
                        {style}
                    />
                </picture>
                <figcaption class="mt-2 text-sm text-gray-500 text-center italic">
                    {@html caption}
                </figcaption>
            </figure>
        {:else}
            <picture>
                <img
                    bind:this={imgEl}
                    src={getSrc(fileSrc, entry)}
                    alt={resolveLocalizedText(entry.alt, $currentLanguage)}
                    data-entry-id={id}
                    loading={lazy ? "lazy" : undefined}
                    {style}
                />
            </picture>
        {/if}
    {:else if !noPlaceholder}
        <picture>
            <img src="/assets/img/placeholder-image.svg" alt="not found" data-entry-id={effectiveId} />
        </picture>
    {/if}
{/if}
