import { useState, useEffect, useRef } from 'react';
import Navbar from './components/Navbar';
import DashboardTab from './components/DashboardTab';
import TextTranslationTab from './components/TextTranslationTab';
import DocumentTranslationTab from './components/DocumentTranslationTab';
import AudioTranslationTab from './components/AudioTranslationTab';
import VideoTranslationTab from './components/VideoTranslationTab';
import SettingsTab from './components/SettingsTab';
import { LanguageProvider, useLang } from './LanguageContext';

function AppInner() {
  const { t } = useLang();
  const [activeTab, setActiveTab] = useState('dashboard');

  const [modelsStatus, setModelsStatus] = useState({
    is_cached: false,
    whisper_cached: false,
    nllb_cached: false,
    tts_cached: false,
    models_dir: ''
  });
  const [isConnected, setIsConnected] = useState(true);
  const [whisperSize, setWhisperSize] = useState('base');

  // Text Translation States
  const [textInput, setTextInput] = useState('');
  const [textOutput, setTextOutput] = useState('');
  const [textSrcLang, setTextSrcLang] = useState('auto');
  const [textTgtLang, setTextTgtLang] = useState('Hindi');
  const [detectedTextLang, setDetectedTextLang] = useState('');
  const [isTranslatingText, setIsTranslatingText] = useState(false);
  const [ttsAudioUrl, setTtsAudioUrl] = useState('');
  const [isGeneratingTts, setIsGeneratingTts] = useState(false);

  // Audio Translation States
  const [audioFile, setAudioFile] = useState(null);
  const [audioSrcLang, setAudioSrcLang] = useState('auto');
  const [audioTgtLang, setAudioTgtLang] = useState('Hindi');
  const [isProcessingAudio, setIsProcessingAudio] = useState(false);
  const [audioProgress, setAudioProgress] = useState(0);
  const [audioProgressText, setAudioProgressText] = useState('');
  const [audioResult, setAudioResult] = useState(null);
  const [audioActiveSubTab, setAudioActiveSubTab] = useState('translation');
  const [isRecording, setIsRecording] = useState(false);
  const [recordingTime, setRecordingTime] = useState(0);
  const mediaRecorderRef = useRef(null);
  const audioChunksRef = useRef([]);
  const timerRef = useRef(null);

  // Video Translation States
  const [videoFile, setVideoFile] = useState(null);
  const [videoSrcLang, setVideoSrcLang] = useState('auto');
  const [videoTgtLang, setVideoTgtLang] = useState('Hindi');
  const [burnSubtitles, setBurnSubtitles] = useState(true);
  const [overlayVoice, setOverlayVoice] = useState(false);
  const [isProcessingVideo, setIsProcessingVideo] = useState(false);
  const [videoProgress, setVideoProgress] = useState(0);
  const [videoProgressText, setVideoProgressText] = useState('');
  const [videoResult, setVideoResult] = useState(null);
  const [isMenuOpen, setIsMenuOpen] = useState(false);

  // Document Translation States
  const [docFile, setDocFile] = useState(null);
  const [docSrcLang, setDocSrcLang] = useState('auto');
  const [docTgtLang, setDocTgtLang] = useState('Hindi');
  const [isProcessingDoc, setIsProcessingDoc] = useState(false);
  const [docResult, setDocResult] = useState(null);

  const pageTitles = {
    dashboard: t('page.dashboard'),
    text:      t('page.text'),
    docs:      t('page.docs'),
    audio:     t('page.audio'),
    video:     t('page.video'),
    settings:  t('page.settings'),
  };

  const pageSubtitles = {
    dashboard: t('page.dashboardSub'),
    text:      t('page.textSub'),
    docs:      t('page.docsSub'),
    audio:     t('page.audioSub'),
    video:     t('page.videoSub'),
    settings:  t('page.settingsSub'),
  };

  const checkServerStatus = async () => {
    try {
      const res = await fetch('/api/models-status');
      if (res.ok) {
        const data = await res.json();
        setModelsStatus(data);
        setIsConnected(true);
      } else {
        setIsConnected(false);
      }
    } catch {
      setIsConnected(false);
    }
  };

  useEffect(() => {
    let cancelled = false;
    const interval = setInterval(async () => {
      try {
        const res = await fetch('/api/models-status');
        if (!cancelled) {
          if (res.ok) {
            const data = await res.json();
            setModelsStatus(data);
            setIsConnected(true);
          } else {
            setIsConnected(false);
          }
        }
      } catch {
        if (!cancelled) setIsConnected(false);
      }
    }, 5000);
    return () => { cancelled = true; clearInterval(interval); };
  }, []);

  const handleTextTranslate = async () => {
    if (!textInput.trim()) return;
    setIsTranslatingText(true);
    setTtsAudioUrl('');
    try {
      const res = await fetch('/api/translate-text', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          text: textInput,
          src_lang: textSrcLang,
          tgt_lang: textTgtLang
        })
      });
      if (res.ok) {
        const data = await res.json();
        setTextOutput(data.translated_text);
        if (data.detected_src_lang) {
          setDetectedTextLang(data.detected_src_lang);
        }
      } else {
        alert('Translation failed. Please make sure the backend is running and models are loaded.');
      }
    } catch {
      alert('Network error connecting to backend.');
    } finally {
      setIsTranslatingText(false);
    }
  };

  const handleTextToSpeech = async () => {
    if (!textOutput.trim()) return;
    setIsGeneratingTts(true);
    try {
      const res = await fetch('/api/text-to-speech', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          text: textOutput,
          lang: textTgtLang
        })
      });
      if (res.ok) {
        const blob = await res.blob();
        const audioUrl = URL.createObjectURL(blob);
        setTtsAudioUrl(audioUrl);
      } else {
        alert('TTS Synthesis failed.');
      }
    } catch {
      alert('Error generating TTS.');
    } finally {
      setIsGeneratingTts(false);
    }
  };

  const startRecording = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      mediaRecorderRef.current = new MediaRecorder(stream);
      audioChunksRef.current = [];

      mediaRecorderRef.current.ondataavailable = (e) => {
        if (e.data.size > 0) audioChunksRef.current.push(e.data);
      };

      mediaRecorderRef.current.onstop = () => {
        const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/wav' });
        const file = new File([audioBlob], "recorded_audio.wav", { type: 'audio/wav' });
        setAudioFile(file);
        setAudioResult(null);
        stream.getTracks().forEach(track => track.stop());
      };

      mediaRecorderRef.current.start();
      setIsRecording(true);
      setRecordingTime(0);
      timerRef.current = setInterval(() => {
        setRecordingTime(prev => prev + 1);
      }, 1000);
    } catch (err) {
      alert('Could not access microphone: ' + err.message);
    }
  };

  const stopRecording = () => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      setIsRecording(false);
      clearInterval(timerRef.current);
    }
  };

  const handleAudioUpload = (e) => {
    const file = e.target.files[0];
    if (file) {
      setAudioFile(file);
      setAudioResult(null);
    }
  };

  const processAudio = async () => {
    if (!audioFile) return;
    setIsProcessingAudio(true);
    setAudioProgress(10);
    setAudioProgressText('Uploading audio file and initializing pipeline...');

    const formData = new FormData();
    formData.append('file', audioFile);
    formData.append('model_size', whisperSize);
    formData.append('src_lang', audioSrcLang);
    formData.append('tgt_lang', audioTgtLang);

    try {
      const progressInterval = setInterval(() => {
        setAudioProgress((prev) => {
          if (prev >= 90) { clearInterval(progressInterval); return prev; }
          if (prev >= 70) { setAudioProgressText('Translating text segments and synthesizing dubbing audio...'); return prev + 1; }
          if (prev >= 40) { setAudioProgressText('Transcribing speech offline using Whisper ASR...'); return prev + 2; }
          return prev + 5;
        });
      }, 800);

      const res = await fetch('/api/translate-audio', {
        method: 'POST',
        body: formData
      });

      clearInterval(progressInterval);

      if (res.ok) {
        setAudioProgress(100);
        setAudioProgressText('Synthesis complete!');
        const data = await res.json();
        setAudioResult(data);
      } else {
        alert('Audio processing failed. Check backend logs.');
        setIsProcessingAudio(false);
      }
    } catch {
      alert('Error connecting to backend.');
      setIsProcessingAudio(false);
    } finally {
      setTimeout(() => {
        setIsProcessingAudio(false);
        setAudioProgress(0);
      }, 1000);
    }
  };

  const handleVideoUpload = (e) => {
    const file = e.target.files[0];
    if (file) {
      setVideoFile(file);
      setVideoResult(null);
    }
  };

  const pollJob = async (job_id, onSuccess, onFail, onProgress) => {
    const interval = setInterval(async () => {
      try {
        const res = await fetch(`/api/jobs/${job_id}`);
        if (res.ok) {
          const job = await res.json();
          if (onProgress) onProgress(job.progress, job.status);

          if (job.status === 'completed') {
            clearInterval(interval);
            onSuccess(job.result);
          } else if (job.status === 'failed') {
            clearInterval(interval);
            onFail(job.error || 'Job failed');
          }
        } else {
          clearInterval(interval);
          onFail('Error checking job status');
        }
      } catch {
        clearInterval(interval);
        onFail('Network error checking job status');
      }
    }, 2000);
    return interval;
  };

  const processVideo = async () => {
    if (!videoFile) return;
    setIsProcessingVideo(true);
    setVideoProgress(5);
    setVideoProgressText('Uploading video track. Initializing workspace...');

    const formData = new FormData();
    formData.append('file', videoFile);
    formData.append('model_size', whisperSize);
    formData.append('src_lang', videoSrcLang);
    formData.append('tgt_lang', videoTgtLang);
    formData.append('burn_subtitles_option', burnSubtitles);
    formData.append('overlay_voice_option', overlayVoice);

    try {
      const res = await fetch('/api/process-video', {
        method: 'POST',
        body: formData
      });

      if (res.ok) {
        const { job_id } = await res.json();
        pollJob(
          job_id,
          (result) => {
            setVideoResult(result);
            setVideoProgress(100);
            setVideoProgressText('Video processed successfully!');
            setTimeout(() => {
              setIsProcessingVideo(false);
              setVideoProgress(0);
            }, 1000);
          },
          (error) => {
            alert(`Video processing failed: ${error}`);
            setIsProcessingVideo(false);
          },
          (progress, status) => {
            setVideoProgress(progress);
            if (status === 'processing') {
              if (progress < 40) setVideoProgressText('Running speech-to-text extraction using Whisper...');
              else if (progress < 70) setVideoProgressText('Translating timeline and rendering transcript overlays...');
              else setVideoProgressText('Injecting subtitle layers and copying streams with FFmpeg...');
            }
          }
        );
      } else {
        alert('Video processing failed to start.');
        setIsProcessingVideo(false);
      }
    } catch {
      alert('Error connecting to video processing endpoint.');
      setIsProcessingVideo(false);
    }
  };

  const handleDocUpload = (e) => {
    const file = e.target.files[0];
    if (file) {
      setDocFile(file);
      setDocResult(null);
    }
  };

  const processDoc = async () => {
    if (!docFile) return;
    setIsProcessingDoc(true);

    const formData = new FormData();
    formData.append('file', docFile);
    formData.append('src_lang', docSrcLang);
    formData.append('tgt_lang', docTgtLang);

    try {
      const res = await fetch('/api/translate-document', {
        method: 'POST',
        body: formData
      });

      if (res.ok) {
        const { job_id } = await res.json();
        pollJob(
          job_id,
          (result) => {
            setDocResult(result);
            setIsProcessingDoc(false);
          },
          (error) => {
            alert(`Document translation failed: ${error}`);
            setIsProcessingDoc(false);
          }
        );
      } else {
        alert('Document translation failed to start.');
        setIsProcessingDoc(false);
      }
    } catch {
      alert('Error connecting to backend.');
      setIsProcessingDoc(false);
    }
  };

  return (
    <div className="app-container">

      <Navbar
        activeTab={activeTab}
        setActiveTab={setActiveTab}
        isMenuOpen={isMenuOpen}
        setIsMenuOpen={setIsMenuOpen}
        isConnected={isConnected}
      />

      <div className="main-content">
        <div className="header-container">
          <h1 className="page-title">{pageTitles[activeTab]}</h1>
          <p className="page-subtitle">{pageSubtitles[activeTab]}</p>
        </div>

        {activeTab === 'dashboard' && <DashboardTab setActiveTab={setActiveTab} />}

        {activeTab === 'text' && (
          <TextTranslationTab
            textInput={textInput} setTextInput={setTextInput}
            textOutput={textOutput}
            textSrcLang={textSrcLang} setTextSrcLang={setTextSrcLang}
            textTgtLang={textTgtLang} setTextTgtLang={setTextTgtLang}
            detectedTextLang={detectedTextLang}
            isTranslatingText={isTranslatingText} handleTextTranslate={handleTextTranslate}
            ttsAudioUrl={ttsAudioUrl}
            isGeneratingTts={isGeneratingTts} handleTextToSpeech={handleTextToSpeech}
          />
        )}

        {activeTab === 'docs' && (
          <DocumentTranslationTab
            docFile={docFile} handleDocUpload={handleDocUpload}
            docSrcLang={docSrcLang} setDocSrcLang={setDocSrcLang}
            docTgtLang={docTgtLang} setDocTgtLang={setDocTgtLang}
            isProcessingDoc={isProcessingDoc} processDoc={processDoc}
            docResult={docResult}
          />
        )}

        {activeTab === 'audio' && (
          <AudioTranslationTab
            audioFile={audioFile} handleAudioUpload={handleAudioUpload}
            audioSrcLang={audioSrcLang} setAudioSrcLang={setAudioSrcLang}
            audioTgtLang={audioTgtLang} setAudioTgtLang={setAudioTgtLang}
            isProcessingAudio={isProcessingAudio} processAudio={processAudio}
            audioProgress={audioProgress} audioProgressText={audioProgressText}
            audioResult={audioResult}
            audioActiveSubTab={audioActiveSubTab} setAudioActiveSubTab={setAudioActiveSubTab}
            isRecording={isRecording} startRecording={startRecording} stopRecording={stopRecording}
            recordingTime={recordingTime}
          />
        )}

        {activeTab === 'video' && (
          <VideoTranslationTab
            videoFile={videoFile} handleVideoUpload={handleVideoUpload}
            videoSrcLang={videoSrcLang} setVideoSrcLang={setVideoSrcLang}
            videoTgtLang={videoTgtLang} setVideoTgtLang={setVideoTgtLang}
            burnSubtitles={burnSubtitles} setBurnSubtitles={setBurnSubtitles}
            overlayVoice={overlayVoice} setOverlayVoice={setOverlayVoice}
            isProcessingVideo={isProcessingVideo} processVideo={processVideo}
            videoProgress={videoProgress} videoProgressText={videoProgressText}
            videoResult={videoResult}
          />
        )}

        {activeTab === 'settings' && (
          <SettingsTab
            whisperSize={whisperSize} setWhisperSize={setWhisperSize}
            isConnected={isConnected} modelsStatus={modelsStatus}
            checkServerStatus={checkServerStatus}
          />
        )}
      </div>

      <footer className="app-footer">
        <div className="footer-brand">
          <span>🌾</span>
          {t('footer.brand')}
        </div>
        <div className="footer-copy">© {new Date().getFullYear()} {t('footer.copyright')}</div>
      </footer>
    </div>
  );
}

function App() {
  return (
    <LanguageProvider>
      <AppInner />
    </LanguageProvider>
  );
}

export default App;
