import { useEffect, useRef, useState } from "react";
import { X, Share2, Edit3, Play, Pause, Volume2, VolumeX, Maximize } from "lucide-react";
import { type Video } from "@shared/schema";
import { Button } from "@/components/ui/button";
import { apiRequest } from "@/lib/queryClient";
import Hls from "hls.js";
import { 
  FacebookIcon,
  TwitterIcon,
  WhatsappIcon
} from "react-share";

import QualityIndicator from "./quality-indicator";
import VASTPlayer from "./vast-player";

// HLS.js types for video streaming

interface VideoModalProps {
  video: Video | null;
  isOpen: boolean;
  onClose: () => void;
  enableAds?: boolean;
}

function formatDuration(seconds: number): string {
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = seconds % 60;
  return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}

function formatViews(views: number): string {
  if (views >= 1000000) {
    return `${(views / 1000000).toFixed(1)}M views`;
  } else if (views >= 1000) {
    return `${(views / 1000).toFixed(1)}K views`;
  }
  return `${views} views`;
}

function formatDate(date: Date | string): string {
  const now = new Date();
  const createdDate = typeof date === 'string' ? new Date(date) : date;
  
  if (!createdDate || isNaN(createdDate.getTime())) {
    return "Unknown";
  }
  
  const diffTime = Math.abs(now.getTime() - createdDate.getTime());
  const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
  
  if (diffDays === 0) return "Today";
  if (diffDays === 1) return "1 day ago";
  if (diffDays < 7) return `${diffDays} days ago`;
  if (diffDays < 30) return `${Math.floor(diffDays / 7)} week${Math.floor(diffDays / 7) > 1 ? 's' : ''} ago`;
  return `${Math.floor(diffDays / 30)} month${Math.floor(diffDays / 30) > 1 ? 's' : ''} ago`;
}

