/**
 * Composant ProgressBar
 * Barre de progression pour le player avec interaction drag et seek
 */

import React, { useState, useRef, useCallback, useEffect } from 'react';
import { calculateProgress } from '../services/playerService';
import { cn } from '@/lib/utils';

export interface ProgressBarProps {
  currentTime: number;
  duration: number;
  onSeek: (time: number) => void;
  className?: string;
  disabled?: boolean;
  showTooltip?: boolean;
}

export function ProgressBar({
  currentTime,
  duration,
  onSeek,
  className,
  disabled = false,
  showTooltip = true,
}: ProgressBarProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [hoverTime, setHoverTime] = useState<number | null>(null);
  const [tooltipPosition, setTooltipPosition] = useState(0);
  const progressBarRef = useRef<HTMLDivElement>(null);
  const progress = Math.min(100, calculateProgress(currentTime, duration));
  const displayProgress =
    isDragging && hoverTime !== null
      ? Math.min(100, calculateProgress(hoverTime, duration))
      : progress;

  const getTimeFromPosition = useCallback(
    (clientX: number): number => {
      if (!progressBarRef.current) return 0;

      const rect = progressBarRef.current.getBoundingClientRect();
      const x = clientX - rect.left;
      const percentage = Math.max(0, Math.min(1, x / rect.width));
      return percentage * duration;
    },
    [duration],
  );

  const handleMouseDown = useCallback(
    (e: React.MouseEvent<HTMLDivElement>) => {
      if (disabled) return;

      setIsDragging(true);
      const time = getTimeFromPosition(e.clientX);
      setHoverTime(time);
      onSeek(time);
    },
    [disabled, getTimeFromPosition, onSeek],
  );

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (!isDragging || disabled) return;

      const time = getTimeFromPosition(e.clientX);
      setHoverTime(time);
      onSeek(time);
    },
    [isDragging, disabled, getTimeFromPosition, onSeek],
  );

  const handleMouseUp = useCallback(() => {
    if (isDragging) {
      setIsDragging(false);
      setHoverTime(null);
    }
  }, [isDragging]);

  const handleMouseEnter = useCallback(
    (e: React.MouseEvent<HTMLDivElement>) => {
      if (disabled || !showTooltip) return;

      const time = getTimeFromPosition(e.clientX);
      setHoverTime(time);
    },
    [disabled, showTooltip, getTimeFromPosition],
  );

  const handleMouseMoveOver = useCallback(
    (e: React.MouseEvent<HTMLDivElement>) => {
      if (disabled || !showTooltip || isDragging) return;

      const time = getTimeFromPosition(e.clientX);
      setHoverTime(time);

      if (progressBarRef.current) {
        const rect = progressBarRef.current.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const percentage = Math.max(0, Math.min(1, x / rect.width));
        setTooltipPosition(percentage * 100);
      }
    },
    [disabled, showTooltip, isDragging, getTimeFromPosition],
  );

  const handleMouseLeave = useCallback(() => {
    if (!isDragging) {
      setHoverTime(null);
    }
  }, [isDragging]);

  useEffect(() => {
    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      return () => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
    }
    return undefined;
  }, [isDragging, handleMouseMove, handleMouseUp]);

  const formatTime = (seconds: number): string => {
    if (isNaN(seconds) || !isFinite(seconds) || seconds < 0) {
      return '0:00';
    }
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = Math.floor(seconds % 60);
    return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
  };

  const tooltipTime = hoverTime !== null ? hoverTime : currentTime;

  return (
    <div
      ref={progressBarRef}
      className={cn(
        'relative w-full h-2 group cursor-pointer',
        disabled && 'cursor-not-allowed opacity-50',
        className,
      )}
      onMouseDown={handleMouseDown}
      onMouseEnter={handleMouseEnter}
      onMouseMove={handleMouseMoveOver}
      onMouseLeave={handleMouseLeave}
      role="slider"
      aria-label="Progression de la lecture"
      aria-valuemin={0}
      aria-valuemax={duration}
      aria-valuenow={currentTime}
      aria-disabled={disabled}
    >
      {/* Background track */}
      <div className="absolute inset-0 bg-gray-200 dark:bg-gray-700 rounded-full" />

      {/* Progress track */}
      <div
        className={cn(
          'absolute left-0 top-0 h-full bg-blue-600 dark:bg-blue-500 rounded-full transition-all',
          isDragging && 'bg-blue-700 dark:bg-blue-600',
        )}
        style={{ width: `${displayProgress}%` }}
      />

      {/* Hover indicator */}
      {hoverTime !== null && !disabled && (
        <div
          className="absolute top-0 h-full w-0.5 bg-blue-800 dark:bg-blue-400 opacity-50"
          style={{ left: `${displayProgress}%` }}
        />
      )}

      {/* Thumb */}
      <div
        className={cn(
          'absolute top-1/2 -translate-y-1/2 w-4 h-4 bg-blue-600 dark:bg-blue-500 rounded-full',
          'opacity-0 group-hover:opacity-100 transition-opacity',
          isDragging && 'opacity-100',
          disabled && 'opacity-0',
        )}
        style={{ left: `calc(${displayProgress}% - 8px)` }}
      />

      {/* Tooltip */}
      {showTooltip && hoverTime !== null && !disabled && (
        <div
          className="absolute bottom-full mb-2 px-2 py-1 bg-gray-900 dark:bg-gray-800 text-white text-xs rounded pointer-events-none whitespace-nowrap"
          style={{
            left: `${tooltipPosition}%`,
            transform: 'translateX(-50%)',
          }}
        >
          {formatTime(tooltipTime)}
        </div>
      )}
    </div>
  );
}

export default ProgressBar;
