import React, { useState, useEffect, useRef } from 'react';
import Hls from 'hls.js';
import './TranslationRoom.css';

interface Language {
  label: string;
  value: string;
}

const SOURCE_VIDEO_URL = 'https://2nbyjxnbl53k-hls-live.5centscdn.com/RTV/59a49be6dc0f146c57cd9ee54da323b1.sdp/playlist.m3u8';
const RTMP_SERVER = 'rtmp://tni-ingest.cdn.cscloudws.com/translations';
const BRIDGE_SERVER_URL = 'ws://localhost:3030'; // WebSocket bridge server
// const RTMP_USERNAME = 'trans1'; // Will be used when implementing RTMP streaming
// const RTMP_PASSWORD = '244PLK'; // Will be used when implementing RTMP streaming

// Default fallback languages in case API fails
const DEFAULT_LANGUAGES: Language[] = [
  { label: 'English', value: 'en' },
  { label: 'Spanish', value: 'es' },
  { label: 'French', value: 'fr' },
  { label: 'German', value: 'de' },
  { label: 'Italian', value: 'it' }
];

const TranslationRoom: React.FC = () => {
  const [languages, setLanguages] = useState<Language[]>(DEFAULT_LANGUAGES);
  const [selectedLanguage, setSelectedLanguage] = useState<string>('');
  const [translatorName, setTranslatorName] = useState<string>('');
  const [inSession, setInSession] = useState<boolean>(false);
  const [isTranslating, setIsTranslating] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string>('');

  const sourceVideoRef = useRef<HTMLVideoElement>(null);
  const outputVideoRef = useRef<HTMLVideoElement>(null);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const audioStreamRef = useRef<MediaStream | null>(null);
  const combinedStreamRef = useRef<MediaStream | null>(null);
  const hlsInstanceRef = useRef<Hls | null>(null);
  const outputHlsRef = useRef<Hls | null>(null);
  const wsRef = useRef<WebSocket | null>(null);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const animationFrameRef = useRef<number | null>(null);

  // Fetch languages on component mount
  useEffect(() => {
    fetchLanguages();
  }, []);

  const fetchLanguages = async () => {
    try {
      setLoading(true);
      setError('');
      const response = await fetch('https://mediathek.tniglobal.org/api/rorlanguagesDropdown');
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      
      const result = await response.json();
      
      // API returns: {success: boolean, message: object, data: array}
      // Languages are in the data property
      if (result.success && result.data && Array.isArray(result.data) && result.data.length > 0) {
        setLanguages(result.data);
        console.log(`Loaded ${result.data.length} languages from API`);
      } else {
        console.error('API did not return valid language data:', result);
        setError('Failed to load languages from API. Please try again.');
      }
      
      setLoading(false);
    } catch (err) {
      console.error('Error fetching languages:', err);
      setError('Failed to load languages from API. Please try again.')
      setLoading(false);
    }
  };

  const handleJoinSession = () => {
    if (!selectedLanguage || !translatorName.trim()) {
      alert('Please select a language and enter your name');
      return;
    }
    setInSession(true);
  };

  const handleLeaveSession = () => {
    if (isTranslating) {
      stopTranslation();
    }
    setInSession(false);
    setSelectedLanguage('');
    setTranslatorName('');
  };

  // Initialize source video when entering session
  useEffect(() => {
    if (inSession && sourceVideoRef.current) {
      initializeSourceVideo();
    }

    return () => {
      if (hlsInstanceRef.current) {
        hlsInstanceRef.current.destroy();
      }
      if (outputHlsRef.current) {
        outputHlsRef.current.destroy();
      }
    };
  }, [inSession]);

  const initializeSourceVideo = () => {
    const video = sourceVideoRef.current;
    if (!video) return;

    if (Hls.isSupported()) {
      const hls = new Hls({
        enableWorker: true,
        lowLatencyMode: true,
      });
      hls.loadSource(SOURCE_VIDEO_URL);
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        video.play().catch(e => console.error('Error playing source video:', e));
      });
      hlsInstanceRef.current = hls;
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
      video.src = SOURCE_VIDEO_URL;
      video.addEventListener('loadedmetadata', () => {
        video.play().catch(e => console.error('Error playing source video:', e));
      });
    }
  };

  const startTranslation = async () => {
    try {
      setIsTranslating(true);

      // Get microphone audio
      const audioStream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
        },
        video: false,
      });

      audioStreamRef.current = audioStream;

      // Capture video from source video element
      const videoElement = sourceVideoRef.current;
      if (!videoElement) {
        throw new Error('Source video not available');
      }

      // Create canvas to capture video
      const canvas = document.createElement('canvas');
      canvas.width = videoElement.videoWidth || 1280;
      canvas.height = videoElement.videoHeight || 720;
      const ctx = canvas.getContext('2d');
      canvasRef.current = canvas;

      // Capture video frames at 30fps
      const videoStream = canvas.captureStream(30);
      
      // Draw video frames to canvas
      const drawFrame = () => {
        if (ctx && videoElement && isTranslating) {
          ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
          animationFrameRef.current = requestAnimationFrame(drawFrame);
        }
      };
      drawFrame();

      // Combine video and audio
      const combinedStream = new MediaStream([
        ...videoStream.getVideoTracks(),
        ...audioStream.getAudioTracks(),
      ]);

      combinedStreamRef.current = combinedStream;

      // Connect to WebSocket bridge server
      const ws = new WebSocket(BRIDGE_SERVER_URL);
      wsRef.current = ws;

      ws.onopen = () => {
        console.log('Connected to RTMP bridge server');
        
        // Start streaming
        ws.send(JSON.stringify({
          type: 'start',
          language: selectedLanguage
        }));

        // Use MediaRecorder to capture and send data to bridge
        const options = {
          mimeType: 'video/webm;codecs=vp8,opus',
          videoBitsPerSecond: 2500000
        };

        const mediaRecorder = new MediaRecorder(combinedStream, options);
        mediaRecorderRef.current = mediaRecorder;

        mediaRecorder.ondataavailable = (event) => {
          if (event.data.size > 0 && ws.readyState === WebSocket.OPEN) {
            // Send binary data to bridge server
            ws.send(event.data);
          }
        };

        mediaRecorder.onerror = (event) => {
          console.error('MediaRecorder error:', event);
        };

        // Start recording in chunks
        mediaRecorder.start(100); // Send data every 100ms
        
        console.log('Started streaming to RTMP via bridge server');
      };

      ws.onerror = (error) => {
        console.error('WebSocket error:', error);
        alert('Failed to connect to RTMP bridge server. Please ensure it\'s running on port 3030.');
        setIsTranslating(false);
      };

      ws.onclose = () => {
        console.log('Disconnected from bridge server');
      };

      ws.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data);
          if (data.type === 'started') {
            console.log('RTMP streaming started for:', data.streamKey);
            // Start monitoring the output stream
            setTimeout(() => {
              startOutputVideo();
            }, 3000);
          } else if (data.type === 'error') {
            console.error('Bridge server error:', data.error);
            alert(`Streaming error: ${data.error}`);
          }
        } catch (err) {
          console.log('Non-JSON message from bridge:', event.data);
        }
      };

    } catch (err) {
      console.error('Error starting translation:', err);
      alert('Failed to start translation. Please check microphone permissions.');
      setIsTranslating(false);
    }
  };

  const startOutputVideo = () => {
    const watchUrl = `https://tni-out.ceflixcdn.com/translations/${selectedLanguage}/playlist.m3u8`;
    const outputVideo = outputVideoRef.current;
    
    if (!outputVideo) return;

    console.log('Loading translated output stream:', watchUrl);

    if (Hls.isSupported()) {
      const hls = new Hls({
        enableWorker: true,
        lowLatencyMode: true,
      });
      
      hls.on(Hls.Events.ERROR, (event, data) => {
        if (data.fatal && data.type === Hls.ErrorTypes.NETWORK_ERROR) {
          console.log('HLS stream not available yet, will retry...');
          setTimeout(() => startOutputVideo(), 3000);
        }
      });

      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        console.log('Translation output stream is now available');
        outputVideo.play().catch((e: any) => console.error('Error playing output:', e));
      });

      hls.loadSource(watchUrl);
      hls.attachMedia(outputVideo);
      outputHlsRef.current = hls;
    } else if (outputVideo.canPlayType('application/vnd.apple.mpegurl')) {
      outputVideo.src = watchUrl;
      outputVideo.addEventListener('loadedmetadata', () => {
        outputVideo.play().catch((e: any) => console.error('Error playing output:', e));
      });
    }
  };

  };

  const stopTranslation = () => {
    // Stop media recorder
    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
      mediaRecorderRef.current.stop();
      mediaRecorderRef.current = null;
    }

    // Stop animation frame
    if (animationFrameRef.current) {
      cancelAnimationFrame(animationFrameRef.current);
      animationFrameRef.current = null;
    }

    // Stop all tracks
    if (audioStreamRef.current) {
      audioStreamRef.current.getTracks().forEach((track: MediaStreamTrack) => track.stop());
      audioStreamRef.current = null;
    }

    if (combinedStreamRef.current) {
      combinedStreamRef.current.getTracks().forEach((track: MediaStreamTrack) => track.stop());
      combinedStreamRef.current = null;
    }

    // Close WebSocket connection
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify({ type: 'stop' }));
      wsRef.current.close();
      wsRef.current = null;
    }

    // Clear output video
    const outputVideo = outputVideoRef.current;
    if (outputVideo) {
      outputVideo.pause();
      outputVideo.src = '';
    }

    // Stop HLS if it's running
    if (outputHlsRef.current) {
      outputHlsRef.current.destroy();
      outputHlsRef.current = null;
    }

    setIsTranslating(false);
  };

  const selectedLangObj = Array.isArray(languages) ? languages.find(l => l.value === selectedLanguage) : null;

  if (!inSession) {
    return (
      <div className="translation-container">
        <div className="translation-setup">
          <h1>🌐 Translation Room</h1>
          <p className="subtitle">Select a language and start translating live video content</p>

          {loading ? (
            <div className="loading">Loading languages...</div>
          ) : error ? (
            <div className="error">{error}</div>
          ) : (
            <div className="setup-form">
              <div className="form-group">
                <label htmlFor="translatorName">Your Name</label>
                <input
                  id="translatorName"
                  type="text"
                  placeholder="Enter your name"
                  value={translatorName}
                  onChange={(e) => setTranslatorName(e.target.value)}
                  className="translator-input"
                />
              </div>

              <div className="form-group">
                <label htmlFor="language">Target Language</label>
                <select
                  id="language"
                  value={selectedLanguage}
                  onChange={(e) => setSelectedLanguage(e.target.value)}
                  className="language-select"
                >
                  <option value="">-- Select a language --</option>
                  {languages.map((lang) => (
                    <option key={lang.value} value={lang.value}>
                      {lang.label}
                    </option>
                  ))}
                </select>
              </div>

              <button
                className="join-translation-btn"
                onClick={handleJoinSession}
                disabled={!selectedLanguage || !translatorName.trim()}
              >
                Join Translation Room
              </button>
            </div>
          )}
        </div>
      </div>
    );
  }

  return (
    <div className="translation-session">
      <header className="session-header">
        <div className="header-info">
          <h2>🌐 Translation Room - {selectedLangObj?.label}</h2>
          <span className="translator-badge">{translatorName}</span>
        </div>
        <button className="leave-session-btn" onClick={handleLeaveSession}>
          ← Leave Session
        </button>
      </header>

      <div className="video-grid">
        <div className="video-panel">
          <div className="panel-header">
            <h3>📺 Source Video</h3>
            <span className="status-badge source">Live</span>
          </div>
          <div className="video-wrapper">
            <video
              ref={sourceVideoRef}
              className="translation-video"
              controls
              muted
              playsInline
            />
          </div>
        </div>

        <div className="video-panel">
          <div className="panel-header">
            <h3>🎙️ Translation Output</h3>
            <span className={`status-badge ${isTranslating ? 'streaming' : 'waiting'}`}>
              {isTranslating ? 'Streaming' : 'Waiting'}
            </span>
          </div>
          <div className="video-wrapper">
            <video
              ref={outputVideoRef}
              className="translation-video"
              controls
              playsInline
            />
          </div>
        </div>
      </div>

      <div className="control-panel">
        <div className="stream-info">
          <div className="info-item">
            <strong>RTMP Server:</strong> {RTMP_SERVER}
          </div>
          <div className="info-item">
            <strong>Stream Key:</strong> {selectedLanguage}
          </div>
          <div className="info-item">
            <strong>Watch URL:</strong> https://tni-out.ceflixcdn.com/translations/{selectedLanguage}/playlist.m3u8
          </div>
        </div>

        <div className="control-buttons">
          {!isTranslating ? (
            <button className="start-btn" onClick={startTranslation}>
              🎙️ Start Translating
            </button>
          ) : (
            <button className="stop-btn" onClick={stopTranslation}>
              ⏹️ Stop Streaming
            </button>
          )}
        </div>

        <div className="rtmp-note">
          <strong>Note:</strong> Direct RTMP streaming from browser requires a server-side bridge (WebRTC-to-RTMP).
          Consider using OBS Browser Source or a streaming server for production use.
        </div>
      </div>
    </div>
  );
};

export default TranslationRoom;
