// Settings · currency, theme, AI toggle, tax rate, data management.

function maskedLicense(code) {
  if (!code) return "";
  const parts = code.split("-");
  if (parts.length <= 2) return code.slice(0, 4) + "•••";
  return parts[0] + "-" + parts.slice(1, -1).map(p => "•".repeat(Math.min(p.length, 4))).join("-") + "-" + parts[parts.length - 1];
}

function Settings() {
  const { state, setSetting, resetDemo, clearAll, loadFromBackup } = useStore();
  const fileRef = React.useRef(null);
  const [confirmReset, setConfirmReset] = React.useState(null);
  const [importMsg, setImportMsg] = React.useState(null);

  function onImport(e) {
    const f = e.target.files?.[0];
    if (!f) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      try {
        const data = JSON.parse(ev.target.result);
        loadFromBackup(data);
        setImportMsg("Backup imported successfully.");
      } catch (err) {
        setImportMsg("That file isn't a valid ExitOS backup.");
      }
      setTimeout(() => setImportMsg(null), 4000);
    };
    reader.readAsText(f);
    e.target.value = "";
  }

  return (
    <div className="exos-page">
      <div className="exos-page-head">
        <div>
          <div className="exos-kicker mono">SETTINGS</div>
          <h1 className="exos-h1">Make it yours.</h1>
          <div className="exos-page-head-sub">Currency, theme, tax assumptions, AI features, and your data · all under your control.</div>
        </div>
      </div>

      {/* Preferences */}
      <Card style={{ marginBottom: 14 }}>
        <SectionHeader kicker="PREFERENCES" title="Display" />
        <SettingRow
          title="Currency"
          sub="All values across the app convert from USD using current FX. Prices remain in USD internally."
        >
          <div style={{ display: "flex", gap: 4 }}>
            {Object.keys(FX).map(c => (
              <Button key={c} size="sm" variant={state.settings.currency === c ? "primary" : "secondary"}
                onClick={() => setSetting("currency", c)}>{c}</Button>
            ))}
          </div>
        </SettingRow>
        <SettingRow
          title="Theme"
          sub="Dark by default. Both modes are tuned for long sessions."
        >
          <div style={{ display: "flex", gap: 4 }}>
            <Button size="sm" variant={state.settings.theme === "dark" ? "primary" : "secondary"}
              icon={<Icons.Moon size={13} />} onClick={() => setSetting("theme", "dark")}>Dark</Button>
            <Button size="sm" variant={state.settings.theme === "light" ? "primary" : "secondary"}
              icon={<Icons.Sun size={13} />} onClick={() => setSetting("theme", "light")}>Light</Button>
          </div>
        </SettingRow>
        <SettingRow title="Density" sub="Trade vertical space for breathing room.">
          <div style={{ display: "flex", gap: 4 }}>
            {["compact", "default", "cozy"].map(d => (
              <Button key={d} size="sm" variant={state.settings.density === d ? "primary" : "secondary"}
                onClick={() => setSetting("density", d)}>{d}</Button>
            ))}
          </div>
        </SettingRow>
      </Card>

      {/* Calculations */}
      <Card style={{ marginBottom: 14 }}>
        <SectionHeader kicker="CALCULATIONS" title="Assumptions" />
        <SettingRow
          title="Tax reserve"
          sub="Flat % subtracted from gains to estimate net cash. Adjust for your jurisdiction."
        >
          <div style={{ width: 280 }}>
            <Slider value={Math.round(state.settings.taxRate * 100)}
              onChange={v => setSetting("taxRate", v / 100)}
              min={0} max={55} format={v => v + "%"} />
          </div>
        </SettingRow>
        <SettingRow
          title="Stablecoin reserve target"
          sub="Suggested % of total to keep in stablecoins after exits."
        >
          <div style={{ width: 280 }}>
            <Slider value={state.settings.stablecoinTargetPct ?? 25}
              onChange={v => setSetting("stablecoinTargetPct", v)}
              min={0} max={80} format={v => v + "%"} />
          </div>
        </SettingRow>
      </Card>

      {/* Live prices */}
      <Card style={{ marginBottom: 14 }}>
        <SectionHeader kicker="LIVE PRICES" title="Price source"
          sub="ExitOS comes with free live CoinGecko prices built in. Upgrade to your own key for faster updates." />
        <PriceSourcePicker />
        <div className="exos-priv-note">
          <Icons.Shield size={14} />
          <span>Your data is stored locally in your browser and is not uploaded to ExitOS servers. API keys never leave your device.</span>
        </div>
      </Card>

      {/* AI */}
      <Card style={{ marginBottom: 14 }}>
        <SectionHeader kicker="AI COACH" title="Smart assist (optional)" />
        <p style={{ margin: "0 0 14px", color: "var(--text-mute)", fontSize: 13, maxWidth: 680, lineHeight: 1.6 }}>
          ExitOS is <strong style={{ color: "var(--text)" }}>fully functional without AI.</strong> The Plan Quality score,
          Behavioral Insights, Mirror read, Round-Trip Risk, recovery math, and Regret Simulator all run on deterministic
          logic in your browser. They don't need an API.
        </p>
        <p style={{ margin: "0 0 16px", color: "var(--text-mute)", fontSize: 13, maxWidth: 680, lineHeight: 1.6 }}>
          What AI <em>adds</em>: a more nuanced, written-out version of the Mirror and Plan Narrator · the same observations,
          but in flowing prose with sharper phrasing. Useful if you want a coach-style read. Skip it if you don't.
        </p>
        <div className="exos-ai-features">
          <Feature on={true} title="Behavioral Mirror · always on" sub="Deterministic read on your plan's posture. Free, instant, no API." />
          <Feature on={!!state.settings.byokAnthropicKey} title="AI rewrite · BYOK" sub="With your Anthropic key: nuanced narrative version of the Mirror." />
          <Feature on={!!state.settings.byokAnthropicKey} title="Plan Narrator · BYOK" sub="Reports page summary in plain English. Optional." />
        </div>
        <AiAccessPanel />
      </Card>

      {/* Data */}
      <Card style={{ marginBottom: 14 }}>
        <SectionHeader kicker="YOUR DATA" title="Backup, transfer & reset" />
        <SettingRow title="License" sub={
          state.settings.aiLicenseCode
            ? <>Active on this device · <span className="mono" style={{ color: "var(--text)" }}>{maskedLicense(state.settings.aiLicenseCode)}</span></>
            : "No license active."
        }>
          {state.settings.aiLicenseCode && (
            <Button variant="ghost" onClick={() => {
              if (confirm("Deactivate ExitOS on this device? You'll need to re-enter your license code to use the app again. Your data stays · export a backup first if you're switching devices.")) {
                setSetting("aiLicenseCode", "");
              }
            }}>Deactivate device</Button>
          )}
        </SettingRow>
        <SettingRow title="Export backup" sub="Download everything (holdings, ladders, scenarios, settings) as JSON.">
          <Button icon={<Icons.Download size={14} />} onClick={() => {
            const data = JSON.stringify(state, null, 2);
            const blob = new Blob([data], { type: "application/json" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a"); a.href = url;
            a.download = `exitos-backup-${new Date().toISOString().slice(0,10)}.json`;
            a.click(); URL.revokeObjectURL(url);
          }}>Download JSON</Button>
        </SettingRow>
        <SettingRow title="Import backup" sub="Restore from a previously-downloaded JSON file.">
          <Button icon={<Icons.Upload size={14} />} onClick={() => fileRef.current?.click()}>Choose file…</Button>
          <input type="file" accept="application/json" ref={fileRef} onChange={onImport} style={{ display: "none" }} />
        </SettingRow>
        {importMsg && <div style={{ padding: "8px 12px", fontSize: 12, color: "var(--text-mute)", marginTop: 4 }}>{importMsg}</div>}
        <SettingRow title="Reset to demo" sub="Restore the example portfolio and default ladders. Your settings are kept.">
          <Button onClick={() => setConfirmReset("demo")}>Reset to demo</Button>
        </SettingRow>
        <SettingRow title="Clear everything" sub="Wipe holdings, ladders, and transactions. This cannot be undone.">
          <Button variant="danger" icon={<Icons.Trash size={14} />} onClick={() => setConfirmReset("clear")}>Clear all data</Button>
        </SettingRow>
      </Card>

      <div className="exos-about">
        <span className="mono">EXITOS v1.0</span>
        <span>· local-only · no accounts · no servers</span>
      </div>

      <Modal open={confirmReset != null} onClose={() => setConfirmReset(null)}
        title={confirmReset === "clear" ? "Clear everything?" : "Reset to demo?"}
        footer={<>
          <Button onClick={() => setConfirmReset(null)}>Cancel</Button>
          <Button variant="primary" onClick={() => {
            if (confirmReset === "clear") clearAll();
            else resetDemo();
            setConfirmReset(null);
          }}>{confirmReset === "clear" ? "Clear all" : "Reset"}</Button>
        </>}>
        <p style={{ margin: 0, color: "var(--text-mute)", fontSize: 14 }}>
          {confirmReset === "clear"
            ? "All your holdings, ladders, and scenarios will be deleted. Your preferences will stay."
            : "Your data will be replaced with the example portfolio. Export a backup first if you want to keep your current setup."}
        </p>
      </Modal>
    </div>
  );
}

function PriceSourcePicker() {
  const { state, setSetting, priceStatus } = useStore();
  const cur = state.settings.priceSource;
  const key = state.settings.coingeckoKey || "";
  const [testing, setTesting] = React.useState(false);
  const [testResult, setTestResult] = React.useState(null);

  async function runTest() {
    setTesting(true);
    setTestResult(null);
    const result = await cgTestConnection(cur, key);
    setTestResult(result);
    setTesting(false);
  }

  const sources = [
    { id: "coingecko-public",title: "Live prices · included free",   sub: "Public CoinGecko API. Real prices for every major coin, no key required. Updates every ~90 seconds. Rate-limited during heavy traffic.", tag: "default" },
    { id: "coingecko-demo",  title: "Live prices · your free CoinGecko key",   sub: "Faster updates (~45 s) and more reliable. Free key · sign up at coingecko.com, paste it here.", tag: "recommended", needsKey: true },
    { id: "coingecko-pro",   title: "Live prices · your CoinGecko Pro key",    sub: "Paid CoinGecko plan. Highest rate limits · only needed if you're refreshing constantly.", tag: "pro", needsKey: true },
    { id: "demo",            title: "Simulated prices",                        sub: "Realistic mock prices that update every couple seconds. Useful if you're offline or just exploring.", tag: null },
    { id: "manual",          title: "Manual prices only",                      sub: "Set each coin's price by hand on the Portfolio page. No network calls at all.", tag: null },
  ];

  return (
    <div className="exos-price-source">
      {sources.map(s => {
        const active = cur === s.id;
        const showsKeyInput = active && s.needsKey;
        return (
          <div key={s.id} className={`exos-source-block ${active ? "on" : ""}`}>
            <button className="exos-price-source-row" onClick={() => { setSetting("priceSource", s.id); setTestResult(null); }}>
              <div className="exos-price-source-radio" data-on={active}>{active && <span />}</div>
              <div style={{ flex: 1, textAlign: "left", minWidth: 0 }}>
                <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
                  <span style={{ fontWeight: 500 }}>{s.title}</span>
                  {s.tag === "default" && <Pill tone="gain" dot>included free</Pill>}
                  {s.tag === "recommended" && <Pill tone="accent" dot>recommended</Pill>}
                  {s.tag === "pro" && <Pill>pro</Pill>}
                  {s.tag === "free" && <Pill>free</Pill>}
                </div>
                <div style={{ fontSize: 12, color: "var(--text-mute)", marginTop: 3 }}>{s.sub}</div>
              </div>
            </button>

            {showsKeyInput && (
              <div className="exos-source-keypane">
                <div className="exos-label" style={{ marginBottom: 6 }}>{s.id === "coingecko-pro" ? "Pro API key" : "Demo API key"}</div>
                <div style={{ display: "flex", gap: 8 }}>
                  <TextInput
                    value={key}
                    onChange={v => setSetting("coingeckoKey", v)}
                    placeholder={s.id === "coingecko-pro" ? "CG-prod-…" : "CG-demo-…"}
                    type="password"
                  />
                  <Button onClick={runTest} disabled={testing || !key} variant="primary">
                    {testing ? "Testing…" : "Test"}
                  </Button>
                </div>
                <div className="exos-source-help">
                  <Icons.Sparkle size={11} />
                  <span>Get a free Demo key at <a href="https://www.coingecko.com/en/api/pricing" target="_blank" rel="noreferrer" className="exos-link">coingecko.com/api/pricing</a> → "Demo" tier. Paste it here, click Test.</span>
                </div>
                {testResult && (
                  <div className={`exos-source-result ${testResult.ok ? "ok" : "err"}`}>
                    {testResult.ok ? <Icons.Check size={13} /> : <Icons.Warning size={13} />}
                    <span>{testResult.msg}</span>
                  </div>
                )}
              </div>
            )}

            {active && s.id === "coingecko-public" && (
              <div className="exos-source-keypane">
                <Button size="sm" onClick={runTest} disabled={testing}>{testing ? "Testing…" : "Test connection"}</Button>
                {testResult && (
                  <div className={`exos-source-result ${testResult.ok ? "ok" : "err"}`} style={{ marginTop: 8 }}>
                    {testResult.ok ? <Icons.Check size={13} /> : <Icons.Warning size={13} />}
                    <span>{testResult.msg}</span>
                  </div>
                )}
              </div>
            )}
          </div>
        );
      })}

      <div className={`exos-source-status ${priceStatus.ok ? "ok" : "err"}`}>
        <span className="exos-status-dot" />
        <span style={{ fontSize: 12 }}>{priceStatus.msg || (priceStatus.ok ? "Connected" : "Not connected")}</span>
      </div>
    </div>
  );
}

function SettingRow({ title, sub, children }) {
  return (
    <div className="exos-set-row">
      <div className="exos-set-text">
        <div className="exos-set-title">{title}</div>
        {sub && <div className="exos-set-sub">{sub}</div>}
      </div>
      <div className="exos-set-action">{children}</div>
    </div>
  );
}

function PriceSourceRow({ id, current, onChange, title, sub, tag }) {
  // kept for backward-compat · unused after PriceSourcePicker rewrite
  const active = current === id;
  return null;
}

function Feature({ on, title, sub }) {
  return (
    <div className={`exos-feature ${on ? "on" : ""}`}>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
        <span className={`exos-feature-dot ${on ? "on" : ""}`} />
        <span style={{ fontWeight: 500, fontSize: 13 }}>{title}</span>
      </div>
      <div style={{ fontSize: 12, color: "var(--text-mute)" }}>{sub}</div>
    </div>
  );
}

function AiAccessPanel() {
  const { state, setSetting } = useStore();
  const hasKey = !!state.settings.byokAnthropicKey;

  return (
    <div className="exos-ai-access">
      <div className="exos-ai-tier" style={{ borderTop: 0, paddingTop: 0 }}>
        <div style={{ flex: 1 }}>
          <div className="exos-set-title">Anthropic API key (optional)</div>
          <div className="exos-set-sub">
            ExitOS works fully without AI. The behavioral insights, mirror read, score, and recovery math
            are all calculated locally. Add an Anthropic key to enable a richer, AI-written version of
            the Behavioral Mirror and Plan Narrator. Your key stays in this browser · never uploaded.
          </div>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 6, alignItems: "flex-end" }}>
          {hasKey && <Pill tone="gain" dot>connected</Pill>}
        </div>
      </div>
      <div style={{ display: "flex", gap: 8 }}>
        <TextInput
          value={state.settings.byokAnthropicKey || ""}
          onChange={v => setSetting("byokAnthropicKey", v)}
          placeholder="sk-ant-api03-…"
          type="password"
        />
        {hasKey && <Button variant="ghost" onClick={() => setSetting("byokAnthropicKey", "")}>Clear</Button>}
      </div>
      <div className="exos-source-help">
        <Icons.Sparkle size={11} />
        <span>Get a key at <a href="https://console.anthropic.com/" target="_blank" rel="noreferrer" className="exos-link">console.anthropic.com</a>. Cost: roughly $0.0003 per call (Haiku 4.5). 100 calls ≈ 3 cents.</span>
      </div>
    </div>
  );
}

