import { useEffect, useRef, useState, useCallback } from 'react';
import './YouTubePlayer.css';
import UserForm from './UserForm';
import WebcamRecorder from './WebcamRecorder';

const DEFAULT_VIDEO_ID = 'wLM5bzt1xks';
const TERP1_HEADSTART = 2; // seconds ahead
const API_BASE_URL = 'http://localhost:3001';

// Extract video ID from various YouTube URL formats
const extractVideoId = (url) => {
  if (!url) return null;

  // Handle direct video ID (11 characters)
  if (/^[a-zA-Z0-9_-]{11}$/.test(url)) {
    return url;
  }

  // Handle various YouTube URL formats
  const patterns = [
    /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/)([a-zA-Z0-9_-]{11})/,
    /youtube\.com\/watch\?.*v=([a-zA-Z0-9_-]{11})/,
  ];

  for (const pattern of patterns) {
    const match = url.match(pattern);
    if (match) return match[1];
  }

  return null;
};

export default function YouTubePlayer() {
  const youtubePlayerRef = useRef(null);
  const localVideo1Ref = useRef(null);
  const localVideo2Ref = useRef(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [isReady, setIsReady] = useState(false);
  const [duration, setDuration] = useState(0);
  const [currentTime, setCurrentTime] = useState(0);
  const [videoTitle, setVideoTitle] = useState('');
  const timeUpdateIntervalRef = useRef(null);

  // YouTube URL state
  const [youtubeUrl, setYoutubeUrl] = useState('');
  const [currentVideoId, setCurrentVideoId] = useState(DEFAULT_VIDEO_ID);

  // Recording state
  const [recordedBlob, setRecordedBlob] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitMessage, setSubmitMessage] = useState(null);

  // Recent recordings state
  // Shared recording state (when viewing via unique link)
  const [sharedRecording, setSharedRecording] = useState(null);
  const [shareLink, setShareLink] = useState(null);

  // Video swap state
  const [videosSwapped, setVideosSwapped] = useState(false);

  // Check for shared recording in URL
  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const shareId = urlParams.get('share');

    if (shareId) {
      // Fetch the shared recording
      fetch(`${API_BASE_URL}/api/share/${shareId}`)
        .then(res => res.json())
        .then(data => {
          if (data && !data.error) {
            setSharedRecording(data);
            // Extract and set the YouTube video ID from the shared recording
            const videoId = extractVideoId(data.youtube_video_url);
            if (videoId) {
              setCurrentVideoId(videoId);
              // Load the video into the player if it's ready
              if (youtubePlayerRef.current && youtubePlayerRef.current.cueVideoById) {
                youtubePlayerRef.current.cueVideoById(videoId);
              }
            }
          }
        })
        .catch(err => console.error('Error fetching shared recording:', err));
    }
  }, []);

  // Load shared recording's YouTube video when player becomes ready
  useEffect(() => {
    if (isReady && sharedRecording?.youtube_video_url) {
      const videoId = extractVideoId(sharedRecording.youtube_video_url);
      if (videoId && videoId !== DEFAULT_VIDEO_ID && youtubePlayerRef.current?.cueVideoById) {
        youtubePlayerRef.current.cueVideoById(videoId);
      }
    }
  }, [isReady, sharedRecording]);

  // Load local videos when sharedRecording changes
  useEffect(() => {
    if (sharedRecording?.recorded_video_path && localVideo1Ref.current) {
      localVideo1Ref.current.load();
    }
    if (sharedRecording?.recorded_video_path_2 && localVideo2Ref.current) {
      localVideo2Ref.current.load();
    }
  }, [sharedRecording?.recorded_video_path, sharedRecording?.recorded_video_path_2]);

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

  const handleLoadVideo = () => {
    const videoId = extractVideoId(youtubeUrl);
    if (!videoId) {
      alert('Please enter a valid YouTube URL');
      return;
    }

    setCurrentVideoId(videoId);
    setCurrentTime(0);
    setIsPlaying(false);

    // Load the new video into the player (cue instead of load to not auto-play)
    if (youtubePlayerRef.current && youtubePlayerRef.current.cueVideoById) {
      youtubePlayerRef.current.cueVideoById(videoId);
    }
  };

  const startTimeTracking = useCallback(() => {
    if (timeUpdateIntervalRef.current) {
      clearInterval(timeUpdateIntervalRef.current);
    }
    timeUpdateIntervalRef.current = setInterval(() => {
      if (youtubePlayerRef.current && youtubePlayerRef.current.getCurrentTime) {
        setCurrentTime(youtubePlayerRef.current.getCurrentTime());
      }
    }, 250);
  }, []);

  const stopTimeTracking = useCallback(() => {
    if (timeUpdateIntervalRef.current) {
      clearInterval(timeUpdateIntervalRef.current);
      timeUpdateIntervalRef.current = null;
    }
  }, []);

  useEffect(() => {
    // Load the YouTube IFrame API script
    const tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    const firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    // Set up the global callback for when API is ready
    window.onYouTubeIframeAPIReady = () => {
      youtubePlayerRef.current = new window.YT.Player('youtube-player', {
        videoId: currentVideoId,
        playerVars: {
          playsinline: 1,
          rel: 0,
        },
        events: {
          onReady: handlePlayerReady,
          onStateChange: handleStateChange,
        },
      });
    };

    // If the API is already loaded (e.g., from a previous mount)
    if (window.YT && window.YT.Player) {
      window.onYouTubeIframeAPIReady();
    }

    return () => {
      stopTimeTracking();
      if (youtubePlayerRef.current && youtubePlayerRef.current.destroy) {
        youtubePlayerRef.current.destroy();
      }
    };
  }, [stopTimeTracking]);

  const handlePlayerReady = () => {
    setIsReady(true);
    // Get the duration of the YouTube video
    if (youtubePlayerRef.current && youtubePlayerRef.current.getDuration) {
      setDuration(youtubePlayerRef.current.getDuration());
    }
    // Get the video title (with a small delay to ensure data is available)
    setTimeout(() => {
      if (youtubePlayerRef.current && youtubePlayerRef.current.getVideoData) {
        const videoData = youtubePlayerRef.current.getVideoData();
        if (videoData && videoData.title) {
          setVideoTitle(videoData.title);
        }
      }
    }, 500);
  };

  const handleVideo1LoadedMetadata = () => {
    // Set terp1.mp4 to start 2 seconds ahead
    if (localVideo1Ref.current) {
      localVideo1Ref.current.currentTime = TERP1_HEADSTART;
    }
  };

  const playAllLocalVideos = () => {
    if (localVideo1Ref.current) {
      localVideo1Ref.current.play();
    }
    if (localVideo2Ref.current) {
      localVideo2Ref.current.play();
    }
  };

  const pauseAllLocalVideos = () => {
    if (localVideo1Ref.current) {
      localVideo1Ref.current.pause();
    }
    if (localVideo2Ref.current) {
      localVideo2Ref.current.pause();
    }
  };

  const handleStateChange = (event) => {
    // YouTube Player States:
    // -1 = unstarted, 0 = ended, 1 = playing, 2 = paused, 3 = buffering, 5 = video cued

    // Update video title and duration when video is cued or changes
    if (event.data === 5 || event.data === -1) { // 5 = cued, -1 = unstarted
      // Update duration
      if (youtubePlayerRef.current && youtubePlayerRef.current.getDuration) {
        const newDuration = youtubePlayerRef.current.getDuration();
        if (newDuration > 0) {
          setDuration(newDuration);
        }
      }
      // Update title with small delay to ensure data is available
      setTimeout(() => {
        if (youtubePlayerRef.current && youtubePlayerRef.current.getVideoData) {
          const videoData = youtubePlayerRef.current.getVideoData();
          if (videoData && videoData.title) {
            setVideoTitle(videoData.title);
          }
        }
      }, 300);
    }

    if (event.data === window.YT.PlayerState.PLAYING) {
      setIsPlaying(true);
      playAllLocalVideos();
      startTimeTracking();
      // Also update duration when playing starts (in case it wasn't available before)
      if (youtubePlayerRef.current && youtubePlayerRef.current.getDuration) {
        const newDuration = youtubePlayerRef.current.getDuration();
        if (newDuration > 0) {
          setDuration(newDuration);
        }
      }
    } else if (
      event.data === window.YT.PlayerState.PAUSED ||
      event.data === window.YT.PlayerState.ENDED
    ) {
      setIsPlaying(false);
      pauseAllLocalVideos();
      stopTimeTracking();
    }
  };

  const handleLocalVideoPlay = () => {
    setIsPlaying(true);
    // Sync YouTube video
    if (youtubePlayerRef.current && isReady) {
      youtubePlayerRef.current.playVideo();
    }
    playAllLocalVideos();
  };

  const handleLocalVideoPause = () => {
    setIsPlaying(false);
    // Sync YouTube video
    if (youtubePlayerRef.current && isReady) {
      youtubePlayerRef.current.pauseVideo();
    }
    pauseAllLocalVideos();
  };

  const handlePlay = () => {
    // Seek to beginning first
    if (youtubePlayerRef.current && youtubePlayerRef.current.seekTo) {
      youtubePlayerRef.current.seekTo(0, true);
    }
    if (localVideo1Ref.current) {
      localVideo1Ref.current.currentTime = TERP1_HEADSTART;
    }
    if (localVideo2Ref.current) {
      localVideo2Ref.current.currentTime = 0;
    }
    setCurrentTime(0);

    // Play all videos
    if (youtubePlayerRef.current && isReady) {
      youtubePlayerRef.current.playVideo();
    }
    playAllLocalVideos();
  };

  const handlePause = () => {
    // Pause all videos
    if (youtubePlayerRef.current && isReady) {
      youtubePlayerRef.current.pauseVideo();
    }
    pauseAllLocalVideos();
  };

  const handleToggle = () => {
    if (isPlaying) {
      handlePause();
    } else {
      handlePlay();
    }
  };

  const handleRecordingComplete = (blob) => {
    setRecordedBlob(blob);
    setSubmitMessage(null);
  };

  const handleReRecord = () => {
    // Seek YouTube video to the beginning
    if (youtubePlayerRef.current && youtubePlayerRef.current.seekTo) {
      youtubePlayerRef.current.seekTo(0, true);
    }
    // Seek local videos to the beginning
    if (localVideo1Ref.current) {
      localVideo1Ref.current.currentTime = TERP1_HEADSTART;
    }
    if (localVideo2Ref.current) {
      localVideo2Ref.current.currentTime = 0;
    }
    setCurrentTime(0);
  };

  const handleDiscard = () => {
    // Pause and seek YouTube video to the beginning
    if (youtubePlayerRef.current) {
      if (youtubePlayerRef.current.pauseVideo) {
        youtubePlayerRef.current.pauseVideo();
      }
      if (youtubePlayerRef.current.seekTo) {
        youtubePlayerRef.current.seekTo(0, true);
      }
    }
    // Pause and seek local videos to the beginning
    if (localVideo1Ref.current) {
      localVideo1Ref.current.pause();
      localVideo1Ref.current.currentTime = TERP1_HEADSTART;
    }
    if (localVideo2Ref.current) {
      localVideo2Ref.current.pause();
      localVideo2Ref.current.currentTime = 0;
    }
    setCurrentTime(0);
    setIsPlaying(false);
  };

  const handleFormSubmit = async ({ name, email }) => {
    if (!name || !name.trim()) {
      setSubmitMessage({ type: 'error', text: 'Please enter your name' });
      return;
    }

    if (!email || !email.trim()) {
      setSubmitMessage({ type: 'error', text: 'Please enter your email address' });
      return;
    }

    if (!recordedBlob) {
      setSubmitMessage({ type: 'error', text: 'Please record a video first' });
      return;
    }

    setIsSubmitting(true);
    setSubmitMessage(null);

    try {
      const formData = new FormData();
      formData.append('name', name);
      formData.append('email', email);
      formData.append('video', recordedBlob, 'recording.webm');

      // Check if we're adding a second video to a shared recording
      // Must have a share parameter in URL and sharedRecording loaded without a second video
      const urlParams = new URLSearchParams(window.location.search);
      const shareId = urlParams.get('share');
      const isAddingSecondVideo = shareId && sharedRecording?.unique_link && !sharedRecording.recorded_video_path_2;

      let response;
      if (isAddingSecondVideo) {
        // Save as second video
        response = await fetch(`${API_BASE_URL}/api/share/${sharedRecording.unique_link}/second-video`, {
          method: 'POST',
          body: formData,
        });
      } else {
        // Save as new recording (first video)
        formData.append('youtubeVideoUrl', `https://www.youtube.com/watch?v=${currentVideoId}`);
        response = await fetch(`${API_BASE_URL}/api/recordings`, {
          method: 'POST',
          body: formData,
        });
      }

      const data = await response.json();

      if (response.ok) {
        if (isAddingSecondVideo) {
          setSubmitMessage({
            type: 'success',
            text: 'Second recording saved successfully!'
          });
          // Refresh the shared recording to show the new video
          const updatedRecording = await fetch(`${API_BASE_URL}/api/share/${sharedRecording.unique_link}`);
          const updatedData = await updatedRecording.json();
          setSharedRecording(updatedData);
        } else {
          const generatedShareLink = `${window.location.origin}${window.location.pathname}?share=${data.uniqueLink}`;
          setShareLink(generatedShareLink);
          setSubmitMessage({
            type: 'success',
            text: 'Recording saved successfully!'
          });
          // Fetch and display the saved recording in the first video player
          const savedRecording = await fetch(`${API_BASE_URL}/api/share/${data.uniqueLink}`);
          const savedData = await savedRecording.json();
          if (savedData && !savedData.error) {
            setSharedRecording(savedData);
          }
        }
        setRecordedBlob(null);
      } else {
        setSubmitMessage({ type: 'error', text: data.error || 'Failed to save recording' });
      }
    } catch (error) {
      console.error('Error submitting recording:', error);
      setSubmitMessage({ type: 'error', text: 'Failed to connect to server. Make sure the server is running.' });
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleSeek = (event) => {
    const newTime = parseFloat(event.target.value);
    setCurrentTime(newTime);

    // Seek YouTube video
    if (youtubePlayerRef.current && youtubePlayerRef.current.seekTo) {
      youtubePlayerRef.current.seekTo(newTime, true);
    }

    // Seek local videos (terp1 with headstart offset)
    // Clamp to video duration if seeking past the end
    if (localVideo1Ref.current) {
      const video1Duration = localVideo1Ref.current.duration || Infinity;
      const video1Time = Math.min(newTime + TERP1_HEADSTART, video1Duration);
      localVideo1Ref.current.currentTime = video1Time;
    }
    if (localVideo2Ref.current) {
      const video2Duration = localVideo2Ref.current.duration || Infinity;
      const video2Time = Math.min(newTime, video2Duration);
      localVideo2Ref.current.currentTime = video2Time;
    }
  };

  return (
    <div className="player-container">
      {/* YouTube URL Input */}
      <div className="youtube-url-input">
        <input
          type="text"
          placeholder="Paste YouTube URL here..."
          value={youtubeUrl}
          onChange={(e) => setYoutubeUrl(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && handleLoadVideo()}
          className="url-input"
        />
        <button onClick={handleLoadVideo} className="load-btn">
          Load Video
        </button>
      </div>

      {videoTitle && <h1 className="video-title">{videoTitle} ({formatTime(duration)})</h1>}
      <div className="video-section">
        <div className="video-wrapper">
          <div id="youtube-player"></div>
        </div>
      </div>

      {/* User Form and Webcam Recorder Section - hide when both recordings exist */}
      {!(sharedRecording?.recorded_video_path && sharedRecording?.recorded_video_path_2) && (
        <div className="user-recording-section">
          <div className="user-form-container">
            <UserForm onSubmit={handleFormSubmit} isSubmitting={isSubmitting} />
            {submitMessage && (
              <p className={`submit-message ${submitMessage.type}`}>
                {submitMessage.text}
              </p>
            )}
            {shareLink && (
              <div className="share-link-container">
                <p className="share-link-label">Share this recording:</p>
                <input
                  type="text"
                  className="share-link-input"
                  value={shareLink}
                  readOnly
                  onClick={(e) => e.target.select()}
                />
                <button
                  className="copy-link-btn"
                  onClick={() => {
                    navigator.clipboard.writeText(shareLink);
                    alert('Link copied to clipboard!');
                  }}
                >
                  Copy Link
                </button>
              </div>
            )}
          </div>
          <WebcamRecorder
            onRecordingComplete={handleRecordingComplete}
            onRecordingStart={handlePlay}
            onRecordingStop={handlePause}
            onReRecord={handleReRecord}
            onDiscard={handleDiscard}
          />
        </div>
      )}

      <div className="timeline-container">
        <span className="time-display">{formatTime(currentTime)}</span>
        <input
          type="range"
          className="timeline-slider"
          min="0"
          max={duration || 100}
          step="0.1"
          value={currentTime}
          onChange={handleSeek}
          disabled={!isReady}
        />
        <span className="time-display">{formatTime(duration)}</span>
      </div>

      <div className="local-videos-row">
        <div className="video-section local-video-section">
          <div className="video-header">
            <h2 className="video-label">
              {sharedRecording ? (videosSwapped ? sharedRecording.name_2 : sharedRecording.name) : 'First Recording'}
            </h2>
            <p className="video-note">
              {sharedRecording ? (videosSwapped ? sharedRecording.email_2 : sharedRecording.email) : 'No recording yet'}
            </p>
            <p className="video-note">This video has 2 seconds headstart</p>
          </div>
          <div className="video-wrapper">
            {sharedRecording ? (
              videosSwapped ? (
                sharedRecording.recorded_video_path_2 ? (
                  <video
                    ref={localVideo1Ref}
                    className="local-video"
                    onPlay={handleLocalVideoPlay}
                    onPause={handleLocalVideoPause}
                    onLoadedMetadata={handleVideo1LoadedMetadata}
                    key={`shared-2-swapped-${sharedRecording.id}-${sharedRecording.recorded_video_path_2}`}
                    src={sharedRecording.recorded_video_path_2}
                  >
                    Your browser does not support the video tag.
                  </video>
                ) : (
                  <div className="no-video-placeholder">
                    <p>No recording yet</p>
                  </div>
                )
              ) : (
                <video
                  ref={localVideo1Ref}
                  className="local-video"
                  onPlay={handleLocalVideoPlay}
                  onPause={handleLocalVideoPause}
                  onLoadedMetadata={handleVideo1LoadedMetadata}
                  key={`shared-${sharedRecording.id}-${sharedRecording.recorded_video_path}`}
                  src={sharedRecording.recorded_video_path}
                >
                  Your browser does not support the video tag.
                </video>
              )
            ) : (
              <div className="no-video-placeholder">
                <p>No recording yet</p>
              </div>
            )}
          </div>
        </div>

        {/* Swap button */}
        <button
          className="swap-btn"
          onClick={() => setVideosSwapped(!videosSwapped)}
          disabled={!sharedRecording?.recorded_video_path_2}
          title="Swap videos"
        >
          ⇄
        </button>

        <div className="video-section local-video-section">
          <div className="video-header">
            <h2 className="video-label">
              {sharedRecording?.recorded_video_path_2 ? (videosSwapped ? sharedRecording.name : sharedRecording.name_2) : 'Second Recording'}
            </h2>
            <p className="video-note">
              {sharedRecording?.recorded_video_path_2 ? (videosSwapped ? sharedRecording.email : sharedRecording.email_2) : (sharedRecording ? 'Waiting for second recording...' : 'No recording yet')}
            </p>
          </div>
          <div className="video-wrapper">
            {sharedRecording?.recorded_video_path_2 ? (
              videosSwapped ? (
                <video
                  ref={localVideo2Ref}
                  className="local-video"
                  onPlay={handleLocalVideoPlay}
                  onPause={handleLocalVideoPause}
                  key={`shared-1-swapped-${sharedRecording.id}-${sharedRecording.recorded_video_path}`}
                  src={sharedRecording.recorded_video_path}
                >
                  Your browser does not support the video tag.
                </video>
              ) : (
                <video
                  ref={localVideo2Ref}
                  className="local-video"
                  onPlay={handleLocalVideoPlay}
                  onPause={handleLocalVideoPause}
                  key={`shared-2-${sharedRecording.id}-${sharedRecording.recorded_video_path_2}`}
                  src={sharedRecording.recorded_video_path_2}
                >
                  Your browser does not support the video tag.
                </video>
              )
            ) : (
              <div className="no-video-placeholder">
                <p>{sharedRecording ? 'Record your interpretation above' : 'No recording yet'}</p>
              </div>
            )}
          </div>
        </div>
      </div>

      <div className="controls">
        <button
          className="control-btn toggle-btn"
          onClick={handleToggle}
          disabled={!isReady}
        >
          {isPlaying ? '⏸ Pause' : '▶ Play'}
        </button>
      </div>
      {!isReady && <p className="loading-text">Loading player...</p>}
    </div>
  );
}
