import { useState, useEffect, useCallback } from 'react';
import useLabStore from '../store/labStore';
import { listOllamaModels, getOllamaModel, setOllamaModel } from '../services/localLLM';

// ── Sub-components ────────────────────────────────────────────────────────────

function StatusBadge({ status }) {
  if (status.usesSay) {
    return (
      <span className="px-2.5 py-1 rounded-full text-xs font-medium bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
        Ready (macOS Voice)
      </span>
    );
  }
  if (status.available) {
    return (
      <span className="px-2.5 py-1 rounded-full text-xs font-medium bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
        Ready
      </span>
    );
  }
  if (status.modelsDownloaded && !status.binaryPresent) {
    return (
      <span className="px-2.5 py-1 rounded-full text-xs font-medium bg-amber-500/10 text-amber-400 border border-amber-500/20">
        Binary missing
      </span>
    );
  }
  if (!status.modelsDownloaded && status.binaryPresent) {
    return (
      <span className="px-2.5 py-1 rounded-full text-xs font-medium bg-amber-500/10 text-amber-400 border border-amber-500/20">
        Model not installed
      </span>
    );
  }
  return (
    <span className="px-2.5 py-1 rounded-full text-xs font-medium bg-white/[0.04] text-slate-500 border border-white/[0.06]">
      Not installed
    </span>
  );
}

function ProgressBar({ progress }) {
  const { status, percent, file, error } = progress || {};

  if (status === 'error') {
    return (
      <p className="text-xs text-red-400 mb-3">
        Installation failed{error ? `: ${error}` : ''}. Check your internet connection and try again.
      </p>
    );
  }

  if (status === 'exists' || status === 'complete') {
    return (
      <div className="flex items-center gap-2 mb-3">
        <div className="w-4 h-4 rounded-full bg-emerald-500/20 flex items-center justify-center flex-shrink-0">
          <svg className="w-2.5 h-2.5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
            <path strokeLinecap="round" strokeLinejoin="round" d="m4.5 12.75 6 6 9-13.5" />
          </svg>
        </div>
        <p className="text-xs text-emerald-400">{file ? `${file} — ` : ''}{status === 'exists' ? 'already installed' : 'done'}</p>
      </div>
    );
  }

  if (status === 'downloading' || status === 'starting') {
    const pct = typeof percent === 'number' ? percent : null;
    return (
      <div className="space-y-1.5 mb-3">
        <div className="flex-1 h-1.5 bg-white/[0.06] rounded-full overflow-hidden">
          <div
            className={`h-full progress-bar-fill rounded-full transition-all duration-300 ${pct === null ? 'animate-pulse' : ''}`}
            style={{ width: pct !== null ? `${pct}%` : '40%' }}
          />
        </div>
        <p className="text-xs text-slate-400">
          {pct !== null ? `${pct}%` : 'Preparing…'}
          {file ? ` — ${file}` : ''}
        </p>
      </div>
    );
  }

  return null;
}

// ── Main screen ───────────────────────────────────────────────────────────────