const SETTINGS_STYLES = `
.exos-set-row { display: flex; align-items: center; gap: 18px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.exos-set-row:first-of-type { padding-top: 10px; }
.exos-set-row:last-of-type { border-bottom: 0; padding-bottom: 4px; }
.exos-set-text { flex: 1; min-width: 0; }
.exos-set-title { font-size: 14px; font-weight: 500; }
.exos-set-sub { font-size: 12px; color: var(--text-mute); margin-top: 2px; max-width: 540px; }
.exos-set-action { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }

.exos-price-source { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.exos-source-block { background: var(--bg-elev-2); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; transition: border-color .12s, background .12s; }
.exos-source-block.on { border-color: var(--accent-line); background: var(--accent-soft); }
.exos-source-block.on .exos-price-source-row { background: transparent; border: 0; }
.exos-price-source-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; background: transparent; border: 0; border-radius: 10px;
  text-align: left; cursor: pointer; transition: background .12s;
  color: var(--text); font: inherit; width: 100%;
}
.exos-source-block:not(.on):hover { border-color: var(--line-strong); }
.exos-source-block:not(.on) .exos-price-source-row:hover { background: var(--bg-hover); }
.exos-price-source-radio {
  width: 16px; height: 16px; border-radius: 50%;
  border: 1.5px solid var(--line-strong); display: grid; place-items: center;
  flex-shrink: 0;
}
.exos-price-source-radio[data-on="true"] { border-color: var(--accent); }
.exos-price-source-radio[data-on="true"] span { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }

.exos-source-keypane { padding: 12px 14px 14px 42px; border-top: 1px solid var(--line); }
.exos-source-help {
  display: flex; gap: 6px; align-items: flex-start; margin-top: 8px;
  font-size: 11.5px; color: var(--text-mute); line-height: 1.5;
}
.exos-source-help svg { color: var(--accent); margin-top: 2px; flex-shrink: 0; }
.exos-link { color: var(--accent); text-decoration: underline; text-decoration-color: var(--accent-line); }
.exos-link:hover { text-decoration-color: var(--accent); }
.exos-source-result {
  display: flex; align-items: center; gap: 6px;
  margin-top: 10px; padding: 7px 10px; border-radius: 6px;
  font-size: 12px;
}
.exos-source-result.ok { background: var(--gain-soft); color: var(--gain); }
.exos-source-result.err { background: var(--loss-soft); color: var(--loss); }

.exos-source-status {
  display: flex; align-items: center; gap: 8px;
  margin-top: 4px; padding: 8px 10px;
  background: var(--bg); border: 1px dashed var(--line); border-radius: 8px;
  color: var(--text-mute);
}
.exos-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gain); }
.exos-source-status.err .exos-status-dot { background: var(--loss); }

.exos-priv-note {
  display: flex; align-items: center; gap: 8px; padding: 10px 12px;
  background: var(--bg-elev-2); border-radius: 8px; margin-top: 12px;
  font-size: 12px; color: var(--text-mute);
}

.exos-ai-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.exos-feature { padding: 12px; background: var(--bg-elev-2); border: 1px solid var(--line); border-radius: 10px; transition: opacity .15s; opacity: 0.6; }
.exos-feature.on { opacity: 1; border-color: var(--accent-line); }
.exos-feature-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); transition: background .15s; }
.exos-feature-dot.on { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
@media (max-width: 760px) { .exos-ai-features { grid-template-columns: 1fr; } }

.exos-ai-access {
  margin-top: 16px; padding: 14px;
  background: var(--bg-elev-2); border: 1px solid var(--line); border-radius: 10px;
  display: flex; flex-direction: column; gap: 14px;
}
.exos-ai-usage { display: flex; flex-direction: column; gap: 10px; }
.exos-ai-usage-bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.exos-ai-usage-fill { height: 100%; transition: width .3s; }
.exos-ai-tier {
  display: flex; align-items: flex-start; gap: 16px;
  padding-top: 14px; border-top: 1px solid var(--line);
}
.exos-ai-tier .exos-set-title { font-size: 13px; }
.exos-ai-tier .exos-set-sub { font-size: 12px; margin-top: 2px; }

.exos-about { padding: 18px 4px; font-size: 11px; color: var(--text-dim); text-align: center; }
.exos-about .mono { color: var(--text-mute); }
`;
(function(){ if(document.getElementById("exos-settings-styles")) return; const t=document.createElement("style"); t.id="exos-settings-styles"; t.textContent=SETTINGS_STYLES; document.head.appendChild(t); })();

window.Settings = Settings;