export default function VideoModal({ video, isOpen, onClose, enableAds = true }: VideoModalProps) {
  const [useVASTPlayer, setUseVASTPlayer] = useState(true);
  const videoRef = useRef<HTMLVideoElement>(null);
  const hlsRef = useRef<Hls | null>(null);
  const [showShareMenu, setShowShareMenu] = useState(false);

  const [videoThumbnail, setVideoThumbnail] = useState<string | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [isMuted, setIsMuted] = useState(false);
  const [showControls, setShowControls] = useState(true);
  const [controlsTimeout, setControlsTimeout] = useState<NodeJS.Timeout | null>(null);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [volume, setVolume] = useState(1);
  const [hoverTime, setHoverTime] = useState(-1);
  
  // All hooks must be declared before any conditional returns
  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === "Escape" && isOpen) {
        onClose();
      }
    };

    if (isOpen) {
      document.addEventListener("keydown", handleEscape);
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "";
    }

    return () => {
      document.removeEventListener("keydown", handleEscape);
      document.body.style.overflow = "";
    };
  }, [isOpen, onClose]);
  
  // Switch to VAST player for monetization
  if (isOpen && video && useVASTPlayer && enableAds) {
    return <VASTPlayer video={video} onClose={onClose} enableAds={enableAds} />;
  }

  // Initialize HLS when video is available
  useEffect(() => {
    if (isOpen && video && videoRef.current) {
      const videoElement = videoRef.current;
      
      // Clean up previous HLS instance
      if (hlsRef.current) {
        hlsRef.current.destroy();
        hlsRef.current = null;
      }

      const videoUrl = video.videoUrl;
      console.log('Loading video with HLS.js:', videoUrl);

      // Check if the video URL is HLS (.m3u8)
      if (videoUrl.includes('.m3u8')) {
        if (Hls.isSupported()) {
          // Use HLS.js for browsers that don't support HLS natively
          const hls = new Hls({
            debug: false,
            enableWorker: false,
            lowLatencyMode: false,
            // Adaptive bitrate settings for optimal streaming
            startLevel: -1, // Auto-select starting quality based on bandwidth
            capLevelToPlayerSize: true, // Limit quality to actual player size
            maxLoadingDelay: 4,
            maxBufferLength: 30, // Keep 30 seconds buffered
            maxBufferSize: 60 * 1000 * 1000, // 60MB buffer
            maxBufferHole: 0.5,
            // Network adaptive settings  
            abrEwmaFastLive: 3,
            abrEwmaSlowLive: 9,
            abrEwmaFastVoD: 3,
            abrEwmaSlowVoD: 9,
            abrMaxWithRealBitrate: false,
            abrBandWidthFactor: 0.95, // Conservative bandwidth usage
            abrBandWidthUpFactor: 0.7, // Slower quality upgrades
            // Fragment loading settings
            fragLoadingTimeOut: 20000,
            manifestLoadingTimeOut: 10000,
            levelLoadingTimeOut: 10000,
            // Start with lower quality for faster initial load
            testBandwidth: false
          });
          
          hls.loadSource(videoUrl);
          hls.attachMedia(videoElement);
          
          hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
            console.log('HLS manifest loaded - Available qualities:', 
              data.levels.map(l => `${l.height}p @ ${Math.round(l.bitrate/1000)}kbps`));
            
            // Log bitrate analysis
            console.log('BITRATE ANALIZA:');
            data.levels.forEach((level, index) => {
              console.log(`Nivo ${index}: ${level.width}x${level.height} @ ${Math.round(level.bitrate/1000)}kbps`);
            });
            
            // Set initial quality based on connection
            const connection = (navigator as any).connection;
            if (connection) {
              const effectiveType = connection.effectiveType;
              const downlink = connection.downlink; // Mbps
              console.log(`Omrežje: ${effectiveType}, hitrost: ${downlink} Mbps`);
              
              // More aggressive quality selection for slow connections
              if (effectiveType === 'slow-2g' || effectiveType === '2g' || downlink < 1) {
                hls.startLevel = 0; // Lowest quality
                console.log('Nastavljam najnižjo kakovost zaradi počasne povezave');
              } else if (effectiveType === '3g' || downlink < 3) {
                hls.startLevel = Math.min(1, data.levels.length - 1);
                console.log('Nastavljam nizko kakovost zaradi 3G povezave');
              }
            }
          });
          
          // Quality level monitoring with detailed stats
          hls.on(Hls.Events.LEVEL_SWITCHED, (event, data) => {
            const level = hls.levels[data.level];
            console.log(`PREKLOPIL KAKOVOST: ${level.height}p @ ${Math.round(level.bitrate/1000)}kbps`);
            console.log('Razlog preklopa: adaptivni algoritem na podlagi omrežne hitrosti');
          });

          // Fragment loading stats - fixed error handling
          hls.on(Hls.Events.FRAG_LOADED, (event, data) => {
            try {
              if (data.frag && data.frag.stats) {
                const stats = data.frag.stats;
                const loadTime = stats.loading.end - stats.loading.start;
                const speed = (stats.total * 8) / loadTime; // bits per ms = kbps
                console.log(`Fragment naložen v ${loadTime}ms, hitrost: ${Math.round(speed)} kbps`);
              }
            } catch (error) {
              // Ignore stats errors, they don't affect playback
            }
          });

          // Buffer monitoring for dynamic adjustment
          hls.on(Hls.Events.BUFFER_APPENDING, () => {
            const buffered = videoElement.buffered;
            if (buffered.length > 0) {
              const bufferLevel = buffered.end(buffered.length - 1) - videoElement.currentTime;
              if (bufferLevel < 2) {
                console.log('Nizek buffer zaznan, lahko zmanjšam kakovost');
              }
            }
          });

          // Network error handling with retries
          hls.on(Hls.Events.ERROR, (event, data) => {
            console.error('HLS napaka:', data);
            if (data.fatal) {
              switch (data.type) {
                case Hls.ErrorTypes.NETWORK_ERROR:
                  console.log('Omrežna napaka, poskušam obnoviti...');
                  // Try to downgrade quality first
                  if (hls.currentLevel > 0) {
                    hls.currentLevel = hls.currentLevel - 1;
                    console.log('Zmanjšujem kakovost zaradi omrežnih težav');
                  }
                  hls.startLoad();
                  break;
                case Hls.ErrorTypes.MEDIA_ERROR:
                  console.log('Medijska napaka, poskušam obnoviti...');
                  hls.recoverMediaError();
                  break;
                default:
                  console.log('Kritična napaka, uničujem HLS instanco...');
                  hls.destroy();
                  break;
              }
            }
          });
          
          hlsRef.current = hls;
        } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
          // For Safari that supports HLS natively
          videoElement.src = videoUrl;
          console.log('Using native HLS support');
        } else {
          console.error('HLS is not supported in this browser');
        }
      } else {
        // For regular MP4 videos
        videoElement.src = videoUrl;
        console.log('Using native video support for MP4');
      }

      // Video event listeners
      videoElement.addEventListener('loadeddata', () => {
        console.log('Video data loaded, capturing thumbnail');
        setTimeout(() => captureVideoThumbnail(), 1000);
      });

      videoElement.addEventListener('canplay', () => {
        console.log('Video can play, capturing thumbnail');
        captureVideoThumbnail();
      });

      videoElement.addEventListener('play', () => setIsPlaying(true));
      videoElement.addEventListener('pause', () => setIsPlaying(false));
      videoElement.addEventListener('volumechange', () => {
        setIsMuted(videoElement.muted);
        setVolume(videoElement.volume);
      });
      videoElement.addEventListener('timeupdate', () => setCurrentTime(videoElement.currentTime));
      videoElement.addEventListener('loadedmetadata', () => setDuration(videoElement.duration));
      videoElement.addEventListener('durationchange', () => setDuration(videoElement.duration));
    }

    // Cleanup when modal closes
    return () => {
      if (hlsRef.current) {
        hlsRef.current.destroy();
        hlsRef.current = null;
      }
    };
  }, [isOpen, video]);

  // Function to capture video thumbnail
  const captureVideoThumbnail = () => {
    try {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const videoElement = videoRef.current;
      
      if (videoElement && ctx && videoElement.videoWidth > 0) {
        canvas.width = videoElement.videoWidth;
        canvas.height = videoElement.videoHeight;
        
        ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
        const thumbnailUrl = canvas.toDataURL('image/jpeg', 0.8);
        setVideoThumbnail(thumbnailUrl);
        console.log('Video thumbnail captured successfully', canvas.width, 'x', canvas.height);
      } else {
        console.log('Video element not ready for thumbnail capture');
        // Retry after a delay
        setTimeout(() => captureVideoThumbnail(), 1000);
      }
    } catch (error) {
      console.log('Failed to capture video thumbnail:', error);
    }
  };



  const handleVideoPlay = async () => {
    if (video) {
      try {
        await apiRequest("POST", `/api/videos/${video.id}/view`);
      } catch (error) {
        console.error("Failed to track video view:", error);
      }
    }
  };

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

  const toggleMute = () => {
    if (videoRef.current) {
      videoRef.current.muted = !videoRef.current.muted;
    }
  };

  const toggleFullscreen = () => {
    if (videoRef.current) {
      if (document.fullscreenElement) {
        document.exitFullscreen();
      } else {
        videoRef.current.requestFullscreen();
      }
    }
  };

  const showControlsTemporarily = () => {
    setShowControls(true);
    if (controlsTimeout) {
      clearTimeout(controlsTimeout);
    }
    const timeout = setTimeout(() => {
      setShowControls(false);
    }, 3000);
    setControlsTimeout(timeout);
  };

  useEffect(() => {
    return () => {
      if (controlsTimeout) {
        clearTimeout(controlsTimeout);
      }
    };
  }, [controlsTimeout]);

  const getShareUrl = () => {
    if (!video?.id) return window.location.origin;
    return `${window.location.origin}?video=${video.id}`;
  };

  const handleProgressClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (videoRef.current && duration > 0) {
      const rect = e.currentTarget.getBoundingClientRect();
      const clickX = e.clientX - rect.left;
      const newTime = (clickX / rect.width) * duration;
      videoRef.current.currentTime = newTime;
      setCurrentTime(newTime);
    }
  };

  const handleProgressHover = (e: React.MouseEvent<HTMLDivElement>) => {
    if (duration > 0) {
      const rect = e.currentTarget.getBoundingClientRect();
      const hoverX = e.clientX - rect.left;
      const time = (hoverX / rect.width) * duration;
      setHoverTime(Math.max(0, Math.min(duration, time)));
    }
  };

  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newVolume = parseFloat(e.target.value);
    if (videoRef.current) {
      videoRef.current.volume = newVolume;
      setVolume(newVolume);
      setIsMuted(newVolume === 0);
    }
  };

  const formatTime = (time: number): string => {
    const minutes = Math.floor(time / 60);
    const seconds = Math.floor(time % 60);
    return `${minutes}:${seconds.toString().padStart(2, '0')}`;
  };

  const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(getShareUrl());
      // Simple notification instead of alert
      const notification = document.createElement('div');
      notification.textContent = 'Link copied!';
      notification.className = 'fixed top-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg z-50 transition-opacity duration-300';
      document.body.appendChild(notification);
      setTimeout(() => {
        notification.style.opacity = '0';
        setTimeout(() => document.body.removeChild(notification), 300);
      }, 2000);
      setShowShareMenu(false);
    } catch (error) {
      console.error('Failed to copy link:', error);
      // Fallback for older browsers
      const textArea = document.createElement('textarea');
      textArea.value = getShareUrl();
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand('copy');
      document.body.removeChild(textArea);
      setShowShareMenu(false);
    }
  };

  const handleBackdropClick = (e: React.MouseEvent) => {
    if (e.target === e.currentTarget) {
      onClose();
    }
    // Close share menu when clicking outside
    setShowShareMenu(false);
  };

  if (!isOpen || !video) return null;

  return (
    <div 
      className="fixed inset-0 bg-black/90 backdrop-blur-sm z-50 flex items-center justify-center p-4"
      onClick={handleBackdropClick}
      data-testid="modal-video"
    >
      <div className="relative w-full max-w-6xl">
        <Button
          variant="ghost"
          size="icon"
          onClick={onClose}
          className="absolute -top-12 right-0 text-white hover:text-bunny-blue transition-colors z-60"
          data-testid="button-close-modal"
        >
          <X className="text-2xl" />
        </Button>
        
        <div className="relative bg-black rounded-lg overflow-hidden">
          <div 
            className="relative flex items-center justify-center bg-black"
            onMouseMove={showControlsTemporarily}
            onMouseEnter={() => setShowControls(true)}
            onMouseLeave={() => setShowControls(false)}
          >
            <video
              ref={videoRef}
              className="w-full h-auto max-h-[80vh] cursor-pointer"
              preload="metadata"
              controls={false}
              onPlay={handleVideoPlay}
              data-testid="video-player"
              crossOrigin="anonymous"
              onClick={togglePlay}
            >
            Your browser does not support the video tag.
          </video>
          
          {/* Central Play/Pause Button */}
          {showControls && (
            <div className="absolute inset-0 flex items-center justify-center">
              <Button
                onClick={togglePlay}
                variant="ghost"
                size="icon"
                className={`rounded-full bg-black/50 hover:bg-black/70 text-white border-2 border-white/20 hover:border-white/40 transition-all duration-200 ${
                  isPlaying ? 'w-16 h-16 opacity-0 hover:opacity-100' : 'w-20 h-20 opacity-100'
                }`}
                data-testid="button-play-center"
              >
                {isPlaying ? <Pause className="w-6 h-6" /> : <Play className="w-8 h-8 ml-1" />}
              </Button>
            </div>
          )}

          {/* Bottom Control Bar */}
          {showControls && (
            <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/90 via-black/70 to-transparent p-4">
              {/* Progress Bar */}
              <div className="mb-3">
                <div 
                  className="w-full h-2 bg-white/20 rounded-full cursor-pointer hover:h-3 transition-all duration-200 relative"
                  onClick={handleProgressClick}
                  onMouseMove={handleProgressHover}
                  onMouseLeave={() => setHoverTime(-1)}
                  data-testid="progress-bar"
                >
                  <div 
                    className="h-full bg-blue-500 rounded-full transition-all duration-200"
                    style={{ width: `${duration > 0 ? (currentTime / duration) * 100 : 0}%` }}
                  />
                  
                  {/* Time tooltip on hover */}
                  {hoverTime >= 0 && (
                    <div 
                      className="absolute -top-8 bg-black/80 text-white text-xs px-2 py-1 rounded pointer-events-none"
                      style={{ left: `${(hoverTime / duration) * 100}%`, transform: 'translateX(-50%)' }}
                    >
                      {formatTime(hoverTime)}
                    </div>
                  )}
                </div>
              </div>

              <div className="flex items-center gap-4">
                {/* Play/Pause Button */}
                <Button
                  onClick={togglePlay}
                  variant="ghost"
                  size="icon"
                  className="text-white hover:text-bunny-blue transition-colors"
                  data-testid="button-play-pause"
                >
                  {isPlaying ? <Pause className="w-5 h-5" /> : <Play className="w-5 h-5" />}
                </Button>

                {/* Volume Control */}
                <div className="flex items-center gap-2">
                  <Button
                    onClick={toggleMute}
                    variant="ghost"
                    size="icon"
                    className="text-white hover:text-bunny-blue transition-colors"
                    data-testid="button-volume"
                  >
                    {isMuted ? <VolumeX className="w-5 h-5" /> : <Volume2 className="w-5 h-5" />}
                  </Button>
                  <input
                    type="range"
                    min="0"
                    max="1"
                    step="0.1"
                    value={isMuted ? 0 : volume}
                    onChange={handleVolumeChange}
                    className="w-16 h-1 bg-white/20 rounded-lg appearance-none cursor-pointer slider"
                    data-testid="volume-slider"
                  />
                </div>

                {/* Time Display */}
                <div className="text-white text-sm font-mono" data-testid="time-display">
                  {formatTime(currentTime)} / {formatTime(duration)}
                </div>

                {/* Share Button */}
                <div className="relative">
                  <Button
                    onClick={() => setShowShareMenu(!showShareMenu)}
                    variant="ghost"
                    size="icon"
                    className="text-white hover:text-bunny-blue transition-colors"
                    data-testid="button-share"
                  >
                    <Share2 className="w-5 h-5" />
                  </Button>
                  
                  {/* Share Menu */}
                  {showShareMenu && (
                    <div className="absolute bottom-12 right-0 bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 z-50 min-w-[200px]">
                      <div className="flex flex-col gap-2">
                        <div className="pb-2 border-b border-gray-200 dark:border-gray-600">
                          <span className="text-sm font-medium text-gray-900 dark:text-gray-100">Share Video</span>
                        </div>
                        
                        <div
                          onClick={() => {
                            window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(getShareUrl())}`, '_blank', 'width=600,height=400');
                            setShowShareMenu(false);
                          }}
                          className="flex items-center gap-2 p-2 w-full hover:bg-gray-100 dark:hover:bg-gray-700 rounded cursor-pointer"
                        >
                          <FacebookIcon size={20} round />
                          <span className="text-sm text-gray-900 dark:text-gray-100">Facebook</span>
                        </div>
                        
                        <div
                          onClick={() => {
                            window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(getShareUrl())}&text=${encodeURIComponent(`Watch "${video.title}" on go4.video`)}`, '_blank', 'width=600,height=400');
                            setShowShareMenu(false);
                          }}
                          className="flex items-center gap-2 p-2 w-full hover:bg-gray-100 dark:hover:bg-gray-700 rounded cursor-pointer"
                        >
                          <TwitterIcon size={20} round />
                          <span className="text-sm text-gray-900 dark:text-gray-100">Twitter</span>
                        </div>
                        
                        <div
                          onClick={() => {
                            window.open(`https://wa.me/?text=${encodeURIComponent(`Watch "${video.title}" on go4.video: ${getShareUrl()}`)}`, '_blank');
                            setShowShareMenu(false);
                          }}
                          className="flex items-center gap-2 p-2 w-full hover:bg-gray-100 dark:hover:bg-gray-700 rounded cursor-pointer"
                        >
                          <WhatsappIcon size={20} round />
                          <span className="text-sm text-gray-900 dark:text-gray-100">WhatsApp</span>
                        </div>
                        
                        <button
                          onClick={copyToClipboard}
                          className="flex items-center gap-2 p-2 w-full hover:bg-gray-100 dark:hover:bg-gray-700 rounded cursor-pointer text-left"
                        >
                          <div className="w-5 h-5 bg-gray-500 rounded-full flex items-center justify-center">
                            <span className="text-white text-xs">📋</span>
                          </div>
                          <span className="text-sm text-gray-900 dark:text-gray-100">Copy Link</span>
                        </button>
                      </div>
                    </div>
                  )}
                </div>

                {/* Fullscreen Button */}
                <Button
                  onClick={toggleFullscreen}
                  variant="ghost"
                  size="icon"
                  className="text-white hover:text-bunny-blue transition-colors ml-auto"
                  data-testid="button-fullscreen"
                >
                  <Maximize className="w-5 h-5" />
                </Button>
              </div>
            </div>
          )}

          {/* Quality Indicator - only show on hover */}
          {hlsRef.current && showControls && (
            <QualityIndicator 
              hlsInstance={hlsRef.current} 
              className="absolute top-4 left-4 transition-opacity duration-300"
            />
          )}


          </div>

          {/* Video info - only show when not playing or when controls are visible */}
          {(!isPlaying || showControls) && (
            <div className="absolute bottom-16 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-6 pointer-events-none transition-opacity duration-300">
              <h3 
                className="text-xl font-semibold mb-2 text-white"
                data-testid="text-modal-title"
              >
                {video.title}
              </h3>
              <div className="flex items-center space-x-4 text-sm text-gray-300">
                <span data-testid="text-modal-views">
                  {formatViews(video.views)}
                </span>
                <span data-testid="text-modal-date">
                  {formatDate(video.createdAt)}
                </span>
                <span data-testid="text-modal-duration">
                  {formatDuration(video.duration)}
                </span>
              </div>
              {video.description && (
                <p className="mt-3 text-gray-300 text-sm" data-testid="text-modal-description">
                  {video.description}
                </p>
              )}
            </div>
          )}
        </div>


      </div>
    </div>
  );
}
