"use client";

import React, { useState, useEffect, useCallback, useRef } from 'react';

export interface CarouselItem {
  /** Image source */
  src?: string;
  /** Alt text for image */
  alt?: string;
  /** Caption title */
  title?: string;
  /** Caption description */
  description?: string;
  /** Custom content instead of image */
  content?: React.ReactNode;
}

export interface CarouselProps {
  /** Carousel items */
  items: CarouselItem[];
  /** Show indicators */
  indicators?: boolean;
  /** Show controls (prev/next) */
  controls?: boolean;
  /** Auto play */
  autoPlay?: boolean;
  /** Interval in ms */
  interval?: number;
  /** Pause on hover */
  pauseOnHover?: boolean;
  /** Enable keyboard navigation */
  keyboard?: boolean;
  /** Enable touch/swipe */
  touch?: boolean;
  /** Crossfade animation */
  fade?: boolean;
  /** Dark variant */
  dark?: boolean;
  /** Active index (controlled) */
  activeIndex?: number;
  /** Callback when slide changes */
  onSlide?: (index: number) => void;
  /** Additional CSS classes */
  className?: string;
}

export const Carousel: React.FC<CarouselProps> = ({
  items,
  indicators = true,
  controls = true,
  autoPlay = false,
  interval = 5000,
  pauseOnHover = true,
  keyboard = true,
  touch = true,
  fade = false,
  dark = false,
  activeIndex: controlledIndex,
  onSlide,
  className = '',
}) => {
  const [currentIndex, setCurrentIndex] = useState(controlledIndex ?? 0);
  const [isPaused, setIsPaused] = useState(false);
  const [touchStart, setTouchStart] = useState<number | null>(null);
  const carouselRef = useRef<HTMLDivElement>(null);

  const activeIndex = controlledIndex ?? currentIndex;

  const goToSlide = useCallback((index: number) => {
    const newIndex = index < 0 ? items.length - 1 : index >= items.length ? 0 : index;
    if (controlledIndex === undefined) {
      setCurrentIndex(newIndex);
    }
    onSlide?.(newIndex);
  }, [items.length, controlledIndex, onSlide]);

  const goToPrev = useCallback(() => {
    goToSlide(activeIndex - 1);
  }, [activeIndex, goToSlide]);

  const goToNext = useCallback(() => {
    goToSlide(activeIndex + 1);
  }, [activeIndex, goToSlide]);

  // Auto play
  useEffect(() => {
    if (!autoPlay || isPaused) return;

    const timer = setInterval(() => {
      goToNext();
    }, interval);

    return () => clearInterval(timer);
  }, [autoPlay, isPaused, interval, goToNext]);

  // Keyboard navigation
  useEffect(() => {
    if (!keyboard) return;

    const handleKeydown = (e: KeyboardEvent) => {
      if (e.key === 'ArrowLeft') {
        goToPrev();
      } else if (e.key === 'ArrowRight') {
        goToNext();
      }
    };

    const carousel = carouselRef.current;
    carousel?.addEventListener('keydown', handleKeydown);
    return () => carousel?.removeEventListener('keydown', handleKeydown);
  }, [keyboard, goToPrev, goToNext]);

  // Touch handling
  const handleTouchStart = (e: React.TouchEvent) => {
    if (!touch) return;
    setTouchStart(e.touches[0].clientX);
  };

  const handleTouchEnd = (e: React.TouchEvent) => {
    if (!touch || touchStart === null) return;

    const touchEnd = e.changedTouches[0].clientX;
    const diff = touchStart - touchEnd;

    if (Math.abs(diff) > 50) {
      if (diff > 0) {
        goToNext();
      } else {
        goToPrev();
      }
    }
    setTouchStart(null);
  };

  const classes = [
    'll-carousel',
    fade && 'll-carousel-fade',
    dark && 'll-carousel-dark',
    className,
  ].filter(Boolean).join(' ');

  return (
    <div
      ref={carouselRef}
      className={classes}
      tabIndex={keyboard ? 0 : undefined}
      onMouseEnter={() => pauseOnHover && setIsPaused(true)}
      onMouseLeave={() => pauseOnHover && setIsPaused(false)}
      onTouchStart={handleTouchStart}
      onTouchEnd={handleTouchEnd}
    >
      {/* Indicators */}
      {indicators && items.length > 1 && (
        <div className="ll-carousel-indicators">
          {items.map((_, index) => (
            <button
              key={index}
              type="button"
              className={`ll-carousel-indicator ${index === activeIndex ? 'active' : ''}`}
              onClick={() => goToSlide(index)}
              aria-current={index === activeIndex}
              aria-label={`Slide ${index + 1}`}
            />
          ))}
        </div>
      )}

      {/* Slides */}
      <div className="ll-carousel-inner">
        {items.map((item, index) => (
          <div
            key={index}
            className={`ll-carousel-item ${index === activeIndex ? 'active' : ''}`}
          >
            {item.content || (
              <img
                src={item.src}
                alt={item.alt || ''}
                className="ll-carousel-image"
              />
            )}
            {(item.title || item.description) && (
              <div className="ll-carousel-caption">
                {item.title && <h5>{item.title}</h5>}
                {item.description && <p>{item.description}</p>}
              </div>
            )}
          </div>
        ))}
      </div>

      {/* Controls */}
      {controls && items.length > 1 && (
        <>
          <button
            type="button"
            className="ll-carousel-control ll-carousel-control-prev"
            onClick={goToPrev}
            aria-label="Previous"
          >
            <span className="ll-carousel-control-icon ll-carousel-control-prev-icon" aria-hidden="true" />
          </button>
          <button
            type="button"
            className="ll-carousel-control ll-carousel-control-next"
            onClick={goToNext}
            aria-label="Next"
          >
            <span className="ll-carousel-control-icon ll-carousel-control-next-icon" aria-hidden="true" />
          </button>
        </>
      )}
    </div>
  );
};
