/**
 * SttBenchmarkPage — Compare STT v1 (latest_long) vs v2 (Chirp 2).
 * SysAdmin only. Upload audio, run both engines, compare results.
 */

import React, { useState, useEffect, useRef, useCallback } from 'react';
import { FaMicrophone, FaUpload, FaPlay, FaStop, FaSpinner } from 'react-icons/fa';
import { useLanguage } from '../../providers/language/LanguageContext';
import { useApiRequest } from '../../hooks/useApi';
import styles from '../admin/Admin.module.css';

interface ModelOption { value: string; label: string }
interface BenchmarkResult {
  api: string;
  model: string;
  latencyMs: number;
  results: { transcript: string; confidence: number; words: number }[];
  resultCount: number;
  location?: string;
  error?: string;
}
interface BenchmarkResponse {
  filename: string;
  fileSizeBytes: number;
  language: string;
  v1: BenchmarkResult | { error: string };
  v2: BenchmarkResult | { error: string };
}
interface ModelsResponse {
  v1Models: ModelOption[];
  v2Models: ModelOption[];
  locations: ModelOption[];
  languages: ModelOption[];
}

export const SttBenchmarkPage: React.FC = () => {
  const { t } = useLanguage();
  const { request } = useApiRequest();

  const [models, setModels] = useState<ModelsResponse | null>(null);
  const [language, setLanguage] = useState('de-DE');
  const [v1Model, setV1Model] = useState('latest_long');
  const [v2Model, setV2Model] = useState('chirp_2');
  const [v2Location, setV2Location] = useState('europe-west4');
  const [running, setRunning] = useState(false);
  const [result, setResult] = useState<BenchmarkResponse | null>(null);

  const [recording, setRecording] = useState(false);
  const [audioBlob, setAudioBlob] = useState<Blob | null>(null);
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    request({ url: '/api/admin/stt-benchmark/models', method: 'get' })
      .then((data: any) => setModels(data))
      .catch(() => {});
  }, []);

  const _startRecording = useCallback(async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm;codecs=opus' });
      chunksRef.current = [];
      recorder.ondataavailable = (e) => { if (e.data.size > 0) chunksRef.current.push(e.data); };
      recorder.onstop = () => {
        const blob = new Blob(chunksRef.current, { type: 'audio/webm' });
        setAudioBlob(blob);
        setAudioUrl(URL.createObjectURL(blob));
        stream.getTracks().forEach(t => t.stop());
      };
      mediaRecorderRef.current = recorder;
      recorder.start();
      setRecording(true);
    } catch (err) {
      console.error('Microphone access denied', err);
    }
  }, []);

  const _stopRecording = useCallback(() => {
    mediaRecorderRef.current?.stop();
    setRecording(false);
  }, []);

  const _handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setAudioBlob(file);
    setAudioUrl(URL.createObjectURL(file));
  }, []);

  const _runBenchmark = useCallback(async () => {
    if (!audioBlob) return;
    setRunning(true);
    setResult(null);
    try {
      const formData = new FormData();
      const filename = audioBlob instanceof File ? audioBlob.name : 'recording.webm';
      formData.append('file', audioBlob, filename);
      formData.append('language', language);
      formData.append('v1Model', v1Model);
      formData.append('v2Model', v2Model);
      formData.append('v2Location', v2Location);

      const resp = await fetch('/api/admin/stt-benchmark/run', {
        method: 'POST',
        body: formData,
        credentials: 'include',
      });
      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
      const data: BenchmarkResponse = await resp.json();
      setResult(data);
    } catch (err: any) {
      console.error('Benchmark failed:', err);
    } finally {
      setRunning(false);
    }
  }, [audioBlob, language, v1Model, v2Model, v2Location]);

  const _renderResult = (label: string, r: BenchmarkResult | { error: string }) => {
    if ('error' in r && r.error) {
      return (
        <div style={{ flex: 1, padding: 16, border: '1px solid #e74c3c', borderRadius: 8, background: '#fdf2f2' }}>
          <h3>{label}</h3>
          <p style={{ color: '#e74c3c' }}>{r.error}</p>
        </div>
      );
    }
    const res = r as BenchmarkResult;
    const topTranscript = res.results?.[0]?.transcript || '(no result)';
    const topConfidence = res.results?.[0]?.confidence ?? 0;
    return (
      <div style={{ flex: 1, padding: 16, border: '1px solid #ddd', borderRadius: 8, background: '#fafafa' }}>
        <h3 style={{ margin: '0 0 8px' }}>{label}</h3>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 12 }}>
          <div><strong>{t('Modell')}:</strong> {res.model}</div>
          <div><strong>{t('Latenz')}:</strong> {res.latencyMs} ms</div>
          <div><strong>{t('Konfidenz')}:</strong> {(topConfidence * 100).toFixed(1)}%</div>
          <div><strong>{t('Alternativen')}:</strong> {res.results?.length || 0}</div>
          {res.location && <div><strong>{t('Region')}:</strong> {res.location}</div>}
        </div>
        <div style={{ background: '#fff', padding: 12, borderRadius: 6, border: '1px solid #eee', fontSize: 15 }}>
          {topTranscript}
        </div>
        {res.results?.length > 1 && (
          <details style={{ marginTop: 8 }}>
            <summary style={{ cursor: 'pointer', fontSize: 13, color: '#666' }}>{t('Weitere Alternativen')}</summary>
            {res.results.slice(1).map((alt, i) => (
              <div key={i} style={{ marginTop: 4, fontSize: 13, color: '#888' }}>
                [{(alt.confidence * 100).toFixed(1)}%] {alt.transcript}
              </div>
            ))}
          </details>
        )}
      </div>
    );
  };

  return (
    <div className={styles.adminPage}>
      <div className={styles.adminHeader}>
        <h1><FaMicrophone style={{ marginRight: 8 }} /> {t('STT Benchmark')}</h1>
        <p style={{ color: '#666', margin: '4px 0 0' }}>
          {t('Vergleiche Speech-to-Text v1 (latest_long) mit v2 (Chirp 2). Lade eine Audio-Datei hoch oder nimm direkt auf.')}
        </p>
      </div>

      <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', margin: '20px 0' }}>
        <label>
          <strong>{t('Sprache')}:</strong>
          <select value={language} onChange={e => setLanguage(e.target.value)} style={{ marginLeft: 8 }}>
            {(models?.languages || [{ value: 'de-DE', label: 'Deutsch' }]).map(l => (
              <option key={l.value} value={l.value}>{l.label}</option>
            ))}
          </select>
        </label>
        <label>
          <strong>v1 {t('Modell')}:</strong>
          <select value={v1Model} onChange={e => setV1Model(e.target.value)} style={{ marginLeft: 8 }}>
            {(models?.v1Models || [{ value: 'latest_long', label: 'latest_long' }]).map(m => (
              <option key={m.value} value={m.value}>{m.label}</option>
            ))}
          </select>
        </label>
        <label>
          <strong>v2 {t('Modell')}:</strong>
          <select value={v2Model} onChange={e => setV2Model(e.target.value)} style={{ marginLeft: 8 }}>
            {(models?.v2Models || [{ value: 'chirp_2', label: 'Chirp 2' }]).map(m => (
              <option key={m.value} value={m.value}>{m.label}</option>
            ))}
          </select>
        </label>
        <label>
          <strong>{t('Region')} (v2):</strong>
          <select value={v2Location} onChange={e => setV2Location(e.target.value)} style={{ marginLeft: 8 }}>
            {(models?.locations || [{ value: 'europe-west4', label: 'Europe West' }]).map(l => (
              <option key={l.value} value={l.value}>{l.label}</option>
            ))}
          </select>
        </label>
      </div>

      <div style={{ display: 'flex', gap: 12, alignItems: 'center', margin: '16px 0' }}>
        {!recording ? (
          <button onClick={_startRecording} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 16px', cursor: 'pointer', background: '#e74c3c', color: '#fff', border: 'none', borderRadius: 6 }}>
            <FaMicrophone /> {t('Aufnehmen')}
          </button>
        ) : (
          <button onClick={_stopRecording} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 16px', cursor: 'pointer', background: '#333', color: '#fff', border: 'none', borderRadius: 6, animation: 'pulse 1s infinite' }}>
            <FaStop /> {t('Stoppen')}
          </button>
        )}

        <button onClick={() => fileInputRef.current?.click()} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 16px', cursor: 'pointer', background: '#3498db', color: '#fff', border: 'none', borderRadius: 6 }}>
          <FaUpload /> {t('Datei hochladen')}
        </button>
        <input ref={fileInputRef} type="file" accept="audio/*" onChange={_handleFileSelect} style={{ display: 'none' }} />

        {audioBlob && (
          <>
            <span style={{ color: '#666', fontSize: 13 }}>
              {audioBlob instanceof File ? audioBlob.name : 'recording.webm'} ({(audioBlob.size / 1024).toFixed(0)} KB)
            </span>
            {audioUrl && <audio src={audioUrl} controls style={{ height: 32 }} />}
          </>
        )}
      </div>

      <button
        onClick={_runBenchmark}
        disabled={!audioBlob || running}
        style={{
          display: 'flex', alignItems: 'center', gap: 8, padding: '10px 24px', cursor: audioBlob && !running ? 'pointer' : 'not-allowed',
          background: audioBlob && !running ? '#27ae60' : '#bdc3c7', color: '#fff', border: 'none', borderRadius: 6, fontSize: 15, fontWeight: 600,
        }}
      >
        {running ? <FaSpinner className="fa-spin" /> : <FaPlay />}
        {running ? t('Benchmark laeuft...') : t('Benchmark starten')}
      </button>

      {result && (
        <div style={{ marginTop: 24 }}>
          <h2>{t('Ergebnis')}</h2>
          <p style={{ fontSize: 13, color: '#888' }}>
            {result.filename} ({(result.fileSizeBytes / 1024).toFixed(0)} KB) — {result.language}
          </p>
          <div style={{ display: 'flex', gap: 16, marginTop: 12 }}>
            {_renderResult(`v1 — ${(result.v1 as any).model || v1Model}`, result.v1)}
            {_renderResult(`v2 — ${(result.v2 as any).model || v2Model}`, result.v2)}
          </div>
        </div>
      )}
    </div>
  );
};

export default SttBenchmarkPage;
