'use client'

import { useState, useEffect, useRef } from 'react'

export interface GalerieBild { id: string; src: string; alt: string }

interface Slot { bild: GalerieBild; phase: 'idle' | 'out' | 'in' }

const VISIBLE = 12
const INTERVAL_MS = 1500
const FLIP_MS = 360
const GAP = 8
const ROW_H = 165

function shuffle<T>(arr: T[]): T[] {
  const a = [...arr]
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]]
  }
  return a
}

export function GalerieAnzeige({ bilder }: { bilder: GalerieBild[] }) {
  const n = Math.min(bilder.length, VISIBLE)

  // Kein shuffle im initializer → Server und Client rendern identisch → kein Hydration-Mismatch
  const [slots, setSlots] = useState<Slot[]>(() =>
    bilder.slice(0, n).map(b => ({ bild: b, phase: 'idle' as const }))
  )

  const slotsRef = useRef<Slot[]>(slots)
  useEffect(() => { slotsRef.current = slots }, [slots])

  const flipping = useRef(new Set<number>())
  const poolRef = useRef<GalerieBild[]>([])
  const poolIdxRef = useRef(0)

  useEffect(() => {
    // Läuft nur auf dem Client, nach der Hydration
    const shuffled = shuffle([...bilder])
    poolRef.current = shuffled
    poolIdxRef.current = n

    setSlots(shuffled.slice(0, n).map(b => ({ bild: b, phase: 'idle' as const })))

    if (bilder.length < 2) return

    const id = setInterval(() => {
      const cur = slotsRef.current
      const free = cur.map((_, i) => i).filter(i => !flipping.current.has(i))
      if (free.length === 0) return

      const si = free[Math.floor(Math.random() * free.length)]

      if (bilder.length > VISIBLE) {
        const next = poolRef.current[poolIdxRef.current % poolRef.current.length]
        poolIdxRef.current++
        flip(si, next)
      } else {
        const others = free.filter(i => i !== si)
        if (others.length === 0) return
        const oi = others[Math.floor(Math.random() * others.length)]
        flip(si, cur[oi].bild)
        flip(oi, cur[si].bild)
      }
    }, INTERVAL_MS)

    return () => clearInterval(id)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []) // bewusst leer: läuft genau einmal nach Mount

  function flip(i: number, newBild: GalerieBild) {
    flipping.current.add(i)
    setSlots(p => p.map((s, j) => j === i ? { ...s, phase: 'out' } : s))
    setTimeout(() => {
      setSlots(p => p.map((s, j) => j === i ? { bild: newBild, phase: 'in' } : s))
      setTimeout(() => {
        setSlots(p => p.map((s, j) => j === i ? { ...s, phase: 'idle' } : s))
        flipping.current.delete(i)
      }, FLIP_MS)
    }, FLIP_MS)
  }

  const imgStyle = (phase: string): React.CSSProperties => ({
    position: 'absolute', inset: 0, width: '100%', height: '100%',
    objectFit: 'cover', objectPosition: 'center',
    animation:
      phase === 'out' ? `galFlipOut ${FLIP_MS}ms ease-in forwards` :
      phase === 'in'  ? `galFlipIn ${FLIP_MS}ms ease-out forwards` :
      'none',
  })

  const numGroups = Math.ceil(slots.length / 4)

  return (
    <>
      <style>{`
        @keyframes galFlipOut {
          from { transform: perspective(700px) rotateY(0deg); }
          to   { transform: perspective(700px) rotateY(90deg); }
        }
        @keyframes galFlipIn {
          from { transform: perspective(700px) rotateY(-90deg); }
          to   { transform: perspective(700px) rotateY(0deg); }
        }
        .galerie-cell:hover .galerie-hl { opacity: 1 !important; }
      `}</style>

      {/* Mobile */}
      <div className="grid grid-cols-2 gap-2 md:hidden">
        {slots.map((slot, si) => (
          <div key={si} className="galerie-cell relative aspect-[4/3] overflow-hidden rounded-lg">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img src={slot.bild.src} alt={slot.bild.alt} style={imgStyle(slot.phase)} />
            <div className="galerie-hl absolute inset-0 transition-opacity duration-300"
              style={{ background: 'rgba(76,175,80,0.15)', opacity: 0 }} />
          </div>
        ))}
      </div>

      {/* Desktop */}
      <div className="hidden md:flex flex-col" style={{ gap: GAP }}>
        {Array.from({ length: numGroups }, (_, gi) => {
          const bigLeft = gi % 2 === 0
          return (
            <div key={gi} style={{
              display: 'grid',
              gridTemplateColumns: bigLeft ? '2fr 1fr' : '1fr 2fr',
              gridTemplateRows: `repeat(3, ${ROW_H}px)`,
              gap: GAP,
            }}>
              {[0, 1, 2, 3].map(idx => {
                const si = gi * 4 + idx
                const slot = slots[si]
                if (!slot) return null
                const cellStyle: React.CSSProperties = bigLeft
                  ? { gridColumn: idx === 0 ? '1' : '2', gridRow: idx === 0 ? '1/4' : `${idx}` }
                  : { gridColumn: idx === 3 ? '2' : '1', gridRow: idx === 3 ? '1/4' : `${idx + 1}` }
                return (
                  <div key={si} className="galerie-cell relative overflow-hidden rounded-lg" style={cellStyle}>
                    {/* eslint-disable-next-line @next/next/no-img-element */}
                    <img src={slot.bild.src} alt={slot.bild.alt} style={imgStyle(slot.phase)} />
                    <div className="galerie-hl absolute inset-0 transition-opacity duration-300"
                      style={{ background: 'rgba(76,175,80,0.15)', opacity: 0 }} />
                  </div>
                )
              })}
            </div>
          )
        })}
      </div>
    </>
  )
}
