"use client";

import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import Image from "next/image";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import { withCDN } from "@/src/lib/utils";

interface ImageLightboxProps {
  /** Already-resolved image URLs (CDN prefix, if any, applied by the caller). */
  images: string[];
  /** Index of the image to open on; `null` keeps the lightbox closed. */
  index: number | null;
  onClose: () => void;
}

/**
 * Full-screen image viewer shared by the gallery sections. Mirrors the Join
 * Free Class carousel's lightbox exactly — same Swiper slider (so the sliding
 * feels identical), same backdrop, arrows, close button and image treatment.
 *
 * Differences are structural only, not visual: it takes resolved URLs and a
 * controlled `index`/`onClose` API, and portals to <body> so it escapes the
 * transformed / clipped ancestors some of these sections sit inside. It does
 * not lock body scroll — matching the reference, and avoiding the scroll jump.
 *
 * Sits at z-[9998], one below the fixed navbar's z-[9999], so the navbar stays
 * visible above the backdrop — matching the inline Join Free Class lightbox,
 * whose lower stacking context lets the navbar show through the same way.
 */
export default function ImageLightbox({ images, index, onClose }: ImageLightboxProps) {
  const isOpen = index !== null && images.length > 0;
  const [mounted, setMounted] = useState(false);
  const swiperRef = useRef<any>(null);

  useEffect(() => setMounted(true), []);

  useEffect(() => {
    if (!isOpen) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
      else if (e.key === "ArrowRight") swiperRef.current?.slideNext();
      else if (e.key === "ArrowLeft") swiperRef.current?.slidePrev();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [isOpen, onClose]);

  if (!mounted || !isOpen) return null;

  return createPortal(
    <div
      className="fixed inset-0 bg-black/90 z-[9998] flex items-center justify-center px-4 pt-24 pb-8"
      onClick={onClose}
    >
      {/* Close */}
      <button
        onClick={onClose}
        className="absolute top-20 right-5 md:top-25 md:right-12 text-white text-2xl md:text-4xl z-50"
      >
        ✕
      </button>

      {/* Same max-width as the image below, so the arrows anchored to this
          container's edges sit right beside it instead of far out. */}
      <div className="relative w-full max-w-4xl" onClick={(e) => e.stopPropagation()}>
        {/* Hidden for a single image (e.g. a hero banner). */}
        {images.length > 1 && (
          <>
            {/* Previous */}
            <button
              onClick={(e) => {
                e.stopPropagation();
                swiperRef.current?.slidePrev();
              }}
              className="absolute left-1 md:-left-16 top-1/2 -translate-y-1/2 z-50"
            >
              <Image
                src={withCDN("/arrow-left.svg")}
                alt="Prev"
                width={28}
                height={28}
                // brightness-0 invert forces the artwork to pure white on the
                // dark backdrop, whatever fill the source SVG ships with.
                className="cursor-pointer w-[20px] h-[20px] md:w-[40px] md:h-[40px] brightness-0 invert"
              />
            </button>

            {/* Next */}
            <button
              onClick={(e) => {
                e.stopPropagation();
                swiperRef.current?.slideNext();
              }}
              className="absolute right-1 md:-right-16 top-1/2 -translate-y-1/2 z-50 transition rotate-180"
            >
              <Image
                src={withCDN("/arrow-left.svg")}
                alt="Next"
                width={28}
                height={28}
                className="w-[20px] h-[20px] md:w-[40px] md:h-[40px] brightness-0 invert"
              />
            </button>
          </>
        )}

        <Swiper
          initialSlide={index ?? 0}
          onSwiper={(swiper) => (swiperRef.current = swiper)}
          slidesPerView={1}
          spaceBetween={20}
          loop
        >
          {images.map((src, i) => (
            <SwiperSlide key={i}>
              <div className="flex justify-center items-center h-[calc(100vh-8rem)]">
                {/* eslint-disable-next-line @next/next/no-img-element */}
                {/* w/h-full + object-contain scales every image — up or down —
                    to the same box, so a low-res source no longer renders
                    smaller than a high-res one. */}
                {/* max-w-4xl keeps the image ~896px wide, which leaves roughly
                    130px between it and the arrows pinned to the max-w-6xl
                    container — matching the Join Free Class lightbox. */}
                <img
                  src={src}
                  alt={`Image ${i + 1}`}
                  className="w-full h-full max-w-4xl object-contain rounded-xl"
                />
              </div>
            </SwiperSlide>
          ))}
        </Swiper>
      </div>
    </div>,
    document.body,
  );
}
