"use client";

import { useEffect, useState } from "react";
import { PageHead } from "../_ui/page-head";

type Loaded = {
  qobuzEmail: string;
  qobuzUserId: string;
  slskdUrl: string;
  qobuzPasswordSet: boolean;
  qobuzTokenSet: boolean;
  slskdApiKeySet: boolean;
};

type Tab = "Qobuz" | "Soulseek" | "Library" | "Monitor" | "Discovery";
const TABS: Tab[] = ["Qobuz", "Soulseek", "Library", "Monitor", "Discovery"];

const DISCOVERY_FIELDS: [string, string][] = [
  ["discover.intervalHours", "Interval (hours)"],
  ["discover.maxSeeds", "Max seeds per sweep"],
  ["discover.similarPerSeed", "Similar per seed"],
  ["discover.albumsPerArtist", "Albums per artist"],
  ["discover.minScore", "Min score"],
];

const MONITOR_FIELDS: [string, string][] = [
  ["monitor.pollIntervalHours", "Poll interval (hours)"],
  ["monitor.retryIntervalHours", "Retry interval (hours)"],
  ["monitor.qualityCutoff", "Quality cutoff"],
  ["monitor.upgradeWindowDays", "Upgrade window (days)"],
];

export function SettingsForm() {
  const [tab, setTab] = useState<Tab>("Qobuz");
  const [qobuzEmail, setQobuzEmail] = useState("");
  const [qobuzPassword, setQobuzPassword] = useState("");
  const [qobuzUserId, setQobuzUserId] = useState("");
  const [qobuzToken, setQobuzToken] = useState("");
  const [slskdUrl, setSlskdUrl] = useState("");
  const [slskdApiKey, setSlskdApiKey] = useState("");
  const [pwSet, setPwSet] = useState(false);
  const [tokenSet, setTokenSet] = useState(false);
  const [keySet, setKeySet] = useState(false);
  const [saved, setSaved] = useState(false);
  const [scanResult, setScanResult] = useState<string | null>(null);
  const [scanRequested, setScanRequested] = useState(false);
  const [discoverCfg, setDiscoverCfg] = useState<Record<string, string>>({});
  const [discoverSaved, setDiscoverSaved] = useState(false);
  const [monitorCfg, setMonitorCfg] = useState<Record<string, string>>({});
  const [monitorSaved, setMonitorSaved] = useState(false);

  useEffect(() => {
    fetch("/api/scan")
      .then((r) => r.json())
      .then((s: { result: string | null; requested: boolean }) => {
        setScanResult(s.result);
        setScanRequested(s.requested);
      });
  }, []);

  async function requestScan() {
    await fetch("/api/scan", { method: "POST" });
    setScanRequested(true);
  }

  useEffect(() => {
    if (!scanRequested) return;
    const id = setInterval(async () => {
      const s = await (await fetch("/api/scan")).json();
      setScanResult(s.result);
      if (!s.requested) setScanRequested(false);
    }, 2000);
    return () => clearInterval(id);
  }, [scanRequested]);

  useEffect(() => {
    fetch("/api/config")
      .then((r) => r.json())
      .then((c: Loaded) => {
        setQobuzEmail(c.qobuzEmail);
        setQobuzUserId(c.qobuzUserId);
        setSlskdUrl(c.slskdUrl);
        setPwSet(c.qobuzPasswordSet);
        setTokenSet(c.qobuzTokenSet);
        setKeySet(c.slskdApiKeySet);
      });
  }, []);

  useEffect(() => {
    fetch("/api/discover/config")
      .then((r) => r.json())
      .then((c: Record<string, string>) => setDiscoverCfg(c));
  }, []);

  useEffect(() => {
    fetch("/api/monitor/config")
      .then((r) => r.json())
      .then((c: Record<string, string>) => setMonitorCfg(c));
  }, []);

  async function saveCredentials(e: React.FormEvent) {
    e.preventDefault();
    await fetch("/api/config", {
      method: "PUT",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ qobuzEmail, qobuzPassword, qobuzUserId, qobuzToken, slskdUrl, slskdApiKey }),
    });
    setQobuzPassword("");
    setQobuzToken("");
    setSlskdApiKey("");
    setSaved(true);
    setTimeout(() => setSaved(false), 1500);
    setPwSet(pwSet || qobuzPassword !== "");
    setTokenSet(tokenSet || qobuzToken !== "");
    setKeySet(keySet || slskdApiKey !== "");
  }

  function setCfg(key: string, value: string) {
    setDiscoverCfg((c) => ({ ...c, [key]: value }));
  }

  async function saveDiscovery(e: React.FormEvent) {
    e.preventDefault();
    await fetch("/api/discover/config", {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(discoverCfg),
    });
    setDiscoverSaved(true);
    setTimeout(() => setDiscoverSaved(false), 1500);
  }

  function setMon(key: string, value: string) {
    setMonitorCfg((c) => ({ ...c, [key]: value }));
  }

  async function saveMonitor(e: React.FormEvent) {
    e.preventDefault();
    await fetch("/api/monitor/config", {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(monitorCfg),
    });
    setMonitorSaved(true);
    setTimeout(() => setMonitorSaved(false), 1500);
  }

  const secretHint = (set: boolean) => (set ? <span className="set"> · set</span> : null);

  async function clearField(field: "qobuzPassword" | "qobuzToken" | "slskdApiKey") {
    await fetch(`/api/config?field=${field}`, { method: "DELETE" });
    if (field === "qobuzPassword") { setPwSet(false); setQobuzPassword(""); }
    if (field === "qobuzToken") { setTokenSet(false); setQobuzToken(""); }
    if (field === "slskdApiKey") { setKeySet(false); setSlskdApiKey(""); }
  }

  return (
    <div>
      <PageHead title="Settings" eyebrow="Credentials · library · discovery" />

      <div className="tabs">
        {TABS.map((t) => (
          <button key={t} className={`tab${tab === t ? " active" : ""}`} onClick={() => setTab(t)}>
            {t}
          </button>
        ))}
      </div>

      {tab === "Qobuz" ? (
        <form className="settings-section" onSubmit={saveCredentials}>
          <div className="subhead">Email / password</div>
          <div className="field-grid">
            <label className="field">
              <span>Qobuz email</span>
              <input aria-label="qobuz email" value={qobuzEmail} onChange={(e) => setQobuzEmail(e.target.value)} />
            </label>
            <label className="field">
              <span>
                Qobuz password{secretHint(pwSet)}
                {pwSet ? (
                  <button type="button" className="btn ghost sm" style={{ marginLeft: 8 }}
                    aria-label="clear qobuz password" onClick={() => clearField("qobuzPassword")}>
                    Clear
                  </button>
                ) : null}
              </span>
              <input aria-label="qobuz password" type="password" placeholder={pwSet ? "•••• stored" : ""} value={qobuzPassword} onChange={(e) => setQobuzPassword(e.target.value)} />
            </label>
          </div>
          <div className="subhead">Auth token (more reliable; overrides email/password)</div>
          <div className="field-grid">
            <label className="field">
              <span>Qobuz user ID</span>
              <input aria-label="qobuz user id" value={qobuzUserId} onChange={(e) => setQobuzUserId(e.target.value)} />
            </label>
            <label className="field">
              <span>
                Qobuz auth token{secretHint(tokenSet)}
                {tokenSet ? (
                  <button type="button" className="btn ghost sm" style={{ marginLeft: 8 }}
                    aria-label="clear qobuz auth token" onClick={() => clearField("qobuzToken")}>
                    Clear
                  </button>
                ) : null}
              </span>
              <input aria-label="qobuz auth token" type="password" placeholder={tokenSet ? "•••• stored" : ""} value={qobuzToken} onChange={(e) => setQobuzToken(e.target.value)} />
            </label>
          </div>
          <div className="save-row">
            <button type="submit" className="btn accent">Save</button>
            {saved ? <span className="saved-note">Saved</span> : null}
          </div>
        </form>
      ) : null}

      {tab === "Soulseek" ? (
        <form className="settings-section" onSubmit={saveCredentials}>
          <div className="subhead">Soulseek (slskd)</div>
          <div className="field-grid">
            <label className="field">
              <span>slskd URL</span>
              <input aria-label="slskd url" value={slskdUrl} onChange={(e) => setSlskdUrl(e.target.value)} />
            </label>
            <label className="field">
              <span>
                slskd API key{secretHint(keySet)}
                {keySet ? (
                  <button type="button" className="btn ghost sm" style={{ marginLeft: 8 }}
                    aria-label="clear slskd api key" onClick={() => clearField("slskdApiKey")}>
                    Clear
                  </button>
                ) : null}
              </span>
              <input aria-label="slskd api key" type="password" placeholder={keySet ? "•••• stored" : ""} value={slskdApiKey} onChange={(e) => setSlskdApiKey(e.target.value)} />
            </label>
          </div>
          <div className="save-row">
            <button type="submit" className="btn accent">Save</button>
            {saved ? <span className="saved-note">Saved</span> : null}
          </div>
        </form>
      ) : null}

      {tab === "Library" ? (
        <section className="settings-section">
          <div className="info-panel">
            <div>
              <span className="k">Music path</span> &nbsp; <code>/music</code>
            </div>
            <div className="muted-note" style={{ fontFamily: "inherit" }}>
              Mounted read/write into the worker. To point Lyra at a different folder, set <code>MUSIC_DIR</code> in{" "}
              <code>docker-compose.yml</code> and rebuild — it can’t be remounted from here.
            </div>
          </div>
          <p className="muted-note">Scan the library to record what’s already on disk as owned + monitored.</p>
          <div className="save-row">
            <button type="button" className="btn" onClick={requestScan} disabled={scanRequested}>
              {scanRequested ? "Scanning…" : "Scan library"}
            </button>
            {scanResult ? (
              <span className="saved-note" aria-label="scan result" style={{ color: "var(--graphite)" }}>
                Last scan: {scanResult}
              </span>
            ) : null}
          </div>
        </section>
      ) : null}

      {tab === "Monitor" ? (
        <form className="settings-section" onSubmit={saveMonitor}>
          <div className="save-row" style={{ margin: "6px 0 4px" }}>
            <label className="toggle">
              <input
                type="checkbox"
                checked={monitorCfg["monitor.enabled"] === "true"}
                onChange={(e) => setMon("monitor.enabled", e.target.checked ? "true" : "false")}
              />
              Automatic monitoring (grab &amp; upgrade)
            </label>
          </div>
          <div className="save-row" style={{ margin: "2px 0 8px" }}>
            <label className="toggle">
              <input
                type="checkbox"
                checked={monitorCfg["monitor.autoMonitorFuture"] === "true"}
                onChange={(e) => setMon("monitor.autoMonitorFuture", e.target.checked ? "true" : "false")}
              />
              Auto-monitor future releases from watched artists
            </label>
          </div>
          <div className="field-grid">
            {MONITOR_FIELDS.map(([key, label]) => (
              <label key={key} className="field">
                <span>{label}</span>
                <input type="number" step="any" value={monitorCfg[key] ?? ""} onChange={(e) => setMon(key, e.target.value)} />
              </label>
            ))}
          </div>
          <div className="save-row">
            <button type="submit" className="btn">Save monitor settings</button>
            {monitorSaved ? <span className="saved-note">Saved</span> : null}
          </div>
        </form>
      ) : null}

      {tab === "Discovery" ? (
        <form className="settings-section" onSubmit={saveDiscovery}>
          <div className="save-row" style={{ margin: "6px 0 4px" }}>
            <label className="toggle">
              <input
                type="checkbox"
                checked={discoverCfg["discover.enabled"] === "true"}
                onChange={(e) => setCfg("discover.enabled", e.target.checked ? "true" : "false")}
              />
              Scheduled discovery sweep
            </label>
          </div>
          <div className="field-grid">
            {DISCOVERY_FIELDS.map(([key, label]) => (
              <label key={key} className="field">
                <span>{label}</span>
                <input type="number" step="any" value={discoverCfg[key] ?? ""} onChange={(e) => setCfg(key, e.target.value)} />
              </label>
            ))}
          </div>
          <div className="save-row">
            <button type="submit" className="btn">Save discovery settings</button>
            {discoverSaved ? <span className="saved-note">Saved</span> : null}
          </div>
        </form>
      ) : null}
    </div>
  );
}
