import React, { useRef, useState } from 'react';
import './Slider.css';

interface SliderProps {
  children: React.ReactNode;
}

function Slider({ children }: SliderProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const imageRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [startPosition, setStartPosition] = useState(0);
  const [currentTranslate, setCurrentTranslate] = useState(0);
  const [prevTranslate, setPrevTranslate] = useState(0);
  const [animationId, setAnimationId] = useState<number | null>(null);
  const [minTranslate, setMinTranslate] = useState(0);
  const [maxTranslate, setMaxTranslate] = useState(0);

  const startDragging = (event: any) => {
    if (event.type === 'touchstart') {
      setStartPosition(event.touches[0].clientX);
    } else {
      setStartPosition(event.clientX);
    }

    setIsDragging(true);
    cancelAnimationFrame(animationId!);
  };

  const dragging = (event: any) => {
    if (isDragging) {
      let currentPosition = 0;

      if (event.type === 'touchmove') {
        currentPosition = event.touches[0].clientX;
      } else {
        currentPosition = event.clientX;
      }

      const diff = currentPosition - startPosition;
      const newTranslate = prevTranslate + diff;
      const newMinTranslate = containerRef.current!.offsetWidth - imageRef.current!.offsetWidth;
      const newMaxTranslate = 0;

      if (newTranslate < newMinTranslate) {
        setCurrentTranslate(newMinTranslate);
      } else if (newTranslate > newMaxTranslate) {
        setCurrentTranslate(newMaxTranslate);
      } else {
        setCurrentTranslate(newTranslate);
      }
    }
  };

  const stopDragging = () => {
    setIsDragging(false);

    if (currentTranslate < minTranslate) {
      setCurrentTranslate(minTranslate);
    } else if (currentTranslate > maxTranslate) {
      setCurrentTranslate(maxTranslate);
    }

    setPrevTranslate(currentTranslate);

    setAnimationId(requestAnimationFrame(() => {
      imageRef.current!.style.transition = 'transform 0.3s ease-out';
      imageRef.current!.style.transform = `translateX(${currentTranslate}px)`;
    }));
  };

  const updateBoundaries = () => {
    if (containerRef.current && imageRef.current) {
      const containerWidth = containerRef.current.offsetWidth;
      const imageWidth = imageRef.current.offsetWidth;
      setMinTranslate(containerWidth - imageWidth);
      setMaxTranslate(0);
    }
  };

  return (
    <div
      className="slider-container"
      ref={containerRef}
      onMouseDown={startDragging}
      onTouchStart={startDragging}
      onMouseUp={stopDragging}
      onTouchEnd={stopDragging}
      onMouseLeave={stopDragging}
      onMouseMove={dragging}
      onTouchMove={dragging}
      onWheel={(event) => {
        event.preventDefault();
        setCurrentTranslate((prevTranslate) => {
          const scrollDistance = event.deltaY * -1;
          const maxScrollDistance = maxTranslate - prevTranslate;
          const minScrollDistance = minTranslate - prevTranslate;
          const scrollAmount =
            scrollDistance > 0
              ? Math.min(scrollDistance, maxScrollDistance)
              : Math.max(scrollDistance, minScrollDistance);
          return prevTranslate + scrollAmount;
        });
      }}
      onResize={updateBoundaries}
    >
      <div className="slider-con" ref={imageRef}>
        {children}
      </div>
    </div>
  );
}

export default Slider;