import { useEffect, useRef, useState, forwardRef, useImperativeHandle, useCallback } from 'react';
import { Plyr } from 'plyr-react';
import 'plyr/dist/plyr.css';
import { useAdiloPlayer } from '@/hooks/useAdiloPlayer';
import { useVideoProgress } from '@/hooks/useVideoProgress';
import { Button } from '@/components/ui/button';
import { RotateCcw } from 'lucide-react';

interface VideoChapter {
  time: number; // Time in seconds
  title: string;
}

interface VideoPlayerWithChaptersProps {
  videoUrl?: string;
  embedCode?: string | null;
  m3u8Url?: string;
  mp4Url?: string;
  videoHost?: 'youtube' | 'adilo' | 'unknown';
  chapters?: VideoChapter[];
  accentColor?: string;
  onChapterChange?: (chapter: VideoChapter) => void;
  onTimeUpdate?: (time: number) => void;
  className?: string;
  videoId?: string; // For progress tracking
  videoType?: 'lesson' | 'webinar'; // For progress tracking
}

export interface VideoPlayerRef {
  jumpToTime: (time: number) => void;
  getCurrentTime: () => number;
}

export const VideoPlayerWithChapters = forwardRef<VideoPlayerRef, VideoPlayerWithChaptersProps>(({
  videoUrl,
  embedCode,
  m3u8Url,
  mp4Url,
  videoHost = 'unknown',
  chapters = [],
  accentColor,
  onChapterChange,
  onTimeUpdate,
  className = '',
  videoId,
  videoType,
}, ref) => {
  const plyrRef = useRef<any>(null);
  const currentChapterIndexRef = useRef<number>(-1);
  const [currentChapterIndex, setCurrentChapterIndex] = useState<number>(-1);
  const [currentTime, setCurrentTime] = useState(0);
  const [playerInstance, setPlayerInstance] = useState<any>(null);
  const [showResumePrompt, setShowResumePrompt] = useState(false);
  const [resumeTime, setResumeTime] = useState(0);
  const saveProgressTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // Determine if using Adilo (M3U8) or YouTube
  const isAdilo = videoHost === 'adilo' || m3u8Url;
  const isYouTube = videoHost === 'youtube' || (videoUrl && (videoUrl.includes('youtube.com') || videoUrl.includes('youtu.be')));

  // Video progress tracking
  const { progress, loading: progressLoading, saveProgress: saveProgressDirect, hasProgress } = useVideoProgress({
    videoId: videoId || '',
    videoType: videoType || 'lesson',
    duration: playerInstance?.duration,
  });

  // Debounced save function (saves every 5 seconds)
  const saveProgressDebounced = useCallback((time: number) => {
    if (saveProgressTimeoutRef.current) {
      clearTimeout(saveProgressTimeoutRef.current);
    }
    saveProgressTimeoutRef.current = setTimeout(() => {
      saveProgressDirect(time);
    }, 5000);
  }, [saveProgressDirect]);

  // Stable callback for finding current chapter
  const findCurrentChapter = useCallback((time: number) => {
    if (chapters.length === 0) return -1;

    let index = chapters.findIndex((chapter, i) => {
      const nextChapter = chapters[i + 1];
      return time >= chapter.time && (!nextChapter || time < nextChapter.time);
    });

    if (index === -1 && time < chapters[0].time) {
      return -1;
    }

    return index;
  }, [chapters]);

  // Stable onTimeUpdate callback for Adilo player
  const handleAdiloTimeUpdate = useCallback((time: number) => {
    setCurrentTime(time);
    onTimeUpdate?.(time);
    saveProgressDebounced(time);

    // Find and update current chapter for Adilo
    const index = findCurrentChapter(time);
    if (index !== currentChapterIndexRef.current) {
      currentChapterIndexRef.current = index;
      setCurrentChapterIndex(index);
      if (index >= 0 && onChapterChange) {
        onChapterChange(chapters[index]);
      }
    }
  }, [onTimeUpdate, onChapterChange, findCurrentChapter, chapters, saveProgressDebounced]);

  // Adilo player hook
  const adiloPlayer = useAdiloPlayer({
    m3u8Url,
    mp4Url,
    onTimeUpdate: handleAdiloTimeUpdate,
    accentColor,
  });

  // Get YouTube video ID
  const getYouTubeId = (url: string): string | null => {
    const match = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([^&\s/]+)/);
    return match ? match[1] : null;
  };

  // Convert embed code to YouTube URL if possible
  const getYouTubeUrlFromEmbed = (embed: string): string | null => {
    const match = embed.match(/src=["'](?:https?:)?\/\/(?:www\.)?youtube\.com\/embed\/([^"'\s?]*)/);
    return match ? `https://www.youtube.com/watch?v=${match[1]}` : null;
  };

  // Determine which video source to use
  const effectiveVideoUrl = isYouTube ? videoUrl : (embedCode ? getYouTubeUrlFromEmbed(embedCode) : videoUrl);
  const useEmbed = !isYouTube && embedCode;

  // Block right-click and dev tools
  useEffect(() => {
    const blockRightClick = (e: MouseEvent | KeyboardEvent) => {
      // Block right-click
      if (e.type === 'contextmenu') {
        e.preventDefault();
        return false;
      }

      // Block F12, Ctrl+Shift+I, Ctrl+Shift+J, Ctrl+U
      const keyboardEvent = e as KeyboardEvent;
      if (
        keyboardEvent.key === 'F12' ||
        (keyboardEvent.ctrlKey && keyboardEvent.shiftKey && (keyboardEvent.key === 'I' || keyboardEvent.key === 'J')) ||
        (keyboardEvent.ctrlKey && keyboardEvent.key === 'U')
      ) {
        e.preventDefault();
        return false;
      }
    };

    document.addEventListener('contextmenu', blockRightClick);
    document.addEventListener('keydown', blockRightClick);

    return () => {
      document.removeEventListener('contextmenu', blockRightClick);
      document.removeEventListener('keydown', blockRightClick);
    };
  }, []);

  // Initialize Plyr and set up time tracking
  useEffect(() => {
    if (!isYouTube) return;

    // Wait for player to initialize
    const checkPlayer = setInterval(() => {
      const player = plyrRef.current?.plyr;
      if (player) {
        clearInterval(checkPlayer);
        setPlayerInstance(player);

        // Set up time tracking using Plyr's event API
        if (typeof player.on === 'function') {
          player.on('timeupdate', () => {
            const time = player.currentTime;
            setCurrentTime(time);

            if (onTimeUpdate) {
              onTimeUpdate(time);
            }

            saveProgressDebounced(time);

            // Find current chapter
            const index = findCurrentChapter(time);
            if (index !== currentChapterIndexRef.current) {
              currentChapterIndexRef.current = index;
              setCurrentChapterIndex(index);
              if (index >= 0 && onChapterChange) {
                onChapterChange(chapters[index]);
              }
            }
          });
        } else {
          // Fallback: poll for time updates
          const interval = setInterval(() => {
            const time = player.currentTime;
            setCurrentTime(time);

            if (onTimeUpdate) {
              onTimeUpdate(time);
            }

            saveProgressDebounced(time);

            // Find current chapter
            const index = findCurrentChapter(time);
            if (index !== currentChapterIndexRef.current) {
              currentChapterIndexRef.current = index;
              setCurrentChapterIndex(index);
              if (index >= 0 && onChapterChange) {
                onChapterChange(chapters[index]);
              }
            }
          }, 500);

          // Store interval ID for cleanup
          return () => clearInterval(interval);
        }
      }
    }, 100);

    return () => clearInterval(checkPlayer);
  }, [isYouTube, findCurrentChapter, onChapterChange, onTimeUpdate, chapters, saveProgressDebounced]);

  // Jump to specific time using Plyr API or Adilo player
  const jumpToTime = (time: number) => {
    if (isAdilo) {
      const video = adiloPlayer.videoRef.current;
      if (video && adiloPlayer.isReady) {
        video.currentTime = time;
        const wasPlaying = !video.paused;
        if (wasPlaying) {
          video.play().catch((err) => {
            if (err.name !== 'AbortError') {
              console.error('Jump failed:', err);
            }
          });
        }
      }
    } else if (playerInstance) {
      playerInstance.currentTime = time;
      playerInstance.play();
    }
  };

  const getCurrentTime = () => {
    return currentTime;
  };

  // Check for saved progress and show resume prompt
  useEffect(() => {
    if (!progressLoading && hasProgress && progress && progress.last_position > 5) {
      setShowResumePrompt(true);
      setResumeTime(progress.last_position);
    }
  }, [progressLoading, hasProgress, progress]);

  const handleResume = () => {
    jumpToTime(resumeTime);
    setShowResumePrompt(false);
  };

  const handleStartFromBeginning = () => {
    setShowResumePrompt(false);
  };

  // Save progress immediately on pause/ended
  useEffect(() => {
    if (!adiloPlayer.videoRef.current) return;

    const video = adiloPlayer.videoRef.current;
    const handlePause = () => {
      // Save immediately on pause
      saveProgressDirect(video.currentTime);
    };

    const handleEnded = () => {
      // Save immediately on end
      saveProgressDirect(video.currentTime);
    };

    video.addEventListener('pause', handlePause);
    video.addEventListener('ended', handleEnded);

    return () => {
      video.removeEventListener('pause', handlePause);
      video.removeEventListener('ended', handleEnded);
    };
  }, [adiloPlayer.videoRef, saveProgressDirect]);

  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyPress = (e: KeyboardEvent) => {
      // Ignore if user is typing in an input
      if (
        e.target instanceof HTMLInputElement ||
        e.target instanceof HTMLTextAreaElement ||
        e.target instanceof HTMLSelectElement ||
        e.target.isContentEditable
      ) {
        return;
      }

      const player = isAdilo ? adiloPlayer.videoRef.current : playerInstance;
      if (!player) return;

      // Space: Play/Pause
      if (e.code === 'Space') {
        e.preventDefault();
        if (isAdilo) {
          const video = player as HTMLVideoElement;
          video.paused ? video.play() : video.pause();
        } else {
          player.playing ? player.pause() : player.play();
        }
      }

      // Arrow Left: Back 5 seconds
      if (e.code === 'ArrowLeft') {
        e.preventDefault();
        const currentTime = isAdilo ? (player as HTMLVideoElement).currentTime : player.currentTime;
        jumpToTime(Math.max(0, currentTime - 5));
      }

      // Arrow Right: Forward 5 seconds
      if (e.code === 'ArrowRight') {
        e.preventDefault();
        const currentTime = isAdilo ? (player as HTMLVideoElement).currentTime : player.currentTime;
        const duration = isAdilo ? (player as HTMLVideoElement).duration : player.duration;
        jumpToTime(Math.min(duration, currentTime + 5));
      }

      // Arrow Up: Volume up 10%
      if (e.code === 'ArrowUp') {
        e.preventDefault();
        if (!isAdilo) {
          const newVolume = Math.min(1, player.volume + 0.1);
          player.volume = newVolume;
        }
      }

      // Arrow Down: Volume down 10%
      if (e.code === 'ArrowDown') {
        e.preventDefault();
        if (!isAdilo) {
          const newVolume = Math.max(0, player.volume - 0.1);
          player.volume = newVolume;
        }
      }

      // F: Fullscreen
      if (e.code === 'KeyF') {
        e.preventDefault();
        if (isAdilo) {
          if (document.fullscreenElement) {
            document.exitFullscreen();
          } else {
            (player as HTMLVideoElement).parentElement?.requestFullscreen();
          }
        } else {
          player.fullscreen.toggle();
        }
      }

      // M: Mute
      if (e.code === 'KeyM') {
        e.preventDefault();
        if (isAdilo) {
          (player as HTMLVideoElement).muted = !(player as HTMLVideoElement).muted;
        } else {
          player.muted = !player.muted;
        }
      }

      // J: Back 10 seconds
      if (e.code === 'KeyJ') {
        e.preventDefault();
        const currentTime = isAdilo ? (player as HTMLVideoElement).currentTime : player.currentTime;
        jumpToTime(Math.max(0, currentTime - 10));
      }

      // L: Forward 10 seconds
      if (e.code === 'KeyL') {
        e.preventDefault();
        const currentTime = isAdilo ? (player as HTMLVideoElement).currentTime : player.currentTime;
        const duration = isAdilo ? (player as HTMLVideoElement).duration : player.duration;
        jumpToTime(Math.min(duration, currentTime + 10));
      }
    };

    document.addEventListener('keydown', handleKeyPress);
    return () => document.removeEventListener('keydown', handleKeyPress);
  }, [isAdilo, adiloPlayer.isReady, playerInstance]);

  // Expose methods via ref
  useImperativeHandle(ref, () => ({
    jumpToTime,
    getCurrentTime,
  }));

  // Adilo M3U8 Player with Video.js
  if (isAdilo) {
    return (
      <div className={`relative ${className}`}>
        <div className="aspect-video rounded-lg overflow-hidden bg-black vjs-big-play-centered">
          <video
            ref={adiloPlayer.videoRef}
            className="video-js vjs-default-skin vjs-big-play-centered vjs-fill"
            playsInline
          />
        </div>

        {/* Resume prompt */}
        {showResumePrompt && (
          <div className="absolute inset-0 bg-black/80 flex items-center justify-center z-10 rounded-lg">
            <div className="text-center space-y-4 p-6">
              <div className="text-white text-lg font-semibold">
                Lanjutkan dari posisi terakhir?
              </div>
              <div className="text-gray-300 text-sm">
                {Math.floor(resumeTime / 60)}:{String(Math.floor(resumeTime % 60)).padStart(2, '0')}
              </div>
              <div className="flex gap-3 justify-center">
                <Button
                  onClick={handleResume}
                  className="bg-primary hover:bg-primary/90"
                >
                  <RotateCcw className="w-4 h-4 mr-2" />
                  Lanjutkan
                </Button>
                <Button
                  onClick={handleStartFromBeginning}
                  variant="outline"
                  className="bg-white/10 hover:bg-white/20 text-white border-white/20"
                >
                  Mulai dari awal
                </Button>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }

  if (useEmbed) {
    // Custom embed (Vimeo, etc. - not Adilo anymore)
    return (
      <div
        className={`aspect-video rounded-lg overflow-hidden ${className}`}
        dangerouslySetInnerHTML={{ __html: embedCode }}
      />
    );
  }

  const youtubeId = effectiveVideoUrl ? getYouTubeId(effectiveVideoUrl) : null;

  // Apply custom accent color
  useEffect(() => {
    if (!accentColor || !plyrRef.current) return;

    const style = document.createElement('style');
    style.textContent = `
      .plyr__control--overlared,
      .plyr__controls .plyr__control.plyr__tab-focus,
      .plyr__controls .plyr__control:hover,
      .plyr__controls .plyr__control[aria-current='true'] {
        background: ${accentColor} !important;
      }
      .plyr__progress__value {
        background: ${accentColor} !important;
      }
      .plyr__volume__value {
        background: ${accentColor} !important;
      }
    `;
    document.head.appendChild(style);

    return () => {
      document.head.removeChild(style);
    };
  }, [accentColor]);

  return (
    <div className={`relative ${className}`}>
      {youtubeId && (
        <>
          <div style={{ position: 'relative', pointerEvents: 'auto' }}>
            <Plyr
              ref={plyrRef}
              source={{
                type: 'video',
                sources: [
                  {
                    src: `https://www.youtube.com/watch?v=${youtubeId}`,
                    provider: 'youtube',
                  },
                ],
              }}
              options={{
                controls: [
                  'play-large',
                  'play',
                  'progress',
                  'current-time',
                  'mute',
                  'volume',
                  'captions',
                  'settings',
                  'pip',
                  'airplay',
                  'fullscreen',
                ],
                speed: {
                  selected: 1,
                  options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
                },
                youtube: {
                  noCookie: true,
                  rel: 0,
                  showinfo: 0,
                  iv_load_policy: 3,
                  modestbranding: 1,
                  controls: 0,
                  disablekb: 1,
                  fs: 0,
                },
                hideControls: false,
                keyboardShortcuts: {
                  focused: true,
                  global: true,
                },
              }}
            />
          </div>

          <style>{`
            /* Block YouTube UI overlays */
            .plyr__video-wrapper .plyr__video-embed iframe {
              pointer-events: none !important;
            }

            /* Only allow clicks on Plyr controls */
            .plyr__controls,
            .plyr__control--overlaid {
              pointer-events: auto !important;
            }

            /* Hide YouTube's native play button that appears behind */
            .plyr__video-wrapper::after {
              content: '';
              position: absolute;
              top: 0;
              left: 0;
              right: 0;
              bottom: 0;
              pointer-events: none;
              z-index: 1;
            }
          `}</style>
        </>
      )}
    </div>
  );
});
