import { useState, useRef, useEffect } from "react";
import { Play } from "lucide-react";
import { type Video } from "@shared/schema";
import Hls from "hls.js";

interface HLSPreviewThumbnailProps {
  video: Video;
  onClick: (video: Video) => void;
  className?: string;
}

export default function HLSPreviewThumbnail({ video, onClick, className = "" }: HLSPreviewThumbnailProps) {
  const [isHovering, setIsHovering] = useState(false);
  const [previewTime, setPreviewTime] = useState(0);
  const [previewThumbnail, setPreviewThumbnail] = useState<string | null>(null);
  const [isVideoLoaded, setIsVideoLoaded] = useState(false);
  const [hlsInstance, setHlsInstance] = useState<Hls | null>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const hoverTimeoutRef = useRef<NodeJS.Timeout>();
  const previewIntervalRef = useRef<NodeJS.Timeout>();

  // Initialize HLS for preview only when hovering
  const initializeVideoOnDemand = () => {
    if (!video.videoUrl.includes('.m3u8') && !video.videoUrlMp4) return;

    const videoElement = videoRef.current;
    if (!videoElement || isVideoLoaded || hlsInstance) return;

    let hls: Hls | null = null;

    // Use MP4 if available for better seek performance
    if (video.videoUrlMp4) {
      videoElement.src = video.videoUrlMp4;
      videoElement.muted = true;
      videoElement.playsInline = true;
      videoElement.preload = 'metadata';
      
      const handleLoadedMetadata = () => {
        setIsVideoLoaded(true);
        videoElement.removeEventListener('loadedmetadata', handleLoadedMetadata);
      };
      videoElement.addEventListener('loadedmetadata', handleLoadedMetadata);
      return;
    }

    // Use HLS with reduced quality for preview
    if (Hls.isSupported() && video.videoUrl.includes('.m3u8')) {
      hls = new Hls({
        startLevel: 0, // Start with lowest quality for faster loading
        capLevelToPlayerSize: true,
        maxLoadingDelay: 2,
        maxBufferLength: 10, // Minimal buffering for previews
        lowLatencyMode: true,
      });

      hls.loadSource(video.videoUrl);
      hls.attachMedia(videoElement);
      
      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        setIsVideoLoaded(true);
      });

      hls.on(Hls.Events.ERROR, (event, data) => {
        console.warn('HLS preview error:', data);
        setIsVideoLoaded(false);
      });

      setHlsInstance(hls);
    }
  };

  // Clean up on unmount
  useEffect(() => {
    return () => {
      if (hlsInstance) {
        hlsInstance.destroy();
      }
    };
  }, [hlsInstance]);

  const generatePreviewThumbnail = (time: number) => {
    const videoElement = videoRef.current;
    if (!videoElement || !isVideoLoaded) return;

    // Clamp time to video duration
    const clampedTime = Math.max(0, Math.min(time, video.duration - 1));
    videoElement.currentTime = clampedTime;
    
    const handleSeeked = () => {
      try {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        if (!ctx) return;

        canvas.width = videoElement.videoWidth || 320;
        canvas.height = videoElement.videoHeight || 180;
        
        ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
        
        const thumbnailUrl = canvas.toDataURL('image/jpeg', 0.7);
        setPreviewThumbnail(thumbnailUrl);
      } catch (error) {
        console.warn('Failed to generate preview thumbnail:', error);
      }
      
      videoElement.removeEventListener('seeked', handleSeeked);
    };

    videoElement.addEventListener('seeked', handleSeeked);
  };

  const handleMouseMove = (e: React.MouseEvent) => {
    if (!isHovering || !containerRef.current || !isVideoLoaded) return;

    const rect = containerRef.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const percentage = Math.max(0, Math.min(1, x / rect.width));
    const time = percentage * video.duration;
    
    setPreviewTime(time);
    
    // Throttle thumbnail generation
    if (previewIntervalRef.current) {
      clearTimeout(previewIntervalRef.current);
    }
    
    previewIntervalRef.current = setTimeout(() => {
      generatePreviewThumbnail(time);
    }, 200);
  };

  const handleMouseEnter = () => {
    if (hoverTimeoutRef.current) {
      clearTimeout(hoverTimeoutRef.current);
    }
    
    hoverTimeoutRef.current = setTimeout(() => {
      setIsHovering(true);
      // Initialize video only when user actually hovers
      initializeVideoOnDemand();
      if (isVideoLoaded) {
        generatePreviewThumbnail(video.duration * 0.25); // Start at 25% of video
      }
    }, 300); // Reduced delay for better UX
  };

  const handleMouseLeave = () => {
    if (hoverTimeoutRef.current) {
      clearTimeout(hoverTimeoutRef.current);
    }
    if (previewIntervalRef.current) {
      clearTimeout(previewIntervalRef.current);
    }
    
    setIsHovering(false);
    setPreviewThumbnail(null);
    setPreviewTime(0);
  };

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

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

  return (
    <div className={`group cursor-pointer ${className}`}>
      {/* Hidden video element for thumbnail generation */}
      <video
        ref={videoRef}
        className="hidden"
        muted
        playsInline
        crossOrigin="anonymous"
        onError={() => setIsVideoLoaded(false)}
      />
      
      <div 
        ref={containerRef}
        className="relative bg-bunny-gray rounded-xl overflow-hidden mb-4 aspect-video"
        onClick={() => onClick(video)}
        onMouseMove={handleMouseMove}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave}
        data-testid={`hls-preview-thumbnail-${video.id}`}
      >
        {/* Main thumbnail or preview */}
        <img
          src={isHovering && previewThumbnail ? previewThumbnail : video.thumbnailUrl}
          alt={video.title}
          className="w-full h-full object-cover transition-all duration-300 group-hover:scale-105"
          data-testid={`img-hls-preview-${video.id}`}
          onError={(e) => {
            const target = e.target as HTMLImageElement;
            target.style.display = 'none';
            // Show fallback background
            if (target.parentElement) {
              target.parentElement.style.background = 'linear-gradient(45deg, #374151, #4b5563)';
            }
          }}
        />
        
        {/* Fallback for missing thumbnails */}
        <div className="absolute inset-0 bg-gradient-to-br from-gray-600 to-gray-700 flex items-center justify-center opacity-0">
          <div className="text-white text-center">
            <Play className="w-12 h-12 mx-auto mb-2 opacity-50" />
            <p className="text-sm opacity-75">Video Preview</p>
          </div>
        </div>
        
        {/* Overlay with play button */}
        <div className={`absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-all duration-300 flex items-center justify-center ${
          isHovering ? 'bg-black/50' : ''
        }`}>
          <div className={`bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center group-hover:bg-white/30 transition-all duration-300 ${
            isHovering ? 'w-20 h-20 bg-white/40 scale-110' : 'w-16 h-16'
          }`}>
            <Play className={`text-white ml-1 transition-all duration-300 ${
              isHovering ? 'text-2xl' : 'text-xl'
            }`} />
          </div>
        </div>
        
        {/* Duration badge */}
        <div className="absolute bottom-3 right-3 bg-black/80 px-2 py-1 rounded text-xs font-medium">
          <span data-testid={`text-duration-${video.id}`}>
            {formatDuration(video.duration)}
          </span>
        </div>

        {/* Preview controls when hovering */}
        {isHovering && isVideoLoaded && (
          <>
            {/* Scrub bar */}
            <div className="absolute bottom-0 left-0 right-0 h-1 bg-white/20">
              <div 
                className="h-full bg-[#da234d] transition-all duration-150"
                style={{ width: `${(previewTime / video.duration) * 100}%` }}
              />
            </div>
            
            {/* Time tooltip */}
            <div 
              className="absolute bottom-12 bg-black/90 text-white text-xs px-2 py-1 rounded pointer-events-none transition-all duration-150 z-10"
              style={{ 
                left: `${Math.max(5, Math.min(95, (previewTime / video.duration) * 100))}%`,
                transform: 'translateX(-50%)'
              }}
            >
              {formatTime(previewTime)}
            </div>

            {/* Preview indicator */}
            <div className="absolute top-2 right-2 bg-[#da234d]/80 text-white text-xs px-2 py-1 rounded">
              Preview
            </div>
          </>
        )}
        
        {/* Loading state */}
        {!isVideoLoaded && (
          <div className="absolute top-2 left-2">
            <div className="w-6 h-6 gradient-primary rounded flex items-center justify-center animate-pulse">
              <div className="w-0 h-0 border-l-[4px] border-l-white border-y-[3px] border-y-transparent"></div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}