"use client"

import { useEffect, useRef, useState } from "react"
import { ChevronLeft, ChevronRight, X, ZoomIn, ZoomOut } from "lucide-react"
import { getSketchStory } from "@/lib/sketch-story"

interface SketchLightboxProps {
  srcs: string[]
  index: number
  alt: string
  onClose: () => void
  onNavigate: (index: number) => void
}

// Le dossier /full/ contient la même image en résolution native, très peu
// compressée (qualité 95) — c'est la version affichée en grand pour le zoom.
function toFullRes(src: string): string {
  const parts = src.split("/")
  const filename = parts.pop()
  return [...parts, "full", filename].join("/")
}

function GlassPanel({ className = "", children }: { className?: string; children: React.ReactNode }) {
  return (
    <div className={`w-[282px] rounded-lg border border-white/15 bg-white/10 backdrop-blur-xl p-6 shadow-2xl ${className}`}>
      {children}
    </div>
  )
}

// Hash simple et stable (même image -> même disposition à chaque rendu,
// mais différente d'une pièce à l'autre) pour choisir quel groupe de
// panneaux part à gauche ou à droite, sans dépendre d'un vrai random qui
// bougerait à chaque re-render.
function hashString(str: string): number {
  let h = 0
  for (let i = 0; i < str.length; i++) h = (h * 31 + str.charCodeAt(i)) >>> 0
  return h
}

// Rotation circulaire — sert à varier l'ordre des panneaux dans une colonne
// d'une pièce à l'autre sans jamais changer le nombre d'éléments empilés.
function rotate<T>(arr: T[], n: number): T[] {
  const i = ((n % arr.length) + arr.length) % arr.length
  return [...arr.slice(i), ...arr.slice(0, i)]
}

function GlassSection({ title, text }: { title: string; text: string }) {
  return (
    <div>
      <p className="font-mono text-[10px] uppercase tracking-widest text-white/50 mb-1.5">{title}</p>
      <p className="text-sm text-white/85 leading-relaxed whitespace-pre-line">{text}</p>
    </div>
  )
}

// Citation d'un des membres du quatuor (styliste, graphiste, électronicien)
// sur cette pièce précise — pas le concept général du drop, un avis
// personnel sur cet objet.
function QuotePanel({ quote, author }: { quote: string; author: string }) {
  return (
    <GlassPanel className="shrink-0">
      <p className="text-sm text-white/90 leading-relaxed italic">&ldquo;{quote}&rdquo;</p>
      <p className="mt-3 font-mono text-[10px] uppercase tracking-widest text-[var(--accent)]">— {author}</p>
    </GlassPanel>
  )
}

function PieceDetailsPanel({
  piece,
  materials,
  process,
}: {
  piece: string
  materials: string
  process: string
}) {
  return (
    <GlassPanel className="shrink-0 max-h-[45vh] overflow-y-auto">
      <h3 className="text-lg font-heading font-bold uppercase tracking-tight text-white mb-4">{piece}</h3>
      <div className="space-y-4">
        <GlassSection title="Matières" text={materials} />
        <GlassSection title="Fabrication" text={process} />
      </div>
    </GlassPanel>
  )
}

function StoryPanel({ story }: { story: string }) {
  return (
    <GlassPanel className="shrink-0 max-h-[45vh] overflow-y-auto">
      <p className="font-mono text-[10px] uppercase tracking-widest text-white/50 mb-3">Ce qu’elle raconte</p>
      <p className="text-sm text-white/85 leading-relaxed whitespace-pre-line">{story}</p>
    </GlassPanel>
  )
}

// Chaque diapo est le triptyque complet [panneaux | image | panneaux] : le
// texte glisse avec l'image, il fait partie du carrousel plutôt que d'être
// un habillage fixe. Contenu propre à chaque pièce (pas le concept du drop,
// déjà expliqué ailleurs sur la page — ici on ne le répète pas). Les 4
// panneaux (pièce, citation styliste, histoire, citation graphiste) sont
// dispersés en quinconce autour de l'image plutôt qu'alignés en colonnes.
function Slide({
  src,
  alt,
  zoomed,
  onToggleZoom,
}: {
  src: string
  alt: string
  zoomed: boolean
  onToggleZoom: () => void
}) {
  const { piece, materials, process, story, stylistQuote, designerQuote, electricianQuote } = getSketchStory(src)

  // Deux groupes de panneaux plutôt qu'une disposition en pourcentages
  // libres : la pièce/histoire (potentiellement longues, défilables) d'un
  // côté, les trois citations du quatuor de l'autre. Chaque groupe est
  // empilé en colonne flexbox — l'empilement garantit nativement l'absence
  // de chevauchement, quelle que soit la hauteur réelle de chaque panneau.
  const h = hashString(src)
  const detailsGroup = [
    <PieceDetailsPanel key="piece" piece={piece} materials={materials} process={process} />,
    <StoryPanel key="story" story={story} />,
  ]
  const quotesGroup = rotate(
    [
      <QuotePanel key="stylist" quote={stylistQuote} author="Le styliste, O.M.T" />,
      <QuotePanel key="designer" quote={designerQuote} author="La graphiste, O.M.T" />,
      <QuotePanel key="electrician" quote={electricianQuote} author="L'électronicien, O.M.T" />,
    ],
    h
  )
  // Le hash décide aussi de quel côté part quel groupe, pour varier la
  // disposition d'une pièce à l'autre sans jamais risquer de superposition.
  const flip = h % 2 === 0
  const leftItems = flip ? detailsGroup : quotesGroup
  const rightItems = flip ? quotesGroup : detailsGroup

  return (
    <div className="snap-center shrink-0 relative w-full h-full flex items-center justify-center px-4">
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src={toFullRes(src)}
        alt={alt}
        onClick={(e) => {
          e.stopPropagation()
          onToggleZoom()
        }}
        className={
          zoomed
            ? "max-w-none w-[1800px] max-w-[none] cursor-zoom-out my-auto"
            : "h-full max-w-full object-contain cursor-zoom-in"
        }
      />

      {/* Au zoom, chaque colonne entière est projetée hors de l'écran
          (transform), au lieu de rester plaquée contre une image bien plus
          grande qu'elle — puis revient à sa place quand on dézoome. */}
      <div
        className={`hidden lg:flex absolute inset-y-6 left-2 z-20 flex-col items-start justify-between gap-6 transition-transform duration-500 ease-out ${zoomed ? "-translate-x-[160%] pointer-events-none" : "translate-x-0"}`}
      >
        {leftItems}
      </div>

      <div
        className={`hidden lg:flex absolute inset-y-6 right-2 z-20 flex-col items-end justify-between gap-6 transition-transform duration-500 ease-out ${zoomed ? "translate-x-[160%] pointer-events-none" : "translate-x-0"}`}
      >
        {rightItems}
      </div>
    </div>
  )
}

