
"use client";

import Hls, { type Level } from "hls.js";
import { useEffect, useRef, useMemo, useState } from "react";
import { Button } from "@/components/ui/button";
import { PictureInPicture, AlertTriangle, Settings, Check, GaugeCircle } from "lucide-react";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuTrigger,
  DropdownMenuLabel,
  DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";


type VideoPlayerProps = {
  src: string[]; // src is now mandatory
  autoPlay?: boolean;
  onActiveSourceChanged?: (activeUrl: string | null) => void;
  onVideoEnded?: () => void;
};

// Helper to check for YouTube URLs and get the embeddable URL
const getYoutubeEmbedUrl = (url: string): string | null => {
  if (!url) return null;
  let videoId = null;
  // Standard watch URL
  const urlMatch = url.match(/[?&]v=([^&]+)/);
  if (urlMatch) {
    videoId = urlMatch[1];
  } else {
    // Short youtu.be URL
    const shortUrlMatch = url.match(/youtu\.be\/([^?]+)/);
    if (shortUrlMatch) {
      videoId = shortUrlMatch[1];
    } else {
      // Embed URL
      const embedMatch = url.match(/youtube\.com\/embed\/([^?]+)/);
      if (embedMatch) {
        videoId = embedMatch[1];
      }
    }
  }

  if (videoId) {
    const params = new URLSearchParams();
    params.set('autoplay', '1');
    params.set('rel', '0');
    params.set('modestbranding', '1');
    params.set('iv_load_policy', '3');
    params.set('enablejsapi', '1'); // Required for JS API
    params.set('origin', window.location.origin); // Required for JS API
    return `https://www.youtube.com/embed/${videoId}?${params.toString()}`;
  }
  return null;
};

const isHlsUrl = (url: string): boolean => {
    return url.endsWith('.m3u8');
};

const isProbablyEmbedUrl = (url: string): boolean => {
    try {
        const urlObj = new URL(url);
        // A simple heuristic: if it's a secure URL and not HLS or YouTube, treat as embed.
        // This could be refined with a list of known embed domains.
        return urlObj.protocol === 'https:' && !isHlsUrl(url) && !getYoutubeEmbedUrl(url);
    } catch (e) {
        return false;
    }
};

const playbackSpeeds = [0.5, 0.75, 1, 1.25, 1.5, 2];

