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

const QUALITIES = ['best', '1080', '720', '480', '360', 'worst'];
const FORMATS = ['mp4', 'mkv', 'webm', 'mp3', 'm4a', 'opus'];
const PLATFORM_KEYS = ['youtube', 'tiktok', 'instagram', 'twitter', 'spotify'];

export default function SettingsPanel({ open, onClose }) {
  const toast = useToast();
  const [config, setConfig] = useState(null);
  const [draft, setDraft] = useState(null);
  const [loadError, setLoadError] = useState(null);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (!open || config) return;
    api('GET', '/api/config')
      .then((data) => {
        setConfig(data);
        setDraft(data);
      })
      .catch((err) => setLoadError(err instanceof ApiError ? err.message : 'Could not load settings.'));
  }, [open, config]);

  useEffect(() => {
    function onKey(e) {
      if (e.key === 'Escape') onClose();
    }
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);

  if (!open) return null;

  function patch(path, value) {
    setDraft((prev) => {
      const next = structuredClone(prev);
      let target = next;
      for (let i = 0; i < path.length - 1; i++) target = target[path[i]];
      target[path[path.length - 1]] = value;
      return next;
    });
  }

  function setCookiesFile(value) {
    setDraft((prev) => ({ ...prev, cookies_file: value || null, cookies_from_browser: value ? null : prev.cookies_from_browser }));
  }
  function setCookiesBrowser(value) {
    setDraft((prev) => ({ ...prev, cookies_from_browser: value || null, cookies_file: value ? null : prev.cookies_file }));
  }

  async function save() {
    if (draft.cookies_file && draft.cookies_from_browser) {
      toast('Cookies file and browser extraction can\'t both be set — clear one first.', 'error');
      return;
    }
    setSaving(true);
    try {
      const saved = await api('PUT', '/api/config', draft);
      setConfig(saved);
      setDraft(saved);
      toast('Settings saved to ~/.config/vdl/config.yaml', 'success');
    } catch (err) {
      toast(err instanceof ApiError ? err.message : 'Could not save settings.', 'error');
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex justify-end">
      <button
        type="button"
        aria-label="Close settings"
        onClick={onClose}
        className="absolute inset-0 bg-ink/30 backdrop-blur-[2px]"
      />
      <aside className="relative flex h-full w-full max-w-lg flex-col overflow-hidden border-l border-line bg-paper shadow-2xl animate-rise">
        <div className="flex items-center justify-between border-b border-line px-7 py-5">
          <div>
            <h2 className="font-display text-3xl italic text-ink">Settings</h2>
            <p className="text-xs text-ink-faint">Saved straight to your vdl config file</p>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="rounded-full border border-line px-4 py-2 text-sm text-ink-soft transition hover:border-ink/30 hover:text-ink"
          >
            Close
          </button>
        </div>

        <div className="flex-1 overflow-y-auto px-7 py-6">
          {loadError && <p className="rounded-2xl border border-rose/30 bg-rose-soft px-4 py-3 text-sm text-rose">{loadError}</p>}
          {!draft && !loadError && <p className="text-sm text-ink-faint">Loading your current configuration…</p>}

          {draft && (
            <div className="space-y-6">
              <Field label="Downloads folder">
                <TextInput value={draft.download_path} onChange={(e) => patch(['download_path'], e.target.value)} />
              </Field>

              <div className="grid gap-4 sm:grid-cols-2">
                <Field label="Default format">
                  <Select value={draft.default_format} onChange={(e) => patch(['default_format'], e.target.value)} options={FORMATS} />
                </Field>
                <Field label="Default quality">
                  <Select value={draft.default_video_quality} onChange={(e) => patch(['default_video_quality'], e.target.value)} options={QUALITIES} />
                </Field>
              </div>

              <Field label="Search results to show" hint="How many results the interactive YouTube search returns">
                <TextInput
                  type="number"
                  min="1"
                  max="50"
                  value={draft.search_results_count}
                  onChange={(e) => patch(['search_results_count'], Number(e.target.value) || draft.search_results_count)}
                />
              </Field>

              <div>
                <p className="mb-2.5 text-xs font-semibold uppercase tracking-[0.16em] text-ink-faint">
                  Per-platform quality
                </p>
                <div className="grid gap-3 rounded-2xl border border-line bg-card p-4 sm:grid-cols-2">
                  {PLATFORM_KEYS.map((key) => (
                    <Field key={key} label={key}>
                      <Select
                        value={draft.platform_quality[key]}
                        onChange={(e) => patch(['platform_quality', key], e.target.value)}
                        options={QUALITIES}
                      />
                    </Field>
                  ))}
                </div>
              </div>

              <div className="grid gap-4 sm:grid-cols-2">
                <Field label="Cookies file" hint="Mutually exclusive with browser extraction">
                  <TextInput
                    placeholder="/path/to/cookies.txt"
                    value={draft.cookies_file || ''}
                    onChange={(e) => setCookiesFile(e.target.value)}
                  />
                </Field>
                <Field label="Cookies from browser" hint="e.g. firefox, chrome">
                  <TextInput
                    placeholder="firefox"
                    value={draft.cookies_from_browser || ''}
                    onChange={(e) => setCookiesBrowser(e.target.value)}
                  />
                </Field>
              </div>

              <div className="grid gap-3 sm:grid-cols-2">
                <Toggle
                  checked={draft.confirm_before_download}
                  onChange={(v) => patch(['confirm_before_download'], v)}
                  label="Confirm before download"
                  sub="Applies to the command-line interface"
                />
                <Toggle
                  checked={draft.no_progress}
                  onChange={(v) => patch(['no_progress'], v)}
                  label="Plain progress output"
                  sub="Disables animated bars in the CLI"
                />
                <Toggle
                  checked={draft.termux_mode}
                  onChange={(v) => patch(['termux_mode'], v)}
                  label="Termux mode"
                  sub="For Android/Termux installs"
                />
              </div>

              <Field label="Helper binaries folder" hint="Advanced — only change this if you know what it does">
                <TextInput value={draft.bins_dir} onChange={(e) => patch(['bins_dir'], e.target.value)} />
              </Field>
            </div>
          )}
        </div>

        {draft && (
          <div className="flex items-center justify-end gap-3 border-t border-line px-7 py-5">
            <button
              type="button"
              onClick={() => setDraft(config)}
              className="text-sm font-medium text-ink-faint transition hover:text-ink-soft"
            >
              Revert changes
            </button>
            <button
              type="button"
              onClick={save}
              disabled={saving}
              className="rounded-xl bg-ink px-6 py-2.5 text-sm font-semibold text-paper transition hover:bg-ink/90 disabled:cursor-wait disabled:opacity-60"
            >
              {saving ? 'Saving…' : 'Save settings'}
            </button>
          </div>
        )}
      </aside>
    </div>
  );
}