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

function Carousel({ 
  children, 
  activeIndex, 
  setActiveIndex, 
  labels = [],
  showLabels = true,
  className = ''
}) {
  const touchStartX = useRef(null);
  const touchStartY = useRef(null);
  const trackRef = useRef(null);
  const [dragOffset, setDragOffset] = useState(0);
  const [isDragging, setIsDragging] = useState(false);
  const itemCount = React.Children.count(children);
  
  const SWIPE_THRESHOLD = 50;

  const handleTouchStart = useCallback((e) => {
    touchStartX.current = e.touches[0].clientX;
    touchStartY.current = e.touches[0].clientY;
    setIsDragging(true);
  }, []);

  const handleTouchMove = useCallback((e) => {
    if (!touchStartX.current || !isDragging) return;
    
    const currentX = e.touches[0].clientX;
    const currentY = e.touches[0].clientY;
    const diffX = currentX - touchStartX.current;
    const diffY = Math.abs(currentY - touchStartY.current);
    
    // Only drag horizontally if not scrolling vertically
    if (Math.abs(diffX) > diffY) {
      // Add resistance at edges
      let offset = diffX;
      if ((activeIndex === 0 && diffX > 0) || (activeIndex === itemCount - 1 && diffX < 0)) {
        offset = diffX * 0.25;
      }
      setDragOffset(offset);
    }
  }, [isDragging, activeIndex, itemCount]);

  const handleTouchEnd = useCallback((e) => {
    if (!touchStartX.current) return;
    
    const diff = touchStartX.current - e.changedTouches[0].clientX;
    
    if (Math.abs(diff) > SWIPE_THRESHOLD) {
      if (diff > 0 && activeIndex < itemCount - 1) {
        setActiveIndex(activeIndex + 1);
      } else if (diff < 0 && activeIndex > 0) {
        setActiveIndex(activeIndex - 1);
      }
    }
    
    touchStartX.current = null;
    touchStartY.current = null;
    setDragOffset(0);
    setIsDragging(false);
  }, [activeIndex, setActiveIndex, itemCount]);

  const handleKeyDown = useCallback((e) => {
    if (e.key === 'ArrowLeft' && activeIndex > 0) {
      setActiveIndex(activeIndex - 1);
    } else if (e.key === 'ArrowRight' && activeIndex < itemCount - 1) {
      setActiveIndex(activeIndex + 1);
    }
  }, [activeIndex, setActiveIndex, itemCount]);

  // Calculate transform with drag offset
  const baseTransform = -(activeIndex * 100);
  const dragPercent = trackRef.current 
    ? (dragOffset / trackRef.current.offsetWidth) * 100 
    : 0;
  const transform = baseTransform + dragPercent;

  return (
    <div 
      className={`carousel ${className}`} 
      onKeyDown={handleKeyDown} 
      tabIndex={0}
      role="region"
      aria-label="Carousel"
    >
      <div className="carousel-container">
        <div className="carousel-viewport">
          <div 
            ref={trackRef}
            className="carousel-track"
            style={{ 
              transform: `translateX(${transform}%)`,
              transition: isDragging ? 'none' : undefined
            }}
            onTouchStart={handleTouchStart}
            onTouchMove={handleTouchMove}
            onTouchEnd={handleTouchEnd}
          >
            {React.Children.map(children, (child, i) => (
              <div 
                className="carousel-slide" 
                key={i}
                role="tabpanel"
                aria-hidden={activeIndex !== i}
              >
                {child}
              </div>
            ))}
          </div>
        </div>
      </div>
      
      <div className={`carousel-dots ${showLabels ? 'labeled' : ''}`} role="tablist">
        {Array.from({ length: itemCount }).map((_, i) => (
          <button
            key={i}
            className={`carousel-dot ${activeIndex === i ? 'active' : ''}`}
            onClick={() => setActiveIndex(i)}
            role="tab"
            aria-selected={activeIndex === i}
            aria-label={labels[i] || `Slide ${i + 1}`}
          >
            {showLabels && labels[i] && (
              <span className="dot-label">{labels[i]}</span>
            )}
          </button>
        ))}
      </div>
    </div>
  );
}

export default Carousel;