export function HlsPlayer({ src: sourceUrls, autoPlay = false, onActiveSourceChanged, onVideoEnded }: VideoPlayerProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const hlsRef = useRef<Hls | null>(null);

  const [isPipSupported, setIsPipSupported] = useState(false);
  const [playbackError, setPlaybackError] = useState<string | null>(null);
  const [qualityLevels, setQualityLevels] = useState<Level[]>([]);
  const [currentQuality, setCurrentQuality] = useState<number>(-1); // -1 for auto
  const [currentSpeed, setCurrentSpeed] = useState(1);

  useEffect(() => {
    // Check for Picture-in-Picture support on the client
    if (typeof document !== 'undefined' && 'pictureInPictureEnabled' in document) {
      setIsPipSupported(document.pictureInPictureEnabled);
    }
  }, []);
  
  const handlePipClick = async () => {
    if (!videoRef.current) return;
    if (document.pictureInPictureElement) {
      await document.exitPictureInPicture();
    } else {
      try {
        await videoRef.current.requestPictureInPicture();
      } catch (error) {
        console.error("Failed to enter Picture-in-Picture mode:", error);
      }
    }
  };

  const handleQualityChange = (levelIndex: string) => {
    const newLevel = parseInt(levelIndex, 10);
    if (hlsRef.current) {
        hlsRef.current.currentLevel = newLevel;
        setCurrentQuality(newLevel);
    }
  };

  const handleSpeedChange = (speedStr: string) => {
    const speed = parseFloat(speedStr);
    if (videoRef.current) {
      videoRef.current.playbackRate = speed;
      setCurrentSpeed(speed);
    }
  };

  const primaryUrl = useMemo(() => (sourceUrls && sourceUrls.length > 0 ? sourceUrls[0] : ''), [sourceUrls]);
  
  const playerType = useMemo(() => {
      if (!primaryUrl) return 'none';
      if (getYoutubeEmbedUrl(primaryUrl)) return 'youtube';
      if (isHlsUrl(primaryUrl)) return 'hls';
      if (isProbablyEmbedUrl(primaryUrl)) return 'iframe';
      return 'none';
  }, [primaryUrl]);

  useEffect(() => {
    if (playerType === 'youtube') {
      const handlePlayerStateChange = (event: MessageEvent) => {
        if (event.source !== iframeRef.current?.contentWindow) return;
        try {
          const data = JSON.parse(event.data);
          if (data.event === 'onStateChange' && data.info === 0 && onVideoEnded) {
            onVideoEnded();
          }
        } catch (error) {/* Ignore non-JSON messages */}
      };

      window.addEventListener('message', handlePlayerStateChange);
      return () => window.removeEventListener('message', handlePlayerStateChange);
    }
  }, [playerType, onVideoEnded]);

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

    if (playerType !== 'hls' || !videoElement || !sourceUrls || sourceUrls.length === 0) {
        if (playerType === 'none' && primaryUrl) {
            setPlaybackError("Unsupported video format. Only HLS (.m3u8), YouTube, or direct embed URLs are supported.");
        }
        return;
    }
    
    if (hlsRef.current) {
      hlsRef.current.destroy();
    }
    
    if (Hls.isSupported()) {
      const hls = new Hls();
      hlsRef.current = hls;
      hls.loadSource(primaryUrl);
      hls.attachMedia(videoElement);

      hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
        if (onActiveSourceChanged) onActiveSourceChanged(primaryUrl);
        if (data.levels.length > 1) {
            setQualityLevels(data.levels);
        }
        if (autoPlay) videoElement.play().catch(err => console.error("Autoplay failed:", err));
      });

      hls.on(Hls.Events.LEVEL_SWITCHED, (event, data) => {
          setCurrentQuality(data.level);
      });

      hls.on(Hls.Events.ERROR, (event, data) => {
        if (data.fatal) {
           console.error('HLS.js fatal error:', data.type, data.details);
           setPlaybackError("This live stream is currently unavailable.");
        }
      });

    } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
      videoElement.src = primaryUrl;
      videoElement.addEventListener('loadedmetadata', () => {
         if (onActiveSourceChanged) onActiveSourceChanged(primaryUrl);
        if (autoPlay) videoElement.play().catch(err => console.error("Native HLS autoplay failed:", err));
      });
      videoElement.addEventListener('error', () => setPlaybackError("This live stream is currently unavailable."));
    }

    const handleEnded = () => { if (onVideoEnded) onVideoEnded(); };
    videoElement.addEventListener('ended', handleEnded);

    return () => {
      if (hlsRef.current) hlsRef.current.destroy();
      if (videoElement) videoElement.removeEventListener('ended', handleEnded);
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [playerType, primaryUrl, autoPlay]);


  const renderPlayer = () => {
        switch (playerType) {
            case 'youtube':
                return (
                    <iframe
                        ref={iframeRef}
                        className="w-full h-full"
                        src={getYoutubeEmbedUrl(primaryUrl)!}
                        title="YouTube video player"
                        frameBorder="0"
                        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                        allowFullScreen
                    ></iframe>
                );
            case 'iframe':
                return (
                    <iframe
                        ref={iframeRef}
                        className="w-full h-full"
                        src={primaryUrl}
                        title="Embedded content player"
                        frameBorder="0"
                        allow="autoplay; fullscreen; picture-in-picture"
                        allowFullScreen
                    ></iframe>
                );
            case 'hls':
                return (
                    <>
                        <video
                            ref={videoRef}
                            className="w-full h-full object-contain"
                            controls
                            autoPlay={autoPlay}
                            playsInline
                            disablePictureInPicture={false}
                        />
                        <div className="absolute top-2 right-2 flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity z-10">
                            <DropdownMenu>
                                <DropdownMenuTrigger asChild>
                                    <Button variant="secondary" size="sm">
                                        <Settings className="h-4 w-4" />
                                    </Button>
                                </DropdownMenuTrigger>
                                <DropdownMenuContent align="end">
                                    <DropdownMenuLabel>Settings</DropdownMenuLabel>
                                    <DropdownMenuSeparator />
                                    {qualityLevels.length > 1 && (
                                        <>
                                            <DropdownMenuRadioGroup value={String(currentQuality)} onValueChange={handleQualityChange}>
                                                <DropdownMenuLabel className="px-2 py-1.5 text-xs font-semibold">Quality</DropdownMenuLabel>
                                                <DropdownMenuRadioItem value="-1">Auto</DropdownMenuRadioItem>
                                                {qualityLevels.map((level, index) => (
                                                    <DropdownMenuRadioItem key={index} value={String(index)}>
                                                        {level.height}p
                                                    </DropdownMenuRadioItem>
                                                ))}
                                            </DropdownMenuRadioGroup>
                                            <DropdownMenuSeparator />
                                        </>
                                    )}
                                     <DropdownMenuRadioGroup value={String(currentSpeed)} onValueChange={handleSpeedChange}>
                                        <DropdownMenuLabel className="px-2 py-1.5 text-xs font-semibold">Playback Speed</DropdownMenuLabel>
                                        {playbackSpeeds.map(speed => (
                                            <DropdownMenuRadioItem key={speed} value={String(speed)}>
                                                {speed === 1 ? 'Normal' : `${speed}x`}
                                            </DropdownMenuRadioItem>
                                        ))}
                                    </DropdownMenuRadioGroup>
                                </DropdownMenuContent>
                            </DropdownMenu>

                            {isPipSupported && !playbackError && (
                                <Button
                                    variant="secondary"
                                    size="sm"
                                    onClick={handlePipClick}
                                >
                                    <PictureInPicture className="mr-2 h-4 w-4" />
                                    Mini Player
                                </Button>
                            )}
                        </div>
                    </>
                );
            default:
                return null;
        }
    };

  return (
    <div 
        className="relative w-full aspect-video bg-black rounded-lg overflow-hidden shadow-2xl group"
        role="application"
    >
      {renderPlayer()}
      {playbackError && (
        <div className="absolute inset-0 flex flex-col items-center justify-center bg-black/80 text-white p-4">
          <AlertTriangle className="w-12 h-12 mb-2 text-yellow-400" />
          <p className="font-semibold text-lg">Playback Error</p>
          <p className="text-sm text-center">{playbackError}</p>
        </div>
      )}
    </div>
  );
}
