"use client";

import { useEffect, useState } from "react";

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

export function SettingsForm() {
  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);

  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); // worker finished the scan
    }, 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));
  }, []);

  async function submit(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);
    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);
  }

  return (
    <>
      <form onSubmit={submit}>
        <fieldset>
          <legend>Qobuz — email/password</legend>
          <label>Qobuz email <input aria-label="qobuz email" value={qobuzEmail} onChange={(e) => setQobuzEmail(e.target.value)} /></label>
          <label>Qobuz password <input aria-label="qobuz password" type="password" placeholder={pwSet ? "•••• (set)" : ""} value={qobuzPassword} onChange={(e) => setQobuzPassword(e.target.value)} /></label>
        </fieldset>
        <fieldset>
          <legend>Qobuz — auth token (more reliable; overrides email/password)</legend>
          <label>Qobuz user ID <input aria-label="qobuz user id" value={qobuzUserId} onChange={(e) => setQobuzUserId(e.target.value)} /></label>
          <label>Qobuz auth token <input aria-label="qobuz auth token" type="password" placeholder={tokenSet ? "•••• (set)" : ""} value={qobuzToken} onChange={(e) => setQobuzToken(e.target.value)} /></label>
        </fieldset>
        <fieldset>
          <legend>Soulseek (slskd)</legend>
          <label>slskd URL <input aria-label="slskd url" value={slskdUrl} onChange={(e) => setSlskdUrl(e.target.value)} /></label>
          <label>slskd API key <input aria-label="slskd api key" type="password" placeholder={keySet ? "•••• (set)" : ""} value={slskdApiKey} onChange={(e) => setSlskdApiKey(e.target.value)} /></label>
        </fieldset>
        <button type="submit">Save</button>
        {saved ? <span> Saved.</span> : null}
      </form>
      <section>
        <h2>Library</h2>
        <p>Scan <code>/music</code> and record what's already on disk as owned + monitored.</p>
        <button type="button" onClick={requestScan} disabled={scanRequested}>
          {scanRequested ? "Scan requested…" : "Scan library"}
        </button>
        {scanResult ? <p aria-label="scan result">Last scan: {scanResult}</p> : null}
      </section>
      <form onSubmit={saveDiscovery}>
        <h2>Discovery</h2>
        <label>
          <input
            type="checkbox"
            checked={discoverCfg["discover.enabled"] === "true"}
            onChange={(e) => setCfg("discover.enabled", e.target.checked ? "true" : "false")}
          />{" "}
          Enable scheduled discovery sweep
        </label>
        {[
          ["discover.intervalHours", "Interval (hours)"],
          ["discover.maxSeeds", "Max seeds per sweep"],
          ["discover.similarPerSeed", "Similar per seed"],
          ["discover.albumsPerArtist", "Albums per artist"],
          ["discover.minScore", "Min score"],
        ].map(([key, label]) => (
          <p key={key}>
            <label>
              {label}:{" "}
              <input
                type="number"
                step="any"
                value={discoverCfg[key] ?? ""}
                onChange={(e) => setCfg(key, e.target.value)}
              />
            </label>
          </p>
        ))}
        <button type="submit">Save discovery settings</button>
        {discoverSaved && <span> Saved.</span>}
      </form>
    </>
  );
}
