"use client";

import { useEffect, useLayoutEffect, useRef, useState } from "react";

export type GalleryView = {
  key: string;
  label: string;
  src: string;
  caption?: string;
};

// fixedRatio: reserva uma caixa 3:4 e centraliza cada imagem nela, para a página não "pular"
// ao trocar entre fotos de proporções diferentes (obra quadrada, horizontal, ambiente...).
export function ZoomableImage({ views, alt, fixedRatio = false, initialIndex = 0 }: { views: GalleryView[]; alt: string; fixedRatio?: boolean; initialIndex?: number }) {
  const [index, setIndex] = useState(initialIndex);
  const [open, setOpen] = useState(false);

  const current = views[index] ?? views[0];

  // Carrossel: as fotos ficam lado a lado e o dedo (ou o trackpad) desliza entre elas, com encaixe em cada foto.
  // As miniaturas continuam funcionando: ao tocar numa, o carrossel rola até ela.
  const trilho = useRef<HTMLDivElement>(null);
  const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const indexRef = useRef(initialIndex);
  indexRef.current = index;

  useLayoutEffect(() => {
    const el = trilho.current;
    if (el && initialIndex > 0) el.scrollTo({ left: initialIndex * el.clientWidth, behavior: "instant" as ScrollBehavior });
  }, [initialIndex]);

  function irPara(i: number) {
    const el = trilho.current;
    setIndex(i);
    indexRef.current = i;
    if (el) el.scrollTo({ left: i * el.clientWidth, behavior: "smooth" });
  }

  function aoRolar() {
    const el = trilho.current;
    if (!el) return;
    if (timer.current) clearTimeout(timer.current);
    timer.current = setTimeout(() => {
      const i = Math.round(el.scrollLeft / Math.max(1, el.clientWidth));
      if (i !== indexRef.current && views[i]) setIndex(i);
    }, 60);
  }

  // Deslizar também na foto ampliada (tela cheia).
  const toque = useRef<{ x: number; y: number } | null>(null);
  function fimDoToque(e: React.TouchEvent) {
    const t = toque.current;
    toque.current = null;
    if (!t || views.length < 2) return;
    const dx = e.changedTouches[0].clientX - t.x;
    const dy = e.changedTouches[0].clientY - t.y;
    if (Math.abs(dx) > 50 && Math.abs(dx) > Math.abs(dy) * 1.5) {
      setIndex((i) => (dx < 0 ? (i + 1) % views.length : (i - 1 + views.length) % views.length));
    }
  }

  useEffect(() => {
    if (!open) return;
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") setOpen(false);
      if (e.key === "ArrowRight") setIndex((i) => (i + 1) % views.length);
      if (e.key === "ArrowLeft") setIndex((i) => (i - 1 + views.length) % views.length);
    }
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
      const el = trilho.current;
      if (el) el.scrollTo({ left: indexRef.current * el.clientWidth, behavior: "instant" as ScrollBehavior });
    };
  }, [open, views.length]);

  return (
    <div>
      <div
        ref={trilho}
        onScroll={aoRolar}
        className="flex snap-x snap-mandatory overflow-x-auto overscroll-x-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
      >
        {views.map((v, i) => (
          <button
            key={v.key}
            type="button"
            onClick={() => setOpen(true)}
            className={`group relative block w-full min-w-full shrink-0 cursor-zoom-in snap-center snap-always overflow-hidden ${fixedRatio ? "aspect-[3/4] bg-white" : "bg-zinc-100"}`}
            aria-label="Ver obra em tamanho grande"
            tabIndex={i === index ? 0 : -1}
          >
            <img
              src={v.src}
              alt={`${alt}, ${v.label}`}
              loading={i < 2 ? "eager" : "lazy"}
              draggable={false}
              className={fixedRatio ? "block h-full w-full object-contain" : "block h-auto w-full"}
            />
            {v.caption && (
              <span className="pointer-events-none absolute left-3 top-3 rounded-full bg-black/70 px-3 py-1 text-xs text-[#ffffff]">
                {v.caption}
              </span>
            )}
            <span className="pointer-events-none absolute bottom-3 right-3 hidden rounded-full bg-black/60 px-3 py-1 text-xs text-[#ffffff] opacity-0 transition-opacity group-hover:opacity-100 md:block">
              Clique para ampliar
            </span>
          </button>
        ))}
      </div>

      {views.length > 1 && (
        <div className="mt-3 flex items-center gap-3">
          <div className="flex gap-2">
            {views.map((v, i) => (
              <button
                key={v.key}
                type="button"
                onClick={() => irPara(i)}
                aria-label={v.label}
                aria-pressed={i === index}
                className={`h-14 w-14 overflow-hidden rounded border-2 transition-colors ${
                  i === index ? "border-zinc-900" : "border-transparent opacity-60 hover:opacity-100"
                }`}
              >
                <img src={v.src} alt={v.label} className="h-full w-full object-cover" />
              </button>
            ))}
          </div>
          <p className="text-xs text-zinc-500">
            {current.label} · Imagem {index + 1} de {views.length}
          </p>
        </div>
      )}

      {open && (
        <div
          className="fixed inset-0 z-50 flex cursor-zoom-out items-center justify-center bg-black/90 p-4"
          onClick={() => setOpen(false)}
          onTouchStart={(e) => {
            toque.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };
          }}
          onTouchEnd={fimDoToque}
          role="dialog"
          aria-modal="true"
        >
          <button
            type="button"
            onClick={() => setOpen(false)}
            className="absolute right-4 top-4 text-3xl leading-none text-[#ffffffcc] hover:text-[#ffffff]"
            aria-label="Fechar"
          >
            ×
          </button>
          {views.length > 1 && (
            <>
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation();
                  setIndex((i) => (i - 1 + views.length) % views.length);
                }}
                className="absolute left-4 top-1/2 -translate-y-1/2 text-4xl leading-none text-[#ffffffcc] hover:text-[#ffffff]"
                aria-label="Anterior"
              >
                ‹
              </button>
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation();
                  setIndex((i) => (i + 1) % views.length);
                }}
                className="absolute right-4 top-1/2 -translate-y-1/2 text-4xl leading-none text-[#ffffffcc] hover:text-[#ffffff]"
                aria-label="Próxima"
              >
                ›
              </button>
            </>
          )}
          <img
            src={current.src}
            alt={`${alt}, ${current.label}`}
            className="max-h-full max-w-full object-contain"
            onClick={(e) => e.stopPropagation()}
          />
          {current.caption && (
            <span className="pointer-events-none absolute bottom-6 left-1/2 -translate-x-1/2 rounded-full bg-black/70 px-4 py-1.5 text-xs text-[#ffffff]">
              {current.caption}
            </span>
          )}
        </div>
      )}
    </div>
  );
}
