import { useState } from 'react';
import { api, ApiError } from '../lib/api';
import { useToast } from '../lib/ToastContext';
import PlatformTabs from './PlatformTabs';
import MetadataPreview from './MetadataPreview';
import { Field, Select, TextInput, Toggle } from './Field';

const QUALITIES = ['best', '1080', '720', '480', '360', 'worst'];
const FORMATS = ['mp4', 'mkv', 'webm', 'mp3', 'm4a', 'opus'];
const AUDIO_FORMATS = new Set(['mp3', 'm4a', 'opus']);

export default function DownloadConsole({ onLaunched }) {
  const toast = useToast();
  const [platform, setPlatform] = useState('yt');
  const [url, setUrl] = useState('');
  const [quality, setQuality] = useState('');
  const [format, setFormat] = useState('');
  const [outputDir, setOutputDir] = useState('');
  const [audioOnly, setAudioOnly] = useState(false);
  const [videoOnly, setVideoOnly] = useState(false);
  const [meta, setMeta] = useState(null);
  const [error, setError] = useState(null);
  const [previewing, setPreviewing] = useState(false);
  const [launching, setLaunching] = useState(false);

  const audioForced = AUDIO_FORMATS.has(format);

  function changePlatform(next) {
    setPlatform(next);
    setMeta(null);
    setError(null);
  }

  function changeFormat(next) {
    setFormat(next);
    if (AUDIO_FORMATS.has(next)) {
      setAudioOnly(true);
      setVideoOnly(false);
    }
  }

  function setAudio(next) {
    setAudioOnly(next);
    if (next) setVideoOnly(false);
  }

  function setVideo(next) {
    setVideoOnly(next);
    if (next) setAudioOnly(false);
  }

  async function fetchPreview() {
    const trimmed = url.trim();
    setError(null);
    if (!trimmed) {
      setError('Paste a link first — that\'s how we know what to fetch.');
      return;
    }
    setPreviewing(true);
    setMeta(null);
    try {
      const data = await api('POST', '/api/fetch-metadata', { url: trimmed, platform });
      setMeta(data);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : 'Something went wrong fetching that link.');
    } finally {
      setPreviewing(false);
    }
  }

  async function startDownload() {
    const trimmed = url.trim();
    if (!trimmed) return;
    setLaunching(true);
    try {
      const data = await api('POST', '/api/download', {
        platform,
        url: trimmed,
        quality: quality || null,
        format: format || null,
        audio_only: audioOnly,
        video_only: videoOnly,
        start: null,
        end: null,
        output_dir: outputDir.trim() || null,
      });
      onLaunched(data.session_id, { url: trimmed, platform });
      toast('Download started — track its progress in Sessions below.', 'success');
      document.getElementById('sessions')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
    } catch (err) {
      setError(err instanceof ApiError ? err.message : 'Could not start the download.');
    } finally {
      setLaunching(false);
    }
  }

  function handleDisabledPlatform(p) {
    toast(`${p.label} downloads aren't available from the browser yet  use the vdl CLI for now.`, 'warn');
  }

  function clearAll() {
    setUrl('');
    setQuality('');
    setFormat('');
    setOutputDir('');
    setAudioOnly(false);
    setVideoOnly(false);
    setMeta(null);
    setError(null);
  }

  return (
    <section id="download" className="mx-auto max-w-6xl px-6 py-14 sm:py-20">
      <div className="mb-8 max-w-xl">
        <h2 className="font-display text-4xl italic text-ink">Start a download</h2>
        <p className="mt-2 text-ink-soft">
          Choose where the link comes from, paste it in, and preview before you commit.
        </p>
      </div>

      <div className="rounded-3xl border border-line bg-card p-6 shadow-sm shadow-ink/5 sm:p-8">
        <div className="space-y-6">
          <div>
            <p className="mb-2.5 text-xs font-semibold uppercase tracking-[0.16em] text-ink-faint">
              Where is it from?
            </p>
            <PlatformTabs value={platform} onChange={changePlatform} onDisabledClick={handleDisabledPlatform} />
          </div>

          <div className="flex flex-col gap-3 sm:flex-row sm:items-end">
            <div className="flex-1">
              <Field label="Link to download">
                <TextInput
                  type="url"
                  placeholder="Paste a video, post, or track URL…"
                  value={url}
                  onChange={(e) => { setUrl(e.target.value); setError(null); setMeta(null); }}
                  onKeyDown={(e) => { if (e.key === 'Enter') fetchPreview(); }}
                  spellCheck={false}
                />
              </Field>
            </div>
            <button
              type="button"
              onClick={fetchPreview}
              disabled={previewing}
              className="rounded-xl border border-ink/15 bg-ink px-6 py-2.5 text-sm font-semibold text-paper transition hover:bg-ink/90 disabled:cursor-wait disabled:opacity-60"
            >
              {previewing ? 'Looking it up…' : 'Preview'}
            </button>
          </div>

          {error && (
            <p className="animate-rise rounded-2xl border border-rose/30 bg-rose-soft px-4 py-3 text-sm text-rose">
              {error}
            </p>
          )}

          <MetadataPreview meta={meta} />

          <div className="grid gap-4 sm:grid-cols-3">
            <Field label="Quality" hint="Leave blank to use your saved default">
              <Select value={quality} onChange={(e) => setQuality(e.target.value)} options={QUALITIES} placeholder="Platform default" />
            </Field>
            <Field label="File format" hint="Picking mp3/m4a/opus switches to audio-only">
              <Select value={format} onChange={(e) => changeFormat(e.target.value)} options={FORMATS} placeholder="Platform default" />
            </Field>
            <Field label="Save to" hint="Leave blank for your configured downloads folder">
              <TextInput placeholder="e.g. ~/Movies" value={outputDir} onChange={(e) => setOutputDir(e.target.value)} />
            </Field>
          </div>

          <div className="grid gap-3 sm:grid-cols-2">
            <Toggle
              checked={audioOnly}
              onChange={setAudio}
              label="Audio only"
              sub="Skip the video stream entirely"
              disabled={audioForced}
            />
            <Toggle
              checked={videoOnly}
              onChange={setVideo}
              label="Video only"
              sub="Skip the audio stream entirely"
              disabled={audioForced}
            />
          </div>

          <div className="flex flex-wrap items-center justify-between gap-3 border-t border-line pt-6">
            <button
              type="button"
              onClick={clearAll}
              className="text-sm font-medium text-ink-faint transition hover:text-ink-soft"
            >
              Clear form
            </button>
            <button
              type="button"
              onClick={startDownload}
              disabled={!meta || launching}
              className="rounded-xl bg-coral px-8 py-3 text-sm font-semibold text-white shadow-md shadow-coral/30 transition hover:bg-coral/90 disabled:cursor-not-allowed disabled:bg-line disabled:text-ink-faint disabled:shadow-none"
            >
              {launching ? 'Starting…' : 'Download'}
            </button>
          </div>
          {!meta && !error && (
            <p className="text-right text-xs text-ink-faint">Preview a link to unlock the download button.</p>
          )}
        </div>
      </div>
    </section>
  );
}