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

interface ClicknHoldOptions {
  duration?: number;
  onComplete?: () => void;
  onStart?: () => void;
  onCancel?: () => void;
  onProgress?: (progress: number) => void;
  disabled?: boolean;
}

type EventHandlers = {
  onMouseDown: (event: React.MouseEvent) => void;
  onMouseUp: () => void;
  onMouseLeave: () => void;
  onTouchStart: (event: React.TouchEvent) => void;
  onTouchEnd: () => void;
  onKeyDown: (event: React.KeyboardEvent) => void;
  onKeyUp: (event: React.KeyboardEvent) => void;
}

export function useClicknHold({
  duration = 2000,
  onComplete,
  onStart,
  onCancel,
  onProgress,
  disabled = false
}: ClicknHoldOptions = {}) {
  const [isHolding, setIsHolding] = useState(false);
  const timerRef = useRef<number>();
  const startTimeRef = useRef<number>();

  const cleanup = useCallback(() => {
    if (timerRef.current) {
      window.clearInterval(timerRef.current);
      timerRef.current = undefined;
    }
    startTimeRef.current = undefined;
    setIsHolding(false);
  }, []);

  const startHolding = useCallback((event: React.MouseEvent | React.TouchEvent | React.KeyboardEvent) => {
    if ('preventDefault' in event) {
      event.preventDefault();
    }

    if (disabled) return;

    startTimeRef.current = Date.now();
    setIsHolding(true);
    onStart?.();

    timerRef.current = window.setInterval(() => {
      const elapsedTime = Date.now() - startTimeRef.current!;
      const progress = Math.min(elapsedTime / duration, 1);
      
      onProgress?.(progress);

      if (elapsedTime >= duration) {
        cleanup();
        onComplete?.();
      }
    }, 16);
  }, [duration, onComplete, onStart, onProgress, cleanup, disabled]);

  const stopHolding = useCallback(() => {
    if (isHolding) {
      cleanup();
      onCancel?.();
    }
  }, [isHolding, cleanup, onCancel]);

  const handleKeyDown = useCallback((event: React.KeyboardEvent) => {
    if (event.key === 'Enter' || event.key === ' ') {
      startHolding(event);
    }
  }, [startHolding]);

  const handleKeyUp = useCallback((event: React.KeyboardEvent) => {
    if (event.key === 'Enter' || event.key === ' ') {
      stopHolding();
    }
  }, [stopHolding]);

  useEffect(() => {
    return cleanup;
  }, [cleanup]);

  const handlers: EventHandlers = {
    onMouseDown: startHolding,
    onMouseUp: stopHolding,
    onMouseLeave: stopHolding,
    onTouchStart: startHolding,
    onTouchEnd: stopHolding,
    onKeyDown: handleKeyDown,
    onKeyUp: handleKeyUp,
  };

  return {
    isHolding,
    handlers,
    startHolding,
    stopHolding
  };
}





