/* LightboxFoto → window. Visor de imagen a pantalla completa con
   zoom (pinch + wheel + doble tap) y pan cuando hay zoom. Header
   casi negro con × para cerrar; footer reservado para acciones
   futuras (compartir, me gusta, etc.).

   Props:
     - src      string URL de la imagen.
     - alt      string texto alternativo (opcional).
     - onClose  () => void  se llama al cerrar el visor.

   Es un portal al body con zIndex 120. No controla scroll del body —
   el overflow:hidden del html durante el visor se maneja acá.
*/
(function () {
  const { useState, useEffect, useRef, useCallback } = React;

  const MIN_SCALE = 1;
  const MAX_SCALE = 4;
  const DOUBLE_TAP_SCALE = 2.4;

  function LightboxFoto({ src, alt, onClose }) {
    const [scale, setScale] = useState(1);
    const [tx, setTx] = useState(0);
    const [ty, setTy] = useState(0);

    // Refs internos — evitamos poner todo en state para no re-renderizar
    // en cada movimiento.
    const interRef = useRef({
      pinchDistInicial: 0,
      escalaInicial: 1,
      txInicial: 0,
      tyInicial: 0,
      pointerInicial: null, // { x, y } para pan
      ultimoTap: 0,
    });

    const reset = useCallback(() => {
      setScale(1); setTx(0); setTy(0);
    }, []);

    // Bloquea scroll de body durante el visor.
    useEffect(() => {
      const prevHtml = document.documentElement.style.overflow;
      const prevBody = document.body.style.overflow;
      document.documentElement.style.overflow = "hidden";
      document.body.style.overflow = "hidden";
      return () => {
        document.documentElement.style.overflow = prevHtml;
        document.body.style.overflow = prevBody;
      };
    }, []);

    // ESC cierra.
    useEffect(() => {
      const onKey = (e) => { if (e.key === "Escape") onClose && onClose(); };
      document.addEventListener("keydown", onKey);
      return () => document.removeEventListener("keydown", onKey);
    }, [onClose]);

    // --- Zoom/pan ---

    const limitarTranslacion = (s, newTx, newTy, el) => {
      // Permitimos mover solo dentro de los límites de la imagen
      // ampliada. Si el visor no ha medido aún, devolvemos tal cual.
      if (!el) return { x: newTx, y: newTy };
      const rect = el.getBoundingClientRect();
      // rect ya refleja la escala actual del transform; usamos el
      // contenedor padre como referencia de viewport.
      const vw = window.innerWidth;
      const vh = window.innerHeight;
      const maxX = Math.max(0, (rect.width - vw) / 2);
      const maxY = Math.max(0, (rect.height - vh) / 2);
      return {
        x: Math.min(maxX, Math.max(-maxX, newTx)),
        y: Math.min(maxY, Math.max(-maxY, newTy)),
      };
    };

    const imgRef = useRef(null);

    const onTouchStart = (e) => {
      const ts = e.touches;
      if (ts.length === 2) {
        const dx = ts[0].clientX - ts[1].clientX;
        const dy = ts[0].clientY - ts[1].clientY;
        interRef.current.pinchDistInicial = Math.hypot(dx, dy);
        interRef.current.escalaInicial = scale;
        interRef.current.txInicial = tx;
        interRef.current.tyInicial = ty;
      } else if (ts.length === 1) {
        // Solo un dedo: preparar pan (si estamos con zoom) o posible
        // doble tap para zoom rápido.
        const ahora = Date.now();
        const ult = interRef.current.ultimoTap;
        if (ahora - ult < 280) {
          // doble tap: toggle zoom.
          if (scale > 1.05) {
            reset();
          } else {
            setScale(DOUBLE_TAP_SCALE);
            // Centrar zoom en el punto tocado (relativo al viewport).
            const cx = ts[0].clientX - window.innerWidth / 2;
            const cy = ts[0].clientY - window.innerHeight / 2;
            setTx(-cx * (DOUBLE_TAP_SCALE - 1));
            setTy(-cy * (DOUBLE_TAP_SCALE - 1));
          }
          interRef.current.ultimoTap = 0;
        } else {
          interRef.current.ultimoTap = ahora;
          interRef.current.pointerInicial = { x: ts[0].clientX, y: ts[0].clientY };
          interRef.current.txInicial = tx;
          interRef.current.tyInicial = ty;
        }
      }
    };

    const onTouchMove = (e) => {
      const ts = e.touches;
      if (ts.length === 2 && interRef.current.pinchDistInicial > 0) {
        e.preventDefault();
        const dx = ts[0].clientX - ts[1].clientX;
        const dy = ts[0].clientY - ts[1].clientY;
        const dist = Math.hypot(dx, dy);
        const ratio = dist / interRef.current.pinchDistInicial;
        const nueva = Math.min(MAX_SCALE, Math.max(MIN_SCALE,
          interRef.current.escalaInicial * ratio));
        setScale(nueva);
        if (nueva <= MIN_SCALE + 0.02) { setTx(0); setTy(0); }
      } else if (ts.length === 1 && scale > 1.02 && interRef.current.pointerInicial) {
        e.preventDefault();
        const dx = ts[0].clientX - interRef.current.pointerInicial.x;
        const dy = ts[0].clientY - interRef.current.pointerInicial.y;
        const lim = limitarTranslacion(
          scale,
          interRef.current.txInicial + dx,
          interRef.current.tyInicial + dy,
          imgRef.current
        );
        setTx(lim.x); setTy(lim.y);
      }
    };

    const onTouchEnd = (e) => {
      if (e.touches.length === 0) {
        interRef.current.pinchDistInicial = 0;
        interRef.current.pointerInicial = null;
      }
    };

    const onWheel = (e) => {
      // En desktop: rueda = zoom. Evita scroll del body.
      e.preventDefault();
      const delta = -e.deltaY;
      const factor = delta > 0 ? 1.1 : 0.9;
      const nueva = Math.min(MAX_SCALE, Math.max(MIN_SCALE, scale * factor));
      setScale(nueva);
      if (nueva <= MIN_SCALE + 0.02) { setTx(0); setTy(0); }
    };

    const onDoubleClick = (e) => {
      if (scale > 1.05) {
        reset();
      } else {
        setScale(DOUBLE_TAP_SCALE);
        const cx = e.clientX - window.innerWidth / 2;
        const cy = e.clientY - window.innerHeight / 2;
        setTx(-cx * (DOUBLE_TAP_SCALE - 1));
        setTy(-cy * (DOUBLE_TAP_SCALE - 1));
      }
    };

    if (typeof document === "undefined" || !src) return null;

    const BG = "#0A0A0A";
    const BAR_BG = "#111111";
    const BAR_COLOR = "#F0F0F0";

    const content = (
      <div
        style={{
          position: "fixed", inset: 0,
          background: BG,
          zIndex: 120,
          display: "flex", flexDirection: "column",
          animation: "lbFade 160ms ease-out",
        }}
        role="dialog"
        aria-modal="true"
        aria-label="Visor de imagen"
      >
        {/* Header */}
        <div
          style={{
            flexShrink: 0,
            height: "calc(56px + env(safe-area-inset-top, 0px))",
            paddingTop: "env(safe-area-inset-top, 0px)",
            background: BAR_BG,
            color: BAR_COLOR,
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            padding: "env(safe-area-inset-top, 0px) 8px 0 16px",
          }}
        >
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            {scale > 1.05 && (
              <button
                type="button"
                onClick={reset}
                style={{
                  background: "transparent",
                  border: "1px solid rgba(255,255,255,0.2)",
                  color: BAR_COLOR,
                  borderRadius: 999,
                  padding: "6px 12px",
                  fontSize: 12, fontWeight: 800,
                  letterSpacing: 0.3,
                  cursor: "pointer",
                  fontFamily: "inherit",
                }}
              >
                Reset
              </button>
            )}
          </div>
          <button
            type="button"
            onClick={onClose}
            aria-label="Cerrar"
            style={{
              width: 40, height: 40,
              borderRadius: 999,
              background: "transparent",
              border: "none",
              color: BAR_COLOR,
              fontSize: 24,
              cursor: "pointer",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              fontFamily: "inherit",
            }}
          >
            ×
          </button>
        </div>

        {/* Viewport con la imagen */}
        <div
          style={{
            flex: 1,
            position: "relative",
            overflow: "hidden",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            touchAction: "none",
          }}
          onTouchStart={onTouchStart}
          onTouchMove={onTouchMove}
          onTouchEnd={onTouchEnd}
          onTouchCancel={onTouchEnd}
          onWheel={onWheel}
          onDoubleClick={onDoubleClick}
        >
          <img
            ref={imgRef}
            src={src}
            alt={alt || ""}
            draggable="false"
            referrerPolicy="no-referrer"
            style={{
              maxWidth: "100%",
              maxHeight: "100%",
              userSelect: "none",
              pointerEvents: "none",
              transform: "translate(" + tx + "px, " + ty + "px) scale(" + scale + ")",
              transition: interRef.current.pinchDistInicial > 0
                ? "none"
                : "transform 160ms cubic-bezier(.2,.9,.3,1.2)",
              willChange: "transform",
            }}
          />
        </div>

        {/* Footer (reservado para acciones futuras) */}
        <div
          style={{
            flexShrink: 0,
            height: "calc(56px + env(safe-area-inset-bottom, 0px))",
            paddingBottom: "env(safe-area-inset-bottom, 0px)",
            background: BAR_BG,
            borderTop: "1px solid rgba(255,255,255,0.08)",
            color: BAR_COLOR,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          {/* Placeholder silencioso: acciones (compartir, like) se
              añaden aquí cuando se definan. */}
          <div
            aria-hidden
            style={{
              fontSize: 11,
              fontWeight: 700,
              color: "rgba(240,240,240,0.55)",
              letterSpacing: 0.4,
            }}
          >
            {scale > 1.05 ? "Arrastra para mover · doble tap para reset" : "Pellizca para ampliar · doble tap para zoom"}
          </div>
        </div>

        <style>{`@keyframes lbFade { from { opacity: 0 } to { opacity: 1 } }`}</style>
      </div>
    );

    return ReactDOM.createPortal(content, document.body);
  }

  window.LightboxFoto = LightboxFoto;
})();
