import { useEffect, useState, type ReactNode } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import { motion, AnimatePresence } from 'framer-motion'
import { ChevronLeft, ChevronRight } from '../../lib/icons'

interface Props {
  children: ReactNode
  /** Padding-x applied to the inner track. Matches whatever sits above
   *  it in the page (typically `px-7`). */
  trackPadding?: string
  /** Gap between children. Cast strips use 12px; recommendation rows
   *  use 12-16px. */
  gap?: string
  /** Vertical offset for the nav arrows so they sit centered on the
   *  poster/avatar, not on the label below. The default `bottom-12`
   *  matches ContentRow which has poster + 2 lines of text. Use
   *  `bottom-14` for cast (avatar + 2 lines) or `bottom-0` to center
   *  on the full row. */
  arrowsBottomInset?: string
  /** Optional className overrides on the outer wrapper. */
  className?: string
}

/**
 * Carousel chrome reused across content rows, cast strips, crew
 * grids, and TMDB recommendation strips. Wraps its children in an
 * Embla viewport with smooth horizontal scroll, hover-revealed nav
 * arrows on either side, and edge fades that hide when the user has
 * already scrolled to that end.
 *
 * Children should be a flex row of equal-height items (the parent
 * supplies the layout; HorizontalScroller just provides the chrome).
 */
export default function HorizontalScroller({
  children,
  trackPadding = 'px-7',
  gap = 'gap-3',
  arrowsBottomInset = 'bottom-12',
  className,
}: Props) {
  const [ref, embla] = useEmblaCarousel({
    align: 'start',
    containScroll: 'trimSnaps',
    dragFree: true,
  })
  const [canPrev, setCanPrev] = useState(false)
  const [canNext, setCanNext] = useState(false)

  useEffect(() => {
    if (!embla) return
    const update = () => {
      setCanPrev(embla.canScrollPrev())
      setCanNext(embla.canScrollNext())
    }
    embla.on('select', update)
    embla.on('reInit', update)
    embla.on('scroll', update)
    update()
    return () => {
      embla.off('select', update)
      embla.off('reInit', update)
      embla.off('scroll', update)
    }
  }, [embla])

  return (
    <div className={`relative group/scroller ${className || ''}`}>
      {/* Edge fade left */}
      <div
        className={`absolute left-0 top-0 bottom-0 w-12 z-10 pointer-events-none bg-gradient-to-r from-void via-void/60 to-transparent transition-opacity duration-300 ${
          canPrev ? 'opacity-100' : 'opacity-0'
        }`}
      />
      {/* Edge fade right */}
      <div
        className={`absolute right-0 top-0 bottom-0 w-12 z-10 pointer-events-none bg-gradient-to-l from-void via-void/60 to-transparent transition-opacity duration-300 ${
          canNext ? 'opacity-100' : 'opacity-0'
        }`}
      />

      <AnimatePresence>
        {canPrev && (
          <motion.button
            initial={{ opacity: 0, x: 4 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: 4 }}
            transition={{ duration: 0.18 }}
            onClick={() => embla?.scrollPrev()}
            className={`absolute left-2 top-0 ${arrowsBottomInset} w-12 z-20 flex items-center justify-center opacity-0 group-hover/scroller:opacity-100 transition-opacity duration-200 focus:opacity-100`}
            aria-label="Previous"
          >
            <div className="w-9 h-9 rounded-full glass-strong border border-border-hover grid place-items-center text-text-2 hover:text-accent shadow-md hover:scale-105 active:scale-95 transition-all duration-200">
              <ChevronLeft size={16} strokeWidth={2.25} />
            </div>
          </motion.button>
        )}
      </AnimatePresence>

      <AnimatePresence>
        {canNext && (
          <motion.button
            initial={{ opacity: 0, x: -4 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: -4 }}
            transition={{ duration: 0.18 }}
            onClick={() => embla?.scrollNext()}
            className={`absolute right-2 top-0 ${arrowsBottomInset} w-12 z-20 flex items-center justify-center opacity-0 group-hover/scroller:opacity-100 transition-opacity duration-200 focus:opacity-100`}
            aria-label="Next"
          >
            <div className="w-9 h-9 rounded-full glass-strong border border-border-hover grid place-items-center text-text-2 hover:text-accent shadow-md hover:scale-105 active:scale-95 transition-all duration-200">
              <ChevronRight size={16} strokeWidth={2.25} />
            </div>
          </motion.button>
        )}
      </AnimatePresence>

      <div ref={ref} className="overflow-hidden">
        <div className={`flex ${gap} ${trackPadding} py-1`}>{children}</div>
      </div>
    </div>
  )
}
