import React, { useState, useRef, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Play, Pause, Volume2, VolumeX, Maximize, Settings, PictureInPicture } from 'lucide-react';
import { Slider } from '../../ui/slider';
import { Button } from '../../ui/button';
import { FloatingMediaWrapper } from '../FloatingMediaWrapper';
import { cn } from '../../shared/utils';

export interface VideoPlayerProps {
  src: string;
  poster?: string;
  title?: string;
  autoPlay?: boolean;
  enableAutoFloat?: boolean;
  className?: string;
}

export function VideoPlayer({
  src,
  poster,
  title,
  autoPlay = false,
  enableAutoFloat = true,
  className,
}: VideoPlayerProps) {
  const { t } = useTranslation();
  const videoRef = useRef<HTMLVideoElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [isFloating, setIsFloating] = useState(false);
  const [isManualFloating, setIsManualFloating] = useState(false);
  const [showControls, setShowControls] = useState(true);
  const [enableAutoFloatLocal, setEnableAutoFloatLocal] = useState(enableAutoFloat);

  let controlsTimeout: NodeJS.Timeout;

  // Wrapper for setIsFloating to handle scroll-on-restore and sync state
  const handleSetFloating = (floating: boolean) => {
    if (videoRef.current) {
      setCurrentTime(videoRef.current.currentTime);
    }

    setIsFloating(floating);

    if (!floating) {
      setIsManualFloating(false);
    }
  };

  // Restore state when switching modes (remounting video element)
  useEffect(() => {
    const video = videoRef.current;
    if (video) {
      if (Math.abs(video.currentTime - currentTime) > 0.5) {
        video.currentTime = currentTime;
      }
      if (isPlaying) {
        const playPromise = video.play();
        if (playPromise !== undefined) {
          playPromise.catch(error => {
            console.log('Playback interrupted during switch:', error);
          });
        }
      }
    }
  }, [isFloating]);

  // Auto-float on scroll logic
  useEffect(() => {
    const container = containerRef.current;
    if (!container || !enableAutoFloatLocal) return;

    const observer = new IntersectionObserver(
      entries => {
        const entry = entries[0];
        if (!entry) return;

        if (isPlaying && !entry.isIntersecting && !isFloating) {
          if (videoRef.current) setCurrentTime(videoRef.current.currentTime);
          setIsFloating(true);
        } else if (entry.isIntersecting && isFloating && !isManualFloating) {
          if (videoRef.current) setCurrentTime(videoRef.current.currentTime);
          handleSetFloating(false);
        }
      },
      { threshold: 0.2 }
    );

    observer.observe(container);
    return () => observer.disconnect();
  }, [isPlaying, isFloating, isManualFloating, enableAutoFloatLocal]);

  // Video Event Listeners
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const updateTime = () => {
      setCurrentTime(video.currentTime);
    };

    const updateDuration = () => setDuration(video.duration);
    const onPlay = () => setIsPlaying(true);
    const onPause = () => setIsPlaying(false);

    video.addEventListener('timeupdate', updateTime);
    video.addEventListener('loadedmetadata', updateDuration);
    video.addEventListener('play', onPlay);
    video.addEventListener('pause', onPause);

    // Initial volume set
    video.volume = volume;
    video.muted = isMuted;

    return () => {
      video.removeEventListener('timeupdate', updateTime);
      video.removeEventListener('loadedmetadata', updateDuration);
      video.removeEventListener('play', onPlay);
      video.removeEventListener('pause', onPause);
    };
  }, [isFloating]); // Re-attach when element changes

  const togglePlay = () => {
    if (videoRef.current) {
      if (isPlaying) {
        videoRef.current.pause();
      } else {
        videoRef.current.play();
      }
    }
  };

  const handleSeek = (value: number[]) => {
    if (videoRef.current) {
      videoRef.current.currentTime = value[0];
      setCurrentTime(value[0]);
    }
  };

  const handleVolumeChange = (value: number[]) => {
    const newVolume = value[0];
    if (videoRef.current) {
      videoRef.current.volume = newVolume;
      setVolume(newVolume);
      setIsMuted(newVolume === 0);
    }
  };

  const toggleMute = () => {
    if (videoRef.current) {
      const newMutedState = !isMuted;
      videoRef.current.muted = newMutedState;
      setIsMuted(newMutedState);
      if (newMutedState) {
        setVolume(0);
      } else {
        setVolume(1);
        videoRef.current.volume = 1;
      }
    }
  };

  const handleMouseMove = () => {
    setShowControls(true);
    clearTimeout(controlsTimeout);
    controlsTimeout = setTimeout(() => {
      if (isPlaying) setShowControls(false);
    }, 2500);
  };

  const formatTime = (time: number) => {
    const minutes = Math.floor(time / 60);
    const seconds = Math.floor(time % 60);
    return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
  };

  return (
    <div ref={containerRef} className={className}>
      <FloatingMediaWrapper
        isFloating={isFloating}
        setIsFloating={handleSetFloating}
        onClose={() => handleSetFloating(false)}
        onCloseMedia={() => {
          setIsFloating(false);
          setEnableAutoFloatLocal(false);
        }}
        title={title || t('media.untitledVideo')}
        aspectRatio={16 / 9}
        className="w-full h-full"
        playerId="video-player"
      >
        <div
          className="relative w-full h-full bg-black group overflow-hidden"
          onMouseMove={handleMouseMove}
          onMouseLeave={() => isPlaying && setShowControls(false)}
        >
          <video
            ref={videoRef}
            src={src}
            poster={poster}
            className="w-full h-full object-contain"
            onClick={togglePlay}
            autoPlay={autoPlay}
            title={title || t('media.video')}
          />

          {!isPlaying && (
            <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
              <div className="w-16 h-16 rounded-full bg-black/40 backdrop-blur-sm flex items-center justify-center border border-white/20 shadow-2xl">
                <Play className="w-8 h-8 text-white ml-1" fill="white" />
              </div>
            </div>
          )}

          <div
            className={cn(
              'absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/60 via-black/30 to-transparent pt-12 pb-4 px-4 transition-opacity duration-300',
              showControls ? 'opacity-100' : 'opacity-0'
            )}
          >
            <div className="mb-4 group/slider">
              <Slider
                value={[currentTime]}
                max={duration || 100}
                step={1}
                onValueChange={handleSeek}
                className="cursor-pointer [&_[data-slot=slider-track]]:bg-white/30 [&_[data-slot=slider-range]]:bg-white [&_[data-slot=slider-thumb]]:bg-white [&_[data-slot=slider-thumb]]:border-white"
                aria-label={t('media.videoProgress')}
              />
            </div>

            <div className="flex items-center justify-between">
              <div className="flex items-center gap-4">
                <Button
                  variant="ghost"
                  size="icon"
                  className="text-white hover:text-white hover:bg-black/50 h-8 w-8"
                  onClick={togglePlay}
                  aria-label={isPlaying ? t('media.pause') : t('media.play')}
                >
                  {isPlaying ? (
                    <Pause className="w-5 h-5" fill="currentColor" />
                  ) : (
                    <Play className="w-5 h-5" fill="currentColor" />
                  )}
                </Button>

                <div className="flex items-center gap-2 group/vol">
                  <Button
                    variant="ghost"
                    size="icon"
                    className="text-white hover:text-white hover:bg-black/50 h-8 w-8"
                    onClick={toggleMute}
                    aria-label={isMuted || volume === 0 ? t('media.unmute') : t('media.mute')}
                  >
                    {isMuted || volume === 0 ? (
                      <VolumeX className="w-5 h-5" />
                    ) : (
                      <Volume2 className="w-5 h-5" />
                    )}
                  </Button>
                  <div className="w-0 overflow-hidden group-hover/vol:w-20 transition-all duration-300">
                    <Slider
                      value={[isMuted ? 0 : volume]}
                      max={1}
                      step={0.01}
                      onValueChange={handleVolumeChange}
                      className="w-20 [&_[data-slot=slider-track]]:bg-white/30 [&_[data-slot=slider-range]]:bg-white [&_[data-slot=slider-thumb]]:bg-white [&_[data-slot=slider-thumb]]:border-white"
                      aria-label={t('media.volume')}
                    />
                  </div>
                </div>

                <div className="text-white text-xs font-medium tabular-nums select-none drop-shadow-md">
                  {formatTime(currentTime)} / {formatTime(duration)}
                </div>
              </div>

              <div className="flex items-center gap-2">
                <Button
                  variant="ghost"
                  size="icon"
                  className="text-white hover:text-white hover:bg-black/50 h-8 w-8"
                  onClick={() => {
                    setEnableAutoFloatLocal(true);
                    if (!isFloating) setIsManualFloating(true);
                    handleSetFloating(!isFloating);
                  }}
                  title={isFloating ? t('media.restore') : t('media.popOut')}
                  aria-label={isFloating ? t('media.restore') : t('media.popOut')}
                >
                  {isFloating ? (
                    <Maximize className="w-4 h-4" />
                  ) : (
                    <PictureInPicture className="w-4 h-4" />
                  )}
                </Button>
              </div>
            </div>
          </div>
        </div>
      </FloatingMediaWrapper>
    </div>
  );
}