export default function SettingsScreen() {
  const { navigate, useLocalAI, setUseLocalAI, theme, setTheme } = useLabStore();
  const [downloading, setDownloading] = useState({ piper: false, whisper: false });
  const [status, setStatus]           = useState({
    piper:   { available: false, modelsDownloaded: false, binaryPresent: false },
    whisper: { available: false, modelsDownloaded: false, binaryPresent: false },
  });
  const [progress, setProgress]       = useState({});
  const [ollamaModels, setOllamaModels] = useState([]);
  const [selectedModel, setSelectedModel] = useState(getOllamaModel());
  const [modelSaved, setModelSaved]   = useState(false);

  const checkStatus = useCallback(async () => {
    if (!window.electronAPI?.download) return;
    try {
      const s = await window.electronAPI.download.status();
      setStatus({
        piper:   s.piper   || { available: false, modelsDownloaded: false, binaryPresent: false },
        whisper: s.whisper || { available: false, modelsDownloaded: false, binaryPresent: false },
      });
    } catch (err) {
      console.warn('Failed to check download status:', err);
    }
  }, []);

  useEffect(() => {
    checkStatus();
    listOllamaModels().then(setOllamaModels);

    if (window.electronAPI) {
      window.electronAPI.config.get('ollamaModel').then(saved => {
        if (saved) { setOllamaModel(saved); setSelectedModel(saved); }
      });
      window.electronAPI.config.get('useLocalAI').then(saved => {
        if (saved != null) setUseLocalAI(saved);
      });
    }

    // Register progress listener — capture the returned cleanup fn
    let cleanup;
    if (window.electronAPI?.download?.onProgress) {
      cleanup = window.electronAPI.download.onProgress((data) => {
        setProgress(prev => ({ ...prev, [data.type]: data }));

        if (data.status === 'complete' || data.status === 'error') {
          setDownloading(prev => ({ ...prev, [data.type]: false }));
          checkStatus();
        }
      });
    }

    return () => { if (typeof cleanup === 'function') cleanup(); };
  }, [checkStatus, setUseLocalAI]);

  const downloadModel = async (type) => {
    if (!window.electronAPI?.download) return;
    setDownloading(prev => ({ ...prev, [type]: true }));
    setProgress(prev => ({ ...prev, [type]: { status: 'starting', percent: 0 } }));
    try {
      await window.electronAPI.download.start(type);
      await checkStatus();
    } catch (err) {
      console.error('Download failed:', err);
      setProgress(prev => ({ ...prev, [type]: { status: 'error', error: err.message } }));
    } finally {
      setDownloading(prev => ({ ...prev, [type]: false }));
    }
  };

  const saveOllamaModel = async (model) => {
    setOllamaModel(model);
    setSelectedModel(model);
    if (window.electronAPI) await window.electronAPI.config.set('ollamaModel', model);
    setModelSaved(true);
    setTimeout(() => setModelSaved(false), 2000);
  };

  const toggleLocalAI = async (value) => {
    setUseLocalAI(value);
    if (window.electronAPI) await window.electronAPI.config.set('useLocalAI', value);
  };

  const isElectron = !!window.electronAPI;

  // ── Model card helper ───────────────────────────────────────────────────────

  const platform = window.electronAPI?.platform;

  const ModelCard = ({ type, label, subtitle, iconColor, iconBg, icon, size }) => {
    const s = status[type];
    const isDownloading = downloading[type];
    const prog = progress[type];
    // macOS TTS is always ready via built-in 'say' — no install needed
    const isAutoReady = s.usesSay;
    const alreadyInstalled = s.modelsDownloaded && s.binaryPresent;

    return (
      <div className="glass rounded-2xl p-5 mb-4">
        <div className="flex items-center justify-between mb-3">
          <div className="flex items-center gap-3">
            <div className={`w-10 h-10 rounded-xl ${iconBg} flex items-center justify-center`}>
              <svg className={`w-5 h-5 ${iconColor}`} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                {icon}
              </svg>
            </div>
            <div>
              <h3 className="font-semibold text-sm">{label}</h3>
              <p className="text-xs text-slate-500">{subtitle}</p>
            </div>
          </div>
          <StatusBadge status={s} />
        </div>

        {/* Binary missing warning */}
        {!isAutoReady && s.modelsDownloaded && !s.binaryPresent && (
          <div className="bg-amber-500/10 border border-amber-500/20 rounded-xl px-3 py-2 mb-3">
            <p className="text-xs text-amber-400">
              Model installed but the {type === 'piper' ? 'Piper' : 'Whisper'} runtime is missing.
              Click Install to download it automatically.
            </p>
          </div>
        )}

        <p className="text-xs text-slate-400 mb-4">
          {isAutoReady
            ? 'Uses macOS built-in voice synthesis — works offline with no setup required.'
            : `Installs an offline ${type === 'piper' ? 'voice synthesis' : 'speech recognition'} engine (${size}). Enables ${type === 'piper' ? 'voice output' : 'voice input'} without internet after installation.`
          }
        </p>

        {/* Progress bar (shown while installing) */}
        {isDownloading && <ProgressBar progress={prog} />}

        {/* Install button — hidden for auto-ready and while installing */}
        {!isAutoReady && !isDownloading && (
          <button
            onClick={() => downloadModel(type)}
            disabled={!isElectron || alreadyInstalled}
            className={`px-4 py-2 rounded-xl text-sm font-medium transition-all ${
              alreadyInstalled
                ? 'bg-white/[0.04] text-slate-500 cursor-not-allowed'
                : 'accent-gradient accent-glow-sm text-white'
            }`}
          >
            {alreadyInstalled ? 'Installed' : 'Install'}
          </button>
        )}
      </div>
    );
  };

  // ── Render ──────────────────────────────────────────────────────────────────

  return (
    <div className="min-h-screen bg-mesh text-white flex flex-col">
      <header className="glass border-0 border-b border-white/[0.06] px-5 py-3 flex items-center gap-3">
        <button
          onClick={() => navigate('dashboard')}
          className="text-slate-400 hover:text-white transition-colors p-1.5 rounded-lg hover:bg-white/[0.05]"
        >
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
          </svg>
        </button>
        <p className="font-semibold text-sm">Settings</p>
      </header>

      <main className="flex-1 p-6 max-w-2xl mx-auto w-full animate-slide-up">
        <h1 className="text-xl font-bold mb-6 tracking-tight">AI Models</h1>

        {!isElectron && (
          <div className="bg-amber-500/10 border border-amber-500/20 rounded-2xl p-4 mb-6 animate-fade-in">
            <p className="text-amber-400 text-sm">
              Model downloads are only available in the desktop app. You are currently running in browser mode.
            </p>
          </div>
        )}

        {/* TTS */}
        <ModelCard
          type="piper"
          label="Text-to-Speech (TTS)"
          subtitle="Piper — Offline voice synthesis"
          iconColor="text-blue-400"
          iconBg="bg-blue-500/15"
          size="~63 MB"
          icon={
            <path strokeLinecap="round" strokeLinejoin="round" d="M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" />
          }
        />

        {/* STT */}
        <ModelCard
          type="whisper"
          label="Speech-to-Text (STT)"
          subtitle="Whisper — Offline voice recognition"
          iconColor="text-rose-400"
          iconBg="bg-rose-500/15"
          size="~75 MB"
          icon={
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z" />
          }
        />

        {/* AI Source */}
        <div className="glass rounded-2xl p-5 mb-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 rounded-xl bg-purple-500/15 flex items-center justify-center">
                <svg className="w-5 h-5 text-purple-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.455 2.456L21.75 6l-1.036.259a3.375 3.375 0 0 0-2.455 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z" />
                </svg>
              </div>
              <div>
                <h3 className="font-semibold text-sm">AI Source</h3>
                <p className="text-xs text-slate-500">
                  {useLocalAI ? 'Using local Ollama model' : 'Using Sarthi Cloud AI (default)'}
                </p>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <span className={`text-xs ${!useLocalAI ? 'text-indigo-400 font-semibold' : 'text-slate-600'}`}>Cloud</span>
              <button
                onClick={() => toggleLocalAI(!useLocalAI)}
                disabled={useLocalAI && ollamaModels.length === 0}
                className={`relative w-11 h-6 rounded-full transition-colors ${
                  useLocalAI ? 'bg-emerald-500' : 'bg-white/[0.1]'
                } disabled:opacity-40`}
              >
                <span className={`absolute top-1 w-4 h-4 bg-white rounded-full shadow transition-all ${
                  useLocalAI ? 'left-6' : 'left-1'
                }`} />
              </button>
              <span className={`text-xs ${useLocalAI ? 'text-emerald-400 font-semibold' : 'text-slate-600'}`}>Local</span>
            </div>
          </div>
          {useLocalAI && ollamaModels.length === 0 && (
            <p className="text-xs text-amber-400 mt-3">
              Ollama not detected at localhost:11434. Install Ollama and pull a model to use local AI.
            </p>
          )}
          {!useLocalAI && (
            <p className="text-xs text-slate-500 mt-3">
              Sarthi Cloud uses the full NCERT curriculum prompt and tracks progress. Recommended for most students.
            </p>
          )}
        </div>

        {/* Ollama model selector */}
        {useLocalAI && ollamaModels.length > 0 && (
          <div className="glass rounded-2xl p-5 mb-4 animate-fade-in">
            <div className="flex items-center gap-3 mb-3">
              <div className="w-10 h-10 rounded-xl bg-emerald-500/15 flex items-center justify-center">
                <svg className="w-5 h-5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z" />
                </svg>
              </div>
              <div>
                <h3 className="font-semibold text-sm">Local AI Model (Ollama)</h3>
                <p className="text-xs text-slate-500">Choose which model to use for offline chat</p>
              </div>
            </div>
            <div className="flex gap-2 flex-wrap">
              {ollamaModels.map(m => (
                <button
                  key={m}
                  onClick={() => saveOllamaModel(m)}
                  className={`px-3 py-1.5 rounded-lg text-xs font-mono transition-all ${
                    selectedModel === m
                      ? 'bg-emerald-500 text-white shadow-lg shadow-emerald-500/20'
                      : 'bg-white/[0.05] text-slate-300 hover:bg-white/[0.08] border border-white/[0.06]'
                  }`}
                >
                  {m}
                </button>
              ))}
            </div>
            {modelSaved && <p className="text-xs text-emerald-400 mt-2 animate-fade-in">Saved!</p>}
          </div>
        )}

        {/* Theme */}
        <div className="glass rounded-2xl p-5 mb-4">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 rounded-xl bg-amber-500/15 flex items-center justify-center">
                <svg className="w-5 h-5 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M4.098 19.902a3.75 3.75 0 0 0 5.304 0l6.401-6.402M6.75 21A3.75 3.75 0 0 1 3 17.25V4.125C3 3.504 3.504 3 4.125 3h5.25c.621 0 1.125.504 1.125 1.125v4.072M6.75 21a3.75 3.75 0 0 0 3.75-3.75V8.197M6.75 21h13.125c.621 0 1.125-.504 1.125-1.125v-5.25c0-.621-.504-1.125-1.125-1.125h-4.072M10.5 8.197l2.88-2.88c.438-.439 1.15-.439 1.59 0l3.712 3.713c.44.44.44 1.152 0 1.59l-2.879 2.88M6.75 17.25h.008v.008H6.75v-.008Z" />
                </svg>
              </div>
              <div>
                <h3 className="font-semibold text-sm">Theme</h3>
                <p className="text-xs text-slate-500">Change the look and feel</p>
              </div>
            </div>
          </div>
          <div className="grid grid-cols-2 gap-3">
            {[
              { id: 'indigo', name: 'Nebula', desc: 'Indigo & purple', colors: ['from-indigo-500 to-purple-600', 'from-purple-500 to-indigo-600', 'from-blue-500 to-indigo-500'] },
              { id: 'emerald', name: 'Forest', desc: 'Emerald & teal', colors: ['from-emerald-500 to-teal-600', 'from-teal-500 to-cyan-600', 'from-cyan-500 to-emerald-500'] },
            ].map(t => (
              <button
                key={t.id}
                onClick={async () => { setTheme(t.id); if (window.electronAPI) await window.electronAPI.config.set('theme', t.id); }}
                className={`relative rounded-xl p-4 border-2 transition-all ${
                  theme === t.id
                    ? `border-${t.id === 'indigo' ? 'indigo' : 'emerald'}-500 bg-${t.id === 'indigo' ? 'indigo' : 'emerald'}-500/10`
                    : 'border-white/[0.06] bg-white/[0.02] hover:border-white/[0.12]'
                }`}
              >
                <div className="flex items-center gap-2 mb-3">
                  {t.colors.map((c, i) => (
                    <div key={i} className={`w-4 h-4 rounded-full bg-gradient-to-br ${c}`} />
                  ))}
                </div>
                <p className="text-sm font-semibold text-white">{t.name}</p>
                <p className="text-xs text-slate-500">{t.desc}</p>
                {theme === t.id && (
                  <div className={`absolute top-2 right-2 w-5 h-5 rounded-full ${t.id === 'indigo' ? 'bg-indigo-500' : 'bg-emerald-500'} flex items-center justify-center`}>
                    <svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="m4.5 12.75 6 6 9-13.5" />
                    </svg>
                  </div>
                )}
              </button>
            ))}
          </div>
        </div>

        {/* Info */}
        <div className="glass rounded-2xl p-5">
          <h3 className="font-semibold text-sm mb-2">About Offline Setup</h3>
          <ul className="text-xs text-slate-400 space-y-1.5 mb-3">
            <li className="flex items-start gap-2">
              <span className="w-1 h-1 rounded-full bg-emerald-500/60 flex-shrink-0 mt-1.5" />
              <span><strong className="text-slate-300">TTS (macOS):</strong> Uses the macOS built-in voice engine — no installation needed, works offline automatically.</span>
            </li>
            <li className="flex items-start gap-2">
              <span className="w-1 h-1 rounded-full bg-slate-600 flex-shrink-0 mt-1.5" />
              <span><strong className="text-slate-300">TTS (Linux):</strong> Click Install to download the Piper engine and voice model (~63 MB).</span>
            </li>
            <li className="flex items-start gap-2">
              <span className="w-1 h-1 rounded-full bg-slate-600 flex-shrink-0 mt-1.5" />
              <span><strong className="text-slate-300">STT:</strong> Click Install to download the Whisper speech recognition model (~75 MB). Works fully offline after setup.</span>
            </li>
          </ul>
          <p className="text-xs text-slate-500">
            Models are stored in your user data folder and persist across app updates.
            One-time install per device — no internet required after setup.
          </p>
        </div>
      </main>
    </div>
  );
}
