import { useEffect, useRef, useState } from 'react';

type Mode = 'mp3' | 'mp4' | 'playlist' | 'facebook';

interface ModeDef {
  key: Mode;
  title: string;
  subtitle: string;
  icon: string;
  accent: string;
  button: string;
  formats: { value: string; label: string }[];
}

const MODES: ModeDef[] = [
  {
    key: 'mp3',
    title: 'MP3',
    subtitle: 'Pobierz dźwięk',
    icon: '♫',
    accent: '#a855f7',
    button: 'POBIERZ DŹWIĘK',
    formats: [
      { value: '320', label: 'MP3  320 kbps' },
      { value: '256', label: 'MP3  256 kbps' },
      { value: '192', label: 'MP3  192 kbps' },
      { value: '128', label: 'MP3  128 kbps' },
    ],
  },
  {
    key: 'mp4',
    title: 'MP4',
    subtitle: 'Pobierz wideo',
    icon: '■',
    accent: '#3b82f6',
    button: 'POBIERZ WIDEO',
    formats: [
      { value: 'best', label: 'MP4  najlepsza' },
      { value: '2160', label: 'MP4  2160p (4K)' },
      { value: '1440', label: 'MP4  1440p' },
      { value: '1080', label: 'MP4  1080p' },
      { value: '720', label: 'MP4  720p' },
      { value: '480', label: 'MP4  480p' },
    ],
  },
  {
    key: 'playlist',
    title: 'PLAYLISTA',
    subtitle: 'Pobierz całą listę',
    icon: '▦',
    accent: '#22c55e',
    button: 'POBIERZ PLAYLISTĘ',
    formats: [
      { value: 'video-1080', label: 'Wideo MP4  1080p' },
      { value: 'video-720', label: 'Wideo MP4  720p' },
      { value: 'audio-320', label: 'Audio MP3  320 kbps' },
    ],
  },
  {
    key: 'facebook',
    title: 'FACEBOOK',
    subtitle: 'Pobierz wideo',
    icon: 'f',
    accent: '#60a5fa',
    button: 'POBIERZ WIDEO',
    formats: [
      { value: 'best', label: 'MP4  najlepsza' },
      { value: '1080', label: 'MP4  1080p' },
      { value: '720', label: 'MP4  720p' },
      { value: '480', label: 'MP4  480p' },
    ],
  },
];

const VERSION = '6.5.6';

