import React, { useState, useEffect, useRef } from 'react';
import { ArrowLeft, FastForward, Keyboard, Maximize, Minimize, Pause, Play, Rewind, SkipBack, SkipForward, Volume2, VolumeX, X } from 'lucide-react';
import { formatTime } from '../lib/utils';

interface VideoPlayerProps {
  url: string;
  title?: string;
  poster?: string;
  startTime?: number;
  onClose?: () => void;
  onProgressUpdate?: (currentTime: number, duration: number) => void;
  onVideoEnded?: () => void;
  showNextButton?: boolean;
  contentRating?: { rating: string, description: string } | null;
  hideTitleInPlayer?: boolean;
  showControls?: boolean;
  containerRef?: React.RefObject<HTMLDivElement>;
  videoRef?: React.RefObject<HTMLVideoElement>;
  customOverlay?: React.ReactNode;
}

const VideoPlayer: React.FC<VideoPlayerProps> = ({
  url,
  title,
  poster,
  startTime = 0,
  onClose,
  onProgressUpdate,
  onVideoEnded,
  showNextButton = false,
  contentRating,
  hideTitleInPlayer = false,
  showControls: initialShowControls = true,
  containerRef,
  videoRef: externalVideoRef,
  customOverlay
}) => {
  const internalVideoRef = useRef<HTMLVideoElement>(null);
  const videoRef = externalVideoRef || internalVideoRef;

  const [isPlaying, setIsPlaying] = useState(false);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(false);
  const [progress, setProgress] = useState(startTime);
  const [duration, setDuration] = useState(0);
  const [showControls, setShowControls] = useState(initialShowControls);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [buffered, setBuffered] = useState(0);
  const [showRating, setShowRating] = useState(true);
  const [hoverTime, setHoverTime] = useState<number | null>(null);
  const [hoverPosition, setHoverPosition] = useState<{ x: number, y: number } | null>(null);
  const [showKeyboardControls, setShowKeyboardControls] = useState(false);
  const controlsTimerRef = useRef<NodeJS.Timeout | null>(null);
  const playerContainerRef = useRef<HTMLDivElement>(null);
  const progressBarRef = useRef<HTMLDivElement>(null);
  const ratingTimerRef = useRef<NodeJS.Timeout | null>(null);

  // Format time manually (in case utils import fails)
  const formatTimeBackup = (time: number): string => {
    const hours = Math.floor(time / 3600);
    const minutes = Math.floor((time % 3600) / 60);
    const seconds = Math.floor(time % 60);
    const minutesStr = minutes.toString().padStart(2, '0');
    const secondsStr = seconds.toString().padStart(2, '0');
    return hours > 0 ? `${hours}:${minutesStr}:${secondsStr}` : `${minutesStr}:${secondsStr}`;
  };
  // Hide content rating after a few seconds
  useEffect(() => {
    if (showRating && contentRating) {
      ratingTimerRef.current = setTimeout(() => {
        setShowRating(false);
      }, 8000);
    }

    return () => {
      if (ratingTimerRef.current) {
        clearTimeout(ratingTimerRef.current);
      }
    };
  }, [showRating, contentRating]);

  useEffect(() => {
    const videoElement = videoRef.current;

    if (videoElement) {
      const handleLoadedMetadata = () => {
        setDuration(videoElement.duration);
        videoElement.currentTime = startTime;
        setProgress(startTime);
      };

      const handleTimeUpdate = () => {
        setProgress(videoElement.currentTime);
        onProgressUpdate?.(videoElement.currentTime, videoElement.duration);
      };

      const handleEnded = () => {
        setIsPlaying(false);
        onVideoEnded?.();
      };

      const handleBufferUpdate = () => {
        if (videoElement.buffered.length > 0) {
          setBuffered(videoElement.buffered.end(videoElement.buffered.length - 1));
        }
      };

      videoElement.addEventListener('loadedmetadata', handleLoadedMetadata);
      videoElement.addEventListener('timeupdate', handleTimeUpdate);
      videoElement.addEventListener('ended', handleEnded);
      videoElement.addEventListener('progress', handleBufferUpdate);

      return () => {
        videoElement.removeEventListener('loadedmetadata', handleLoadedMetadata);
        videoElement.removeEventListener('timeupdate', handleTimeUpdate);
        videoElement.removeEventListener('ended', handleEnded);
        videoElement.removeEventListener('progress', handleBufferUpdate);
      };
    }
  }, [url, startTime, onProgressUpdate, onVideoEnded, videoRef]);

  useEffect(() => {
    if (isPlaying) {
      videoRef.current?.play();
    } else {
      videoRef.current?.pause();
    }
  }, [isPlaying, videoRef]);

  useEffect(() => {
    if (videoRef.current) {
      videoRef.current.volume = isMuted ? 0 : volume;
    }
  }, [volume, isMuted, videoRef]);

  const hideControlsTimer = () => {
    if (controlsTimerRef.current) {
      clearTimeout(controlsTimerRef.current);
    }

    controlsTimerRef.current = setTimeout(() => {
      if (isPlaying && !showKeyboardControls) {
        setShowControls(false);
      }
    }, 3000);
  };

  const handleMouseMove = () => {
    setShowControls(true);
    hideControlsTimer();
  };

  useEffect(() => {
    hideControlsTimer();
    return () => {
      if (controlsTimerRef.current) {
        clearTimeout(controlsTimerRef.current);
      }
    };
  }, [isPlaying, showKeyboardControls]);

  // Keyboard controls
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      switch (e.key) {
        case ' ':
        case 'k':
          e.preventDefault();
          setIsPlaying(prev => !prev);
          setShowControls(true);
          break;
        case 'ArrowRight':
          e.preventDefault();
          skipForward();
          setShowControls(true);
          break;
        case 'ArrowLeft':
          e.preventDefault();
          skipBackward();
          setShowControls(true);
          break;
        case 'f':
          e.preventDefault();
          toggleFullscreen();
          break;
        case 'm':
          e.preventDefault();
          setIsMuted(prev => !prev);
          setShowControls(true);
          break;
        case '?':
          e.preventDefault();
          setShowKeyboardControls(prev => !prev);
          setShowControls(true);
          break;
        case 'Escape':
          if (showKeyboardControls) {
            setShowKeyboardControls(false);
          } else if (isFullscreen) {
            document.exitFullscreen();
          } else if (onClose) {
            onClose();
          }
          break;
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [isFullscreen, onClose, showKeyboardControls]);

  // Fullscreen handlers
  useEffect(() => {
    const handleFullScreenChange = () => {
      setIsFullscreen(document.fullscreenElement === (containerRef?.current || playerContainerRef.current));
    };

    document.addEventListener('fullscreenchange', handleFullScreenChange);
    return () => document.removeEventListener('fullscreenchange', handleFullScreenChange);
  }, [containerRef]);

  const toggleFullscreen = async () => {
    const fullscreenElement = containerRef?.current || playerContainerRef.current;
    if (!fullscreenElement) return;

    if (!isFullscreen) {
      await fullscreenElement.requestFullscreen();
    } else {
      await document.exitFullscreen();
    }
  };

  // Player control handlers
  const handlePlayPause = () => {
    setIsPlaying(!isPlaying);
  };

  const handleMute = () => {
    setIsMuted(!isMuted);
  };

  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newVolume = parseFloat(e.target.value);
    setVolume(newVolume);
    if (newVolume === 0) {
      setIsMuted(true);
    } else if (isMuted) {
      setIsMuted(false);
    }
  };

  const handleProgressChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newTime = parseFloat(e.target.value);
    setProgress(newTime);
    if (videoRef.current) {
      videoRef.current.currentTime = newTime;
    }
  };

  // Direct progress bar click handler
  const handleProgressBarClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!progressBarRef.current || !duration) return;

    const rect = progressBarRef.current.getBoundingClientRect();
    const clickPosition = (e.clientX - rect.left) / rect.width;
    const newTime = duration * clickPosition;

    if (videoRef.current) {
      videoRef.current.currentTime = newTime;
      setProgress(newTime);
    }
  };

  // Progress bar hover handler for time preview
  const handleProgressBarHover = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!progressBarRef.current || !duration) return;

    const rect = progressBarRef.current.getBoundingClientRect();
    const hoverPosition = (e.clientX - rect.left) / rect.width;
    const hoverTimeValue = duration * hoverPosition;

    setHoverTime(hoverTimeValue);
    setHoverPosition({ x: e.clientX, y: rect.top });
  };

  const handleProgressBarLeave = () => {
    setHoverTime(null);
    setHoverPosition(null);
  };

  // Use the imported formatTime function with a fallback
  const formatTimeDisplay = formatTime || formatTimeBackup;

  const skipForward = () => {
    if (videoRef.current) {
      videoRef.current.currentTime = Math.min(
        videoRef.current.duration,
        videoRef.current.currentTime + 10
      );
    }
  };

  const skipBackward = () => {
    if (videoRef.current) {
      videoRef.current.currentTime = Math.max(
        0,
        videoRef.current.currentTime - 10
      );
    }
  };

  const toggleKeyboardControls = () => {
    setShowKeyboardControls(prev => !prev);
    setShowControls(true);
  };

  return (
    <div
      className="w-full h-full overflow-hidden bg-black"
      ref={playerContainerRef}
      onMouseMove={handleMouseMove}
    >
      {/* Content rating overlay - only shown briefly */}
      {contentRating && showRating && (
        <div className="absolute top-16 left-6 z-40 bg-black/60 backdrop-blur-sm px-4 py-2 rounded text-white flex items-center gap-2 animate-fade-in">
          <div className="text-lg font-bold border px-2 py-0.5">
            {contentRating.rating}
          </div>
          <span className='font-extrabold text-2xl text-primary'>|</span>
          <div className="text-sm">
            {contentRating.description}
          </div>
        </div>
      )}

      <video
        ref={videoRef}
        src={url}
        className="w-full h-full object-contain"
        poster={poster}
        onClick={handlePlayPause}
        playsInline
      />

      {/* Custom overlay from parent components */}
      {customOverlay}

      {/* Controls overlay - visible based on state */}
      <div
        className={`absolute inset-0 transition-opacity duration-300 ${showControls ? 'opacity-100' : 'opacity-0 pointer-events-none'
          }`}
      >
        {/* Top bar */}
        <div className="absolute top-0 left-0 right-0 p-4 bg-gradient-to-b from-black/80 to-transparent z-10">
          <div className="flex justify-between items-center">
            <button
              onClick={onClose}
              className="text-white hover:text-gray-300 transition-colors"
            >
              <ArrowLeft size={24} />
            </button>
            {!hideTitleInPlayer && (
              <h2 className="text-white font-medium text-lg hidden sm:block">
                {title}
              </h2>
            )}
            <button
              onClick={onClose}
              className="text-white hover:text-gray-300 transition-colors"
            >
              <X size={24} />
            </button>
          </div>
        </div>

        {/* Center controls */}
        <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
          {/* Skip backward 10s */}
          <button
            onClick={skipBackward}
            className="z-10 relative pointer-events-auto text-white hover:text-gray-300 transition-colors p-2 rounded-full hover:bg-black/30 mx-4"
          >
            <Rewind size={32} />
          </button>

          {/* Play/Pause button */}
          <button
            onClick={handlePlayPause}
            className="text-white bg-black/30 backdrop-blur-sm p-4 rounded-full hover:bg-white/20 transition-all pointer-events-auto relative w-20 h-20 flex items-center justify-center"
          >
            {isPlaying ? (
              <Pause size={40} />
            ) : (
              <Play size={40} />
            )}
          </button>

          {/* Skip forward 10s */}
          <button
            onClick={skipForward}
            className="z-10 relative pointer-events-auto text-white hover:text-gray-300 transition-colors p-2 rounded-full hover:bg-black/30 mx-4"
          >
            <FastForward size={32} />
          </button>
        </div>

        {/* Bottom controls */}
        <div className="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/80 to-transparent">
          {/* Progress bar */}
          <div className="mb-3 relative">
            <div
              ref={progressBarRef}
              className="relative w-full h-2 bg-white/30 rounded-full group cursor-pointer"
              onClick={handleProgressBarClick}
              onMouseMove={handleProgressBarHover}
              onMouseLeave={handleProgressBarLeave}
            >
              {/* Buffered progress */}
              <div
                className="absolute h-full bg-white/50 rounded-full"
                style={{ width: `${(buffered / duration) * 100}%` }}
              ></div>

              {/* Played progress */}
              <div
                className="absolute h-full bg-primary rounded-full"
                style={{ width: `${(progress / duration) * 100}%` }}
              >
                {/* Thumb */}
                <div className="absolute right-0 top-1/2 transform -translate-y-1/2 w-4 h-4 bg-primary rounded-full scale-0 group-hover:scale-100 transition-transform"></div>
              </div>

              {/* Time preview tooltip */}
              {hoverTime !== null && hoverPosition && (
                <div
                  className="absolute -top-8 bg-black/80 px-2 py-1 rounded text-white text-xs transform -translate-x-1/2 pointer-events-none"
                  style={{ left: `${(hoverTime / duration) * 100}%` }}
                >
                  {formatTimeDisplay(hoverTime)}
                </div>
              )}

              {/* Invisible range input for seeking */}
              <input
                type="range"
                min={0}
                max={duration || 100}
                value={progress}
                onChange={handleProgressChange}
                className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
                style={{ padding: 0, margin: 0 }}
              />
            </div>

            <div className="flex justify-between text-xs text-white mt-1">
              <span>{formatTimeDisplay(progress)}</span>
              <span>{formatTimeDisplay(duration)}</span>
            </div>
          </div>

          {/* Controls row */}
          <div className="flex justify-between items-center">
            <div className="flex items-center space-x-4">
              <button
                onClick={handlePlayPause}
                className="text-white hover:text-gray-300 transition-colors"
              >
                {isPlaying ? <Pause size={24} /> : <Play size={24} />}
              </button>

              <div className="flex items-center relative group">
                <button
                  onClick={handleMute}
                  className="text-white hover:text-gray-300 transition-colors"
                >
                  {isMuted || volume === 0 ? <VolumeX size={24} /> : <Volume2 size={24} />}
                </button>

                <div className="hidden group-hover:block w-20 ml-2">
                  <input
                    type="range"
                    min={0}
                    max={1}
                    step={0.1}
                    value={volume}
                    onChange={handleVolumeChange}
                    className="w-full h-1 bg-gray-700/50 appearance-none rounded cursor-pointer accent-primary"
                  />
                </div>
              </div>

              <button
                onClick={toggleKeyboardControls}
                className="text-white hover:text-gray-300 transition-colors"
                title="Show keyboard shortcuts"
              >
                <Keyboard size={20} />
              </button>
            </div>

            <div className="flex items-center space-x-4">
              {!hideTitleInPlayer && title && (
                <div className="text-white text-sm hidden sm:block">
                  <span>{title}</span>
                </div>
              )}

              <button
                onClick={toggleFullscreen}
                className="text-white hover:text-gray-300 transition-colors"
              >
                {isFullscreen ? <Minimize size={24} /> : <Maximize size={24} />}
              </button>

              {showNextButton && (
                <button
                  onClick={onVideoEnded}
                  className="text-white hover:text-gray-300 transition-colors"
                >
                  <SkipForward size={24} />
                </button>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* Keyboard controls dialog - shown only when requested */}
      {showKeyboardControls && (
        <div className="absolute inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center z-50" onClick={() => setShowKeyboardControls(false)}>
          <div className="bg-gray-900/90 border border-gray-700 rounded-lg max-w-md w-full p-6" onClick={e => e.stopPropagation()}>
            <div className="flex justify-between items-center mb-4">
              <h3 className="text-xl font-bold text-white">Keyboard Controls</h3>
              <button onClick={() => setShowKeyboardControls(false)} className="text-gray-400 hover:text-white">
                <X size={20} />
              </button>
            </div>

            <div className="grid grid-cols-2 gap-y-3 text-sm">
              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">Space</kbd> or <kbd className="px-2 py-1 bg-gray-800 rounded mx-2">K</kbd>
              </div>
              <div>Play/Pause</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">←</kbd>
              </div>
              <div>Rewind 10 seconds</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">→</kbd>
              </div>
              <div>Forward 10 seconds</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">M</kbd>
              </div>
              <div>Mute/Unmute</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">F</kbd>
              </div>
              <div>Fullscreen</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">Esc</kbd>
              </div>
              <div>Exit fullscreen/Close player</div>

              <div className="flex items-center">
                <kbd className="px-2 py-1 bg-gray-800 rounded mr-2">?</kbd>
              </div>
              <div>Show/hide this menu</div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default VideoPlayer;