export function SketchLightbox({
  srcs,
  index,
  alt,
  onClose,
  onNavigate,
}: SketchLightboxProps) {
  const trackRef = useRef<HTMLDivElement>(null)
  const [current, setCurrent] = useState(index)
  const [zoomed, setZoomed] = useState(false)

  // Positionne le carrousel sur la diapo initiale sans animation, une seule
  // fois au montage — pas de setState ici, juste un scroll DOM direct.
  useEffect(() => {
    const track = trackRef.current
    if (!track) return
    track.scrollTo({ left: index * track.clientWidth, behavior: "instant" })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  function scrollToIndex(i: number, smooth = true) {
    const track = trackRef.current
    if (!track) return
    track.scrollTo({ left: i * track.clientWidth, behavior: smooth ? "smooth" : "instant" })
  }

  function onScroll() {
    const track = trackRef.current
    if (!track) return
    const i = Math.round(track.scrollLeft / track.clientWidth)
    if (i !== current) {
      setCurrent(i)
      setZoomed(false)
      onNavigate(i)
    }
  }

  useEffect(() => {
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === "Escape") onClose()
      if (e.key === "ArrowRight") scrollToIndex((current + 1) % srcs.length)
      if (e.key === "ArrowLeft") scrollToIndex((current - 1 + srcs.length) % srcs.length)
    }
    window.addEventListener("keydown", onKeyDown)
    return () => window.removeEventListener("keydown", onKeyDown)
  }, [current, srcs.length, onClose])

  return (
    <div
      className="fixed inset-0 z-[100] bg-black/95 flex flex-col"
      onClick={onClose}
      role="dialog"
      aria-modal="true"
      aria-label={alt}
    >
      <div className="flex items-center justify-between px-4 py-3 shrink-0">
        <p className="font-mono text-[10px] uppercase tracking-widest text-white/60">
          {current + 1} / {srcs.length}
        </p>
        <div className="flex items-center gap-4">
          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation()
              setZoomed((z) => !z)
            }}
            className="text-white/70 hover:text-white transition-colors"
            aria-label={zoomed ? "Dézoomer" : "Zoomer"}
          >
            {zoomed ? <ZoomOut size={20} /> : <ZoomIn size={20} />}
          </button>
          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation()
              onClose()
            }}
            className="text-white/70 hover:text-white transition-colors"
            aria-label="Fermer"
          >
            <X size={22} />
          </button>
        </div>
      </div>

      <div className="relative flex-1 min-h-0" onClick={(e) => e.stopPropagation()}>
        <div
          ref={trackRef}
          onScroll={onScroll}
          className={`h-full flex ${zoomed ? "overflow-auto" : "overflow-x-auto overflow-y-hidden"} snap-x snap-mandatory no-scrollbar`}
        >
          {srcs.map((src, i) => (
            <Slide
              key={src}
              src={src}
              alt={alt}
              zoomed={zoomed && i === current}
              onToggleZoom={() => setZoomed((z) => !z)}
            />
          ))}
        </div>

        {srcs.length > 1 && (
          <>
            <button
              type="button"
              onClick={() => scrollToIndex((current - 1 + srcs.length) % srcs.length)}
              className="absolute left-2 top-1/2 -translate-y-1/2 z-10 text-white/60 hover:text-white transition-colors bg-black/40 rounded-full p-2"
              aria-label="Croquis précédent"
            >
              <ChevronLeft size={24} />
            </button>
            <button
              type="button"
              onClick={() => scrollToIndex((current + 1) % srcs.length)}
              className="absolute right-2 top-1/2 -translate-y-1/2 z-10 text-white/60 hover:text-white transition-colors bg-black/40 rounded-full p-2"
              aria-label="Croquis suivant"
            >
              <ChevronRight size={24} />
            </button>
          </>
        )}
      </div>
    </div>
  )
}