export default function App() {
  const [url, setUrl] = useState('');
  const [mode, setMode] = useState<Mode>('mp3');
  const [format, setFormat] = useState('320');
  const [subtitles, setSubtitles] = useState(false);
  const [subsMode, setSubsMode] = useState<'embed' | 'file'>('embed');
  const [busy, setBusy] = useState(false);
  const [progress, setProgress] = useState(0);
  const [log, setLog] = useState<string[]>(['OK: wszystko gotowe do pobierania.']);
  const [ytdlp, setYtdlp] = useState<{ version: string; autoUpdate: boolean; updating?: boolean } | null>(null);
  const esRef = useRef<EventSource | null>(null);
  const jobRef = useRef<string | null>(null);
  const logEndRef = useRef<HTMLDivElement | null>(null);

  const def = MODES.find((m) => m.key === mode)!;

  useEffect(() => {
    // przy zmianie trybu ustaw domyślny format
    setFormat(MODES.find((m) => m.key === mode)!.formats[0].value);
  }, [mode]);

  useEffect(() => {
    logEndRef.current?.scrollIntoView({ block: 'end' });
  }, [log]);

  useEffect(() => {
    fetch('/api/ytdlp')
      .then((r) => r.json())
      .then(setYtdlp)
      .catch(() => {});
  }, []);

  async function checkUpdate() {
    setYtdlp((y) => (y ? { ...y, updating: true } : y));
    appendLog('Sprawdzam aktualizacje yt-dlp...');
    try {
      const r = await fetch('/api/ytdlp/update', { method: 'POST' });
      const res = await r.json();
      appendLog(
        res.updated
          ? `yt-dlp zaktualizowany do ${res.version}.`
          : `yt-dlp jest aktualny (${res.version}).`,
      );
      setYtdlp((y) => (y ? { ...y, version: res.version, updating: false } : y));
    } catch {
      appendLog('Nie udało się sprawdzić aktualizacji yt-dlp.');
      setYtdlp((y) => (y ? { ...y, updating: false } : y));
    }
  }

  function appendLog(line: string) {
    setLog((l) => [...l.slice(-400), line]);
  }

  async function paste() {
    try {
      const t = await navigator.clipboard.readText();
      if (t) setUrl(t.trim());
    } catch {
      appendLog('Nie udało się odczytać schowka (brak uprawnień przeglądarki).');
    }
  }

  function reset() {
    esRef.current?.close();
    esRef.current = null;
    jobRef.current = null;
    setBusy(false);
  }

  async function start() {
    if (!url.trim()) {
      appendLog('BŁĄD: wklej najpierw link.');
      return;
    }
    setBusy(true);
    setProgress(0);
    setLog([`Start: ${def.title} — ${url.trim()}`]);
    try {
      const res = await fetch('/api/jobs', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ url: url.trim(), mode, format, subtitles, subsMode }),
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const { id } = await res.json();
      jobRef.current = id;

      const es = new EventSource(`/api/jobs/${id}/events`);
      esRef.current = es;
      es.onmessage = (e) => handleEvent(e.data);
      es.onerror = () => {
        // strumień zamknięty (koniec joba lub błąd sieci)
        es.close();
      };
    } catch (e: any) {
      appendLog(`BŁĄD: ${e?.message || e}`);
      reset();
    }
  }

  function handleEvent(data: string) {
    let ev: any;
    try {
      ev = JSON.parse(data);
    } catch {
      return;
    }
    switch (ev.kind) {
      case 'log':
        appendLog(ev.line);
        break;
      case 'progress':
        setProgress(ev.percent);
        break;
      case 'done': {
        setProgress(100);
        appendLog(`Pobieranie zakończone: ${ev.file?.name}`);
        // wywołaj pobranie pliku przez przeglądarkę
        const a = document.createElement('a');
        a.href = ev.downloadUrl;
        a.download = ev.file?.name || '';
        document.body.appendChild(a);
        a.click();
        a.remove();
        reset();
        break;
      }
      case 'error':
        appendLog(`BŁĄD: ${ev.message}`);
        reset();
        break;
      default:
        break;
    }
  }

  async function stop() {
    const id = jobRef.current;
    if (id) {
      try {
        await fetch(`/api/jobs/${id}`, { method: 'DELETE' });
      } catch {
        /* ignore */
      }
    }
    appendLog('Zatrzymano.');
    reset();
  }

  return (
    <div className="app">
      <div className="card">
        <header className="head">
          <div className="logo">↓</div>
          <div className="head-text">
            <h1>Video &amp; Sound Downloader Pro</h1>
            <p>Pobieraj audio, wideo i playlisty z jednego panelu</p>
          </div>
          <span className="badge">v{VERSION}</span>
        </header>

        <label className="field-label">Link:</label>
        <div className="link-row">
          <input
            className="link-input"
            placeholder="Wklej link (YouTube, YouTube Music, Shorts, Facebook, LinkedIn, ARTE TV…)"
            value={url}
            onChange={(e) => setUrl(e.target.value)}
          />
          <button className="icon-btn" title="Wklej ze schowka" onClick={paste}>
            {'\u{1F517}'}
          </button>
        </div>

        <label className="field-label">Wybierz opcję:</label>
        <div className="modes">
          {MODES.map((m) => (
            <button
              key={m.key}
              className={`mode ${mode === m.key ? 'active' : ''}`}
              style={mode === m.key ? { borderColor: m.accent } : undefined}
              onClick={() => setMode(m.key)}
            >
              <span className="mode-icon" style={{ color: m.accent }}>
                {m.icon}
              </span>
              <span className="mode-title">{m.title}</span>
              <span className="mode-sub">{m.subtitle}</span>
            </button>
          ))}
        </div>

        <div className="row2">
          <div className="col">
            <label className="field-label">Jakość / Format:</label>
            <select className="select" value={format} onChange={(e) => setFormat(e.target.value)}>
              {def.formats.map((f) => (
                <option key={f.value} value={f.value}>
                  {f.label}
                </option>
              ))}
            </select>
          </div>
          <div className="col">
            <label className="field-label">Napisy:</label>
            <div className="save-to">
              <label className="subs">
                <input
                  type="checkbox"
                  checked={subtitles && mode !== 'mp3'}
                  onChange={(e) => setSubtitles(e.target.checked)}
                  disabled={mode === 'mp3'}
                />
                Pobierz napisy
              </label>
              <select
                className="select subs-select"
                value={subsMode}
                onChange={(e) => setSubsMode(e.target.value as 'embed' | 'file')}
                disabled={!subtitles || mode === 'mp3'}
              >
                <option value="embed">Osadź w pliku wideo</option>
                <option value="file">Osobny plik (.srt)</option>
              </select>
            </div>
          </div>
        </div>
        <p className="hint">
          Napisy dotyczą tylko faktycznie dostępnych napisów — nie obejmują
          automatycznie generowanych napisów YouTube. Gotowy plik pobiera się przez
          przeglądarkę (folder „Pobrane”).
        </p>

        <div className="actions">
          <button
            className="download-btn"
            onClick={start}
            disabled={busy}
            style={{ opacity: busy ? 0.6 : 1 }}
          >
            {busy ? `Pobieram… ${Math.round(progress)}%` : `↓  ${def.button}`}
          </button>
          <button className="stop-btn" onClick={stop} disabled={!busy}>
            STOP
          </button>
        </div>

        {busy && (
          <div className="progress">
            <div className="progress-bar" style={{ width: `${progress}%` }} />
          </div>
        )}

        <div className="logbox">
          <div className="logbox-title">Log</div>
          <div className="logbox-body">
            {log.map((l, i) => (
              <div key={i} className="logline">
                {l}
              </div>
            ))}
            <div ref={logEndRef} />
          </div>
        </div>

        <footer className="foot">
          <button className="ghost" onClick={() => alert('Wsparcie: napisz na support@naurecki.pl')}>
            Wsparcie
          </button>
          {ytdlp && (
            <div className="ytdlp-info">
              <span title={ytdlp.autoUpdate ? 'Auto-aktualizacja włączona' : 'Auto-aktualizacja wyłączona'}>
                yt-dlp {ytdlp.version}
                {ytdlp.autoUpdate ? ' · auto-update' : ''}
              </span>
              <button className="ghost small" onClick={checkUpdate} disabled={ytdlp.updating}>
                {ytdlp.updating ? 'Sprawdzam…' : 'Sprawdź aktualizacje'}
              </button>
            </div>
          )}
          <button
            className="ghost"
            onClick={() =>
              alert('Video & Sound Downloader Pro — webowa wersja oparta o yt-dlp + FFmpeg.')
            }
          >
            O mnie
          </button>
        </footer>
      </div>
    </div>
  );
}
