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

interface CustomScrollbarProps {
  children: React.ReactNode;
  className?: string;
  horizontal?: boolean;
}

export const CustomScrollbar: React.FC<CustomScrollbarProps> = ({ 
  children, 
  className = '',
  horizontal = false 
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const thumbRef = useRef<HTMLDivElement>(null);
  
  const [isHoveringContainer, setIsHoveringContainer] = useState(false);
  const [isHoveringTrack, setIsHoveringTrack] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [thumbSize, setThumbSize] = useState(40);
  
  // Drag state
  const dragState = useRef({
    isActive: false,
    startMouse: 0,
    startScroll: 0,
    trackSize: 0,
    maxScroll: 0
  });

  // Update thumb size
  const updateMetrics = useCallback(() => {
    const container = containerRef.current;
    if (!container) return;
    
    if (horizontal) {
      const ratio = container.clientWidth / Math.max(container.scrollWidth, 1);
      setThumbSize(Math.max(40, ratio * container.clientWidth));
    } else {
      const ratio = container.clientHeight / Math.max(container.scrollHeight, 1);
      setThumbSize(Math.max(40, ratio * container.clientHeight));
    }
    
    updateThumbVisual();
  }, [horizontal]);

  // Update thumb position from scroll
  const updateThumbVisual = useCallback(() => {
    const container = containerRef.current;
    const thumb = thumbRef.current;
    if (!container || !thumb) return;
    
    if (dragState.current.isActive) return;
    
    if (horizontal) {
      const maxScroll = container.scrollWidth - container.clientWidth;
      const trackSize = container.clientWidth - thumbSize;
      if (maxScroll <= 0 || trackSize <= 0) {
        thumb.style.transform = 'translateX(0px)';
        return;
      }
      const ratio = container.scrollLeft / maxScroll;
      thumb.style.transform = `translateX(${ratio * trackSize}px)`;
    } else {
      const maxScroll = container.scrollHeight - container.clientHeight;
      const trackSize = container.clientHeight - thumbSize;
      if (maxScroll <= 0 || trackSize <= 0) {
        thumb.style.transform = 'translateY(0px)';
        return;
      }
      const ratio = container.scrollTop / maxScroll;
      thumb.style.transform = `translateY(${ratio * trackSize}px)`;
    }
  }, [horizontal, thumbSize]);

  // Setup
  useEffect(() => {
    updateMetrics();
    
    const handleResize = () => updateMetrics();
    window.addEventListener('resize', handleResize);
    
    const observer = new MutationObserver(() => updateMetrics());
    if (containerRef.current) {
      observer.observe(containerRef.current, { childList: true, subtree: true });
    }
    
    return () => {
      window.removeEventListener('resize', handleResize);
      observer.disconnect();
    };
  }, [updateMetrics]);

  // Scroll listener
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const onScroll = () => {
      if (!dragState.current.isActive) {
        updateThumbVisual();
      }
    };

    container.addEventListener('scroll', onScroll, { passive: true });
    return () => container.removeEventListener('scroll', onScroll);
  }, [updateThumbVisual]);

  // Drag handling - DIRECT synchronous updates
  useEffect(() => {
    if (!isDragging) {
      // Restore transition when not dragging
      if (thumbRef.current) {
        thumbRef.current.style.transition = 'opacity 0.15s, width 0.15s, height 0.15s';
      }
      return;
    }

    const container = containerRef.current;
    const thumb = thumbRef.current;
    if (!container || !thumb) return;

    const state = dragState.current;
    state.isActive = true;
    
    // REMOVE transition during drag for instant response
    thumb.style.transition = 'none';

    const handleMouseMove = (e: MouseEvent) => {
      const mousePos = horizontal ? e.clientX : e.clientY;
      const deltaMouse = mousePos - state.startMouse;
      const scrollRatio = deltaMouse / state.trackSize;
      const newScroll = state.startScroll + (scrollRatio * state.maxScroll);
      const clampedScroll = Math.max(0, Math.min(newScroll, state.maxScroll));
      
      if (horizontal) {
        container.scrollLeft = clampedScroll;
        const visualRatio = state.maxScroll > 0 ? clampedScroll / state.maxScroll : 0;
        thumb.style.transform = `translateX(${visualRatio * state.trackSize}px)`;
      } else {
        container.scrollTop = clampedScroll;
        const visualRatio = state.maxScroll > 0 ? clampedScroll / state.maxScroll : 0;
        thumb.style.transform = `translateY(${visualRatio * state.trackSize}px)`;
      }
    };

    const handleMouseUp = () => {
      state.isActive = false;
      setIsDragging(false);
      // Transition will be restored by effect cleanup
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
      state.isActive = false;
    };
  }, [isDragging, horizontal]);

  const handleThumbMouseDown = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    
    const container = containerRef.current;
    const thumb = thumbRef.current;
    if (!container || !thumb) return;
    
    const state = dragState.current;
    
    if (horizontal) {
      state.startMouse = e.clientX;
      state.startScroll = container.scrollLeft;
      state.trackSize = container.clientWidth - thumbSize;
      state.maxScroll = container.scrollWidth - container.clientWidth;
    } else {
      state.startMouse = e.clientY;
      state.startScroll = container.scrollTop;
      state.trackSize = container.clientHeight - thumbSize;
      state.maxScroll = container.scrollHeight - container.clientHeight;
    }
    
    // Remove transition immediately on mouse down
    thumb.style.transition = 'none';
    setIsDragging(true);
  };

  const handleTrackClick = (e: React.MouseEvent) => {
    if (e.target === thumbRef.current) return;
    
    const container = containerRef.current;
    if (!container) return;
    
    const rect = container.getBoundingClientRect();
    
    if (horizontal) {
      const clickX = e.clientX - rect.left;
      const percentage = clickX / rect.width;
      container.scrollTo({
        left: percentage * (container.scrollWidth - container.clientWidth),
        behavior: 'smooth'
      });
    } else {
      const clickY = e.clientY - rect.top;
      const percentage = clickY / rect.height;
      container.scrollTo({
        top: percentage * (container.scrollHeight - container.clientHeight),
        behavior: 'smooth'
      });
    }
  };

  const isActive = isHoveringTrack || isDragging;
  const opacity = isActive ? 0.6 : (isHoveringContainer ? 0.2 : 0);
  const size = isActive ? '6px' : '2px';

  return (
    <div 
      className={`relative ${className}`}
      onMouseEnter={() => setIsHoveringContainer(true)}
      onMouseLeave={() => {
        setIsHoveringContainer(false);
        if (!isDragging) setIsHoveringTrack(false);
      }}
    >
      <div
        ref={containerRef}
        className="h-full w-full overflow-auto scrollbar-hide"
        style={{ 
          scrollbarWidth: 'none', 
          msOverflowStyle: 'none',
          overflowX: horizontal ? 'auto' : 'hidden',
          overflowY: horizontal ? 'hidden' : 'auto'
        }}
      >
        {children}
      </div>

      <div
        className={`absolute cursor-pointer z-10 ${horizontal ? 'bottom-0 left-0 right-0 h-4' : 'top-0 right-0 bottom-0 w-4'}`}
        style={{ opacity }}
        onMouseEnter={() => setIsHoveringTrack(true)}
        onMouseLeave={() => { if (!isDragging) setIsHoveringTrack(false); }}
        onClick={handleTrackClick}
      >
        <div
          ref={thumbRef}
          className="absolute rounded-full bg-zinc-400 cursor-grab active:cursor-grabbing"
          style={{
            [horizontal ? 'left' : 'top']: 0,
            [horizontal ? 'bottom' : 'right']: '4px',
            [horizontal ? 'width' : 'height']: thumbSize,
            [horizontal ? 'height' : 'width']: size,
            opacity: isActive ? 0.9 : 0.5,
            transition: 'opacity 0.15s, width 0.15s, height 0.15s',
            transform: horizontal ? 'translateX(0px)' : 'translateY(0px)',
            willChange: 'transform'
          }}
          onMouseDown={handleThumbMouseDown}
        />
      </div>

      <style>{`
        .scrollbar-hide::-webkit-scrollbar {
          display: none !important;
        }
      `}</style>
    </div>
  );
};
