'use client'

import Image from 'next/image'
import { useCallback, useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import type { GalleryItem } from '@/lib/data'
import { IconArrowBack, IconArrowForward, IconClose } from './Icons'

type Dir = 'next' | 'prev' | 'none'

/**
 * Teljes képernyős képnézegető.
 * - a képből vett elmosott háttér adja a mélységet
 * - irányfüggő be-/kicsúszás lapozáskor
 * - bélyegképsáv, ami az aktuálisra görget
 * - kattintásra ránagyít, a nagyított képen belül az egérrel lehet mozogni
 * - érintésen húzással lapoz, billentyűzeten nyilakkal
 * - a szomszédos képeket előre betölti, hogy a váltás azonnali legyen
 */
export default function Lightbox({
  items,
  index,
  onClose,
  onIndexChange,
  basePath,
}: {
  items: GalleryItem[]
  index: number
  onClose: () => void
  onIndexChange: (update: (prev: number) => number) => void
  basePath: string
}) {
  const [dir, setDir] = useState<Dir>('none')
  const [zoomed, setZoomed] = useState(false)
  const [origin, setOrigin] = useState('50% 50%')
  const stripRef = useRef<HTMLDivElement>(null)
  const touchX = useRef<number | null>(null)
  const [mounted, setMounted] = useState(false)

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

  const current = items[index]

  // Funkcionális frissítés: két gyors kattintás egy renderen belül is
  // két lépést jelentsen, ne olvassa mindkettő ugyanazt az elavult indexet.
  const go = useCallback(
    (d: 1 | -1) => {
      setDir(d === 1 ? 'next' : 'prev')
      setZoomed(false)
      onIndexChange((prev) => (prev + d + items.length) % items.length)
    },
    [items.length, onIndexChange]
  )

  const jumpTo = useCallback(
    (i: number) => {
      setDir(i > index ? 'next' : 'prev')
      setZoomed(false)
      onIndexChange(() => i)
    },
    [index, onIndexChange]
  )

  // billentyűzet
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') return zoomed ? setZoomed(false) : onClose()
      if (e.key === 'ArrowLeft') go(-1)
      if (e.key === 'ArrowRight') go(1)
    }
    document.addEventListener('keydown', onKey)
    document.body.style.overflow = 'hidden'
    return () => {
      document.removeEventListener('keydown', onKey)
      document.body.style.overflow = ''
    }
  }, [go, onClose, zoomed])

  // A bélyegképsáv kövesse az aktuális képet — csak a sáv saját
  // vízszintes görgetését állítjuk, a scrollIntoView a lapot is mozgatná.
  useEffect(() => {
    const strip = stripRef.current
    const active = strip?.querySelector<HTMLElement>('.is-active')
    if (!strip || !active) return
    strip.scrollTo({
      left: active.offsetLeft - strip.clientWidth / 2 + active.clientWidth / 2,
      behavior: 'smooth',
    })
  }, [index])

  const src = (item: GalleryItem) => `${basePath}/${item.picture}`
  const alt = (item: GalleryItem, i: number) => item.title ?? `Esküvői fotó ${i + 1}`

  const prevItem = items[(index - 1 + items.length) % items.length]
  const nextItem = items[(index + 1) % items.length]

  if (!mounted) return null

  return createPortal(
    <div
      className="lightbox"
      role="dialog"
      aria-modal="true"
      aria-label={`${index + 1}. kép a ${items.length}-ból`}
      onClick={onClose}
      onTouchStart={(e) => {
        touchX.current = e.touches[0].clientX
      }}
      onTouchEnd={(e) => {
        if (touchX.current === null) return
        const dx = e.changedTouches[0].clientX - touchX.current
        if (Math.abs(dx) > 55) go(dx < 0 ? 1 : -1)
        touchX.current = null
      }}
    >
      <div className="lightbox-ambient" style={{ backgroundImage: `url(${src(current)})` }} />

      <span className="lightbox-counter">
        <b>{String(index + 1).padStart(2, '0')}</b> / {String(items.length).padStart(2, '0')}
      </span>

      <div className={`lightbox-stage dir-${dir}`}>
        <Image
          key={current.id}
          src={src(current)}
          alt={alt(current, index)}
          width={1800}
          height={1350}
          sizes="94vw"
          priority
          className={zoomed ? 'is-zoomed' : undefined}
          style={zoomed ? { transformOrigin: origin } : undefined}
          onClick={(e) => {
            e.stopPropagation()
            const r = e.currentTarget.getBoundingClientRect()
            setOrigin(`${((e.clientX - r.left) / r.width) * 100}% ${((e.clientY - r.top) / r.height) * 100}%`)
            setZoomed((z) => !z)
          }}
          onMouseMove={(e) => {
            if (!zoomed) return
            const r = e.currentTarget.getBoundingClientRect()
            setOrigin(`${((e.clientX - r.left) / r.width) * 100}% ${((e.clientY - r.top) / r.height) * 100}%`)
          }}
        />
      </div>

      {/* a szomszédos képek előtöltése — a lapozás így nem villan */}
      <div style={{ display: 'none' }} aria-hidden="true">
        <Image src={src(prevItem)} alt="" width={1800} height={1350} sizes="94vw" />
        <Image src={src(nextItem)} alt="" width={1800} height={1350} sizes="94vw" />
      </div>

      <button type="button" className="lightbox-btn lightbox-close" onClick={onClose} aria-label="Bezárás">
        <IconClose />
      </button>
      <button
        type="button"
        className="lightbox-btn lightbox-prev"
        onClick={(e) => {
          e.stopPropagation()
          go(-1)
        }}
        aria-label="Előző kép"
      >
        <IconArrowBack />
      </button>
      <button
        type="button"
        className="lightbox-btn lightbox-next"
        onClick={(e) => {
          e.stopPropagation()
          go(1)
        }}
        aria-label="Következő kép"
      >
        <IconArrowForward />
      </button>

      <div className="lightbox-strip" ref={stripRef} onClick={(e) => e.stopPropagation()}>
        {items.map((item, i) => (
          <button
            key={item.id}
            type="button"
            className={`lightbox-thumb${i === index ? ' is-active' : ''}`}
            onClick={() => jumpTo(i)}
            aria-label={`Ugrás a ${i + 1}. képre`}
            aria-current={i === index}
          >
            <Image src={src(item)} alt="" width={74} height={52} sizes="74px" loading="lazy" />
          </button>
        ))}
      </div>
    </div>,
    document.body
  )
}
