(() => {
    let lightboxHistoryActive = false;

    const lightbox = document.getElementById("lightbox");
    const stage = lightbox?.querySelector(".lightbox__stage");
    const img = document.getElementById("lightbox-img");
    if (!lightbox || !stage || !img) return;

    let open = false;

    // Transform state (relative to centered position)
    let scale = 1;
    let tx = 0;
    let ty = 0;

    // Base rendered size of the image at scale=1 (in px)
    let baseW = 0;
    let baseH = 0;

    // Dragging
    let lastX = 0;
    let lastY = 0;

    // Touch pinch
    let touchMode = null;
    let pinchStartDist = 0;
    let pinchStartScale = 1;
    let pinchMid = { x: 0, y: 0 };

    const MIN_SCALE = 1;
    const MAX_SCALE = 6;

    const clamp = (n, a, b) => Math.max(a, Math.min(b, n));

    const rect = (el) => el.getBoundingClientRect();

    function measureBaseSize() {
        // IMPORTANT: measure when tx/ty=0 and scale=1 so we get the centered base size.
        const prev = img.style.transform;
        img.style.transform = "translate(0px, 0px) scale(1)";
        const r = rect(img);
        baseW = r.width;
        baseH = r.height;
        img.style.transform = prev;
    }

    function clampPan() {
        const s = rect(stage);

        const scaledW = baseW * scale;
        const scaledH = baseH * scale;

        // When the image is smaller than the stage, keep it centered (no panning).
        const maxX = Math.max(0, (scaledW - s.width) / 2);
        const maxY = Math.max(0, (scaledH - s.height) / 2);

        tx = clamp(tx, -maxX, maxX);
        ty = clamp(ty, -maxY, maxY);
    }

    function applyTransform() {
        clampPan();
        img.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
    }

    function resetView() {
        scale = 1;
        tx = 0;
        ty = 0;
        applyTransform();
    }

    function openLightbox(src, alt) {
        img.onload = null;
        img.src = src;
        img.alt = alt || "";

        lightbox.classList.add("open");
        lightbox.setAttribute("aria-hidden", "false");
        document.body.classList.add("lb-open");
        open = true;

        if (!lightboxHistoryActive) {
            history.pushState({ lightbox: true }, "");
            lightboxHistoryActive = true;
        }

        // Block background scroll/gestures while open (especially iOS)
        document.addEventListener("touchmove", preventTouchScroll, { passive: false });

        img.onload = () => {
            // Wait for layout to settle, then measure and reset.
            requestAnimationFrame(() => {
                measureBaseSize();
                resetView();
            });
        };

        // If cached and instantly available
        if (img.complete) {
            requestAnimationFrame(() => {
                measureBaseSize();
                resetView();
            });
        }
    }

    function closeLightbox(fromPopState = false) {
        lightbox.classList.remove("open");
        lightbox.setAttribute("aria-hidden", "true");
        document.body.classList.remove("lb-open");
        open = false;

        img.classList.remove("dragging");
        touchMode = null;

        document.removeEventListener("touchmove", preventTouchScroll, { passive: false });

        if (lightboxHistoryActive && !fromPopState) {
            history.back();
        }

        lightboxHistoryActive = false;
    }

    function preventTouchScroll(e) {
        if (open) e.preventDefault();
    }

    function zoomAt(clientX, clientY, newScale) {
        const s = rect(stage);

        const cx = clientX - s.left - s.width / 2;
        const cy = clientY - s.top - s.height / 2;

        const prevScale = scale;
        scale = clamp(newScale, MIN_SCALE, MAX_SCALE);

        // Keep point under cursor stable (relative to center-based coordinates)
        tx = cx - ((cx - tx) / prevScale) * scale;
        ty = cy - ((cy - ty) / prevScale) * scale;

        applyTransform();
    }

    // Open on thumbnail click; close on backdrop click
    document.addEventListener("click", (e) => {
        const thumb = e.target.closest("img.zoomable");
        if (thumb) {
            openLightbox(thumb.dataset.full || thumb.src, thumb.alt);
            return;
        }
        if (open && (e.target === lightbox || e.target === stage)) closeLightbox();
    });

    // Prevent clicking the image from closing
    img.addEventListener("click", (e) => {
        if (open) e.stopPropagation();
    });

    // ESC to close
    document.addEventListener("keydown", (e) => {
        if (open && e.key === "Escape") closeLightbox();
    });

    // Wheel / trackpad zoom
    stage.addEventListener("wheel", (e) => {
        if (!open) return;
        e.preventDefault();
        const factor = e.deltaY < 0 ? 1.12 : 1 / 1.12;
        zoomAt(e.clientX, e.clientY, scale * factor);
    }, { passive: false });

    // --- CLICK vs DRAG (Pointer Events) ---
    let pointerId = null;
    let downX = 0, downY = 0;
    let startTx = 0, startTy = 0;

    let moved = false;
    const DRAG_THRESHOLD = 6; // px
    const ZOOM_IN = 2.5;

    function setZoomedClass() {
        img.classList.toggle("is-zoomed", scale > 1);
    }

    img.addEventListener("pointerdown", (e) => {
        if (!open) return;

        pointerId = e.pointerId;
        img.setPointerCapture(pointerId);

        downX = e.clientX;
        downY = e.clientY;
        startTx = tx;
        startTy = ty;
        moved = false;

        // Don’t let the browser start image dragging/scrolling
        e.preventDefault();
    });

    img.addEventListener("pointermove", (e) => {
        if (!open || pointerId !== e.pointerId) return;

        const dx = e.clientX - downX;
        const dy = e.clientY - downY;

        // Decide if this gesture is a pan
        if (!moved && (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD)) {
            moved = true;
            img.classList.add("dragging");
        }

        // If panning, update translate (pan) from the start position
        if (moved && scale > 1) {
            tx = startTx + dx;
            ty = startTy + dy;
            applyTransform();
        }
    });

    img.addEventListener("pointerup", (e) => {
        if (!open || pointerId !== e.pointerId) return;

        img.classList.remove("dragging");
        img.releasePointerCapture(pointerId);
        pointerId = null;

        // If we didn't move enough, treat as a click: toggle zoom
        if (!moved) {
            // Zoom around where they clicked
            const target = (scale === 1) ? ZOOM_IN : 1;
            zoomAt(e.clientX, e.clientY, target);
            setZoomedClass();
        }

        moved = false;
    });

    img.addEventListener("pointercancel", () => {
        img.classList.remove("dragging");
        pointerId = null;
        moved = false;
    });

    // Touch: pan + pinch
    stage.addEventListener("touchstart", (e) => {
        if (!open) return;

        if (e.touches.length === 1) {
            touchMode = "pan";
            lastX = e.touches[0].clientX;
            lastY = e.touches[0].clientY;
        } else if (e.touches.length === 2) {
            touchMode = "pinch";
            const [a, b] = e.touches;
            pinchStartDist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
            pinchStartScale = scale;
            pinchMid = { x: (a.clientX + b.clientX) / 2, y: (a.clientY + b.clientY) / 2 };
        }
    }, { passive: false });

    stage.addEventListener("touchmove", (e) => {
        if (!open) return;
        e.preventDefault();

        if (touchMode === "pan" && e.touches.length === 1) {
            const x = e.touches[0].clientX;
            const y = e.touches[0].clientY;
            tx += x - lastX;
            ty += y - lastY;
            lastX = x;
            lastY = y;
            applyTransform();
        }

        if (touchMode === "pinch" && e.touches.length === 2) {
            const [a, b] = e.touches;
            const dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
            const ratio = dist / pinchStartDist;
            zoomAt(pinchMid.x, pinchMid.y, pinchStartScale * ratio);
        }
    }, { passive: false });

    stage.addEventListener("touchend", (e) => {
        if (!open) return;
        if (e.touches.length === 0) touchMode = null;
        if (e.touches.length === 1) {
            touchMode = "pan";
            lastX = e.touches[0].clientX;
            lastY = e.touches[0].clientY;
        }
    });

    window.addEventListener("popstate", (e) => {
        // If the lightbox is open, Back should close it — not leave the page
        if (open) {
            closeLightbox(true);
        }
    });
})();