import { FormEvent, useEffect, useState } from "react";
import {
  changeCredentials,
  getUsername,
  setSession,
  apiFetch,
  StrategySettings,
  RuntimeSettings,
} from "../api/client";

type Tab = "strategy" | "runtime" | "account";

export default function SettingsPage() {
  const [tab, setTab] = useState<Tab>("strategy");

  const [newUsername, setNewUsername] = useState(getUsername() || "admin");
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [err, setErr] = useState("");
  const [ok, setOk] = useState("");
  const [loading, setLoading] = useState(false);

  const [fee, setFee] = useState(0.0005);
  const [exitMode, setExitMode] = useState<"fixed_usdt" | "premium_multiple">(
    "fixed_usdt",
  );
  const [netTarget, setNetTarget] = useState(15);
  const [premMult, setPremMult] = useState(1);
  const [rest, setRest] = useState(300);
  const [orderInterval, setOrderInterval] = useState(1);
  const [skipWeekends, setSkipWeekends] = useState(true);
  const [leverage, setLeverage] = useState(3);
  const [minHours, setMinHours] = useState(12);
  const [minOptLev, setMinOptLev] = useState(100);
  const [atmOffOn, setAtmOffOn] = useState(false);
  const [maxAtmOff, setMaxAtmOff] = useState(3);
  const [closeDevPct, setCloseDevPct] = useState(30);
  const [perpQty, setPerpQty] = useState(1);
  const [optQty, setOptQty] = useState(2);
  const [initialEquity, setInitialEquity] = useState(10000);
  const [exchange, setExchange] = useState<"okx" | "binance">("okx");
  const [stratOk, setStratOk] = useState("");

  const [runtime, setRuntime] = useState<RuntimeSettings | null>(null);
  const [mode, setMode] = useState<"SIM" | "LIVE">("SIM");
  const [okxKey, setOkxKey] = useState("");
  const [okxSecret, setOkxSecret] = useState("");
  const [okxPass, setOkxPass] = useState("");
  const [bnKey, setBnKey] = useState("");
  const [bnSecret, setBnSecret] = useState("");
  const [runtimeOk, setRuntimeOk] = useState("");

  function loadRuntime() {
    apiFetch<RuntimeSettings>("/api/settings/runtime")
      .then((r) => {
        setRuntime(r);
        setMode(r.mode === "LIVE" ? "LIVE" : "SIM");
      })
      .catch(() => undefined);
  }

  useEffect(() => {
    apiFetch<StrategySettings>("/api/settings/strategy")
      .then((s) => {
        setFee(s.fee_rate);
        setExitMode(s.exit_mode === "premium_multiple" ? "premium_multiple" : "fixed_usdt");
        setNetTarget(s.net_profit_target ?? 15);
        setPremMult(s.premium_exit_multiple ?? 1);
        setRest(s.rest_seconds);
        setOrderInterval(s.live_order_interval_sec ?? 1);
        setSkipWeekends(s.skip_weekends !== false);
        setLeverage(s.leverage ?? 3);
        setMinHours(s.min_option_hours ?? 12);
        setMinOptLev(s.min_option_leverage ?? 100);
        setAtmOffOn(s.atm_open_offset_enabled === true);
        setMaxAtmOff(s.max_atm_open_offset ?? 3);
        setCloseDevPct(s.close_bid_mark_max_pct ?? 30);
        setPerpQty(s.perp_qty_eth ?? 1);
        setOptQty(s.option_qty_eth ?? 2);
        setInitialEquity(s.initial_equity ?? 10000);
        setExchange(s.exchange === "binance" ? "binance" : "okx");
      })
      .catch(() => undefined);
    loadRuntime();
  }, []);

  async function onSaveCreds(e: FormEvent) {
    e.preventDefault();
    setErr("");
    setOk("");
    if (newPassword !== confirmPassword) {
      setErr("两次输入的新密码不一致");
      return;
    }
    if (newPassword.length < 4) {
      setErr("新密码至少 4 位");
      return;
    }
    setLoading(true);
    try {
      const res = await changeCredentials({
        current_password: currentPassword,
        new_username: newUsername.trim(),
        new_password: newPassword,
      });
      setSession(res.token, res.username);
      setCurrentPassword("");
      setNewPassword("");
      setConfirmPassword("");
      setOk("用户名/密码已更新");
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    } finally {
      setLoading(false);
    }
  }

  async function onSaveStrategy(e: FormEvent) {
    e.preventDefault();
    setStratOk("");
    setErr("");
    try {
      await apiFetch("/api/settings/strategy", {
        method: "PUT",
        body: JSON.stringify({
          fee_rate: fee,
          exit_mode: exitMode,
          net_profit_target: netTarget,
          premium_exit_multiple: premMult,
          rest_seconds: rest,
          live_order_interval_sec: orderInterval,
          skip_weekends: skipWeekends,
          leverage,
          min_option_hours: minHours,
          min_option_leverage: minOptLev,
          atm_open_offset_enabled: atmOffOn,
          max_atm_open_offset: maxAtmOff,
          close_bid_mark_max_pct: closeDevPct,
          perp_qty_eth: perpQty,
          option_qty_eth: optQty,
          initial_equity: initialEquity,
          exchange,
        }),
      });
      setStratOk(
        "策略参数已保存（切换交易所/改模拟资金需无持仓；切换后会重连行情）",
      );
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    }
  }

  async function onSaveRuntime(e: FormEvent) {
    e.preventDefault();
    setErr("");
    setRuntimeOk("");
    const goingLive = mode === "LIVE" && runtime?.mode !== "LIVE";
    if (goingLive) {
      const typed = window.prompt('切换到 LIVE 实盘：请输入 LIVE 确认（将真实下单）');
      if (typed !== "LIVE") {
        setErr("已取消：须输入 LIVE 才能切换到实盘");
        return;
      }
    }
    setLoading(true);
    try {
      const body: Record<string, unknown> = {
        mode,
        confirm_live: goingLive,
      };
      if (okxKey.trim()) body.okx_api_key = okxKey.trim();
      if (okxSecret.trim()) body.okx_api_secret = okxSecret.trim();
      if (okxPass.trim()) body.okx_api_passphrase = okxPass.trim();
      if (bnKey.trim()) body.binance_api_key = bnKey.trim();
      if (bnSecret.trim()) body.binance_api_secret = bnSecret.trim();
      const r = await apiFetch<RuntimeSettings>("/api/settings/runtime", {
        method: "PUT",
        body: JSON.stringify(body),
      });
      setRuntime(r);
      setMode(r.mode === "LIVE" ? "LIVE" : "SIM");
      setOkxKey("");
      setOkxSecret("");
      setOkxPass("");
      setBnKey("");
      setBnSecret("");
      setRuntimeOk(
        r.mode === "LIVE"
          ? r.live_ready
            ? "已切换 LIVE，密钥已写入 .env"
            : `已切 LIVE，但未就绪：${r.live_ready_reason}`
          : "已切换 SIM，配置已写入 .env",
      );
    } catch (ex) {
      setErr(ex instanceof Error ? ex.message : String(ex));
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="settings-page">
      <h2 style={{ marginTop: 0 }}>系统设置</h2>
      <div className="tabs">
        <button
          type="button"
          className={tab === "strategy" ? "tab active" : "tab"}
          onClick={() => setTab("strategy")}
        >
          策略设置
        </button>
        <button
          type="button"
          className={tab === "runtime" ? "tab active" : "tab"}
          onClick={() => {
            setTab("runtime");
            loadRuntime();
          }}
        >
          运行模式
        </button>
        <button
          type="button"
          className={tab === "account" ? "tab active" : "tab"}
          onClick={() => setTab("account")}
        >
          登录账户
        </button>
      </div>

      {tab === "strategy" ? (
        <div className="card settings-card">
          <p className="settings-lead">
            无开仓时间窗；可切换 OKX / 币安行情（SIM 本地撮合）；周六日可跳过开仓；出场按净盈利或到期全平。
          </p>
          {stratOk ? <div className="settings-ok">{stratOk}</div> : null}
          {err && tab === "strategy" ? <div className="err">{err}</div> : null}
          <form onSubmit={onSaveStrategy}>
            <section className="settings-section">
              <h3>交易所</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="exch">行情交易所（SIM 只读）</label>
                  <select
                    id="exch"
                    className="mono"
                    value={exchange}
                    onChange={(e) =>
                      setExchange(e.target.value === "binance" ? "binance" : "okx")
                    }
                  >
                    <option value="okx">OKX（USDC 期权族）</option>
                    <option value="binance">币安（USDT 永续 + 欧洲期权）</option>
                  </select>
                  <p className="settings-hint">
                    有持仓时不可切换。切换后自动套用该所合约并重连公共行情。
                  </p>
                </div>
              </div>
            </section>

            <section className="settings-section">
              <h3>资金</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="equity">模拟资金（USDT）</label>
                  <input
                    id="equity"
                    className="mono"
                    type="number"
                    step="100"
                    min="1000"
                    value={initialEquity}
                    onChange={(e) => setInitialEquity(Number(e.target.value))}
                  />
                  <p className="settings-hint">
                    保存后将权益重置为该金额（须无持仓）。默认 10000。
                  </p>
                </div>
                <div className="field">
                  <label htmlFor="lev">永续杠杆倍数</label>
                  <input
                    id="lev"
                    className="mono"
                    type="number"
                    step="1"
                    min="1"
                    value={leverage}
                    onChange={(e) => setLeverage(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="perp">永续 ETH 数量</label>
                  <input
                    id="perp"
                    className="mono"
                    type="number"
                    step="0.01"
                    min="0.01"
                    value={perpQty}
                    onChange={(e) => setPerpQty(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="opt">期权 ETH 数量</label>
                  <input
                    id="opt"
                    className="mono"
                    type="number"
                    step="0.01"
                    min="0.01"
                    value={optQty}
                    onChange={(e) => setOptQty(Number(e.target.value))}
                  />
                </div>
              </div>
            </section>

            <section className="settings-section">
              <h3>选约</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="hours">期权最小剩余小时</label>
                  <input
                    id="hours"
                    className="mono"
                    type="number"
                    step="1"
                    min="1"
                    value={minHours}
                    onChange={(e) => setMinHours(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="olev">期权杠杆下限（现价÷卖一权利金）</label>
                  <input
                    id="olev"
                    className="mono"
                    type="number"
                    step="1"
                    min="1"
                    value={minOptLev}
                    onChange={(e) => setMinOptLev(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="atmoffOn">开仓 ATM 偏差限制</label>
                  <select
                    id="atmoffOn"
                    className="mono"
                    value={atmOffOn ? "1" : "0"}
                    onChange={(e) => setAtmOffOn(e.target.value === "1")}
                  >
                    <option value="0">关闭（默认）</option>
                    <option value="1">开启</option>
                  </select>
                  <p className="settings-hint">
                    关闭时不限制 |ATM − 现价|；开启后超过下方点数则不开仓。
                  </p>
                </div>
                <div className="field">
                  <label htmlFor="atmoff">开仓 ATM 最大偏差（点）</label>
                  <input
                    id="atmoff"
                    className="mono"
                    type="number"
                    step="0.5"
                    min="0"
                    disabled={!atmOffOn}
                    value={maxAtmOff}
                    onChange={(e) => setMaxAtmOff(Number(e.target.value))}
                  />
                  <p className="settings-hint">
                    仅在上方开关开启时生效。默认 3；币安行权价步进较粗时可能长时间无开仓机会。
                  </p>
                </div>
              </div>
            </section>

            <section className="settings-section">
              <h3>出场与风控</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="exitMode">出场规则</label>
                  <select
                    id="exitMode"
                    className="mono"
                    value={exitMode}
                    onChange={(e) =>
                      setExitMode(
                        e.target.value === "premium_multiple"
                          ? "premium_multiple"
                          : "fixed_usdt",
                      )
                    }
                  >
                    <option value="fixed_usdt">固定净盈利（USDT）</option>
                    <option value="premium_multiple">权利金倍数</option>
                  </select>
                </div>
                {exitMode === "fixed_usdt" ? (
                  <div className="field">
                    <label htmlFor="netTarget">净盈利出场目标（USDT）</label>
                    <input
                      id="netTarget"
                      className="mono"
                      type="number"
                      step="0.1"
                      min="0.1"
                      value={netTarget}
                      onChange={(e) => setNetTarget(Number(e.target.value))}
                    />
                  </div>
                ) : (
                  <div className="field">
                    <label htmlFor="premMult">权利金倍数（1 = 一倍权利金）</label>
                    <input
                      id="premMult"
                      className="mono"
                      type="number"
                      step="0.1"
                      min="0.1"
                      value={premMult}
                      onChange={(e) => setPremMult(Number(e.target.value))}
                    />
                  </div>
                )}
                <div className="field">
                  <label htmlFor="closeDev">平仓买一/标记最大偏差（%）</label>
                  <input
                    id="closeDev"
                    className="mono"
                    type="number"
                    step="1"
                    min="1"
                    value={closeDevPct}
                    onChange={(e) => setCloseDevPct(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="rest">轮间休息秒数</label>
                  <input
                    id="rest"
                    className="mono"
                    type="number"
                    step="1"
                    value={rest}
                    onChange={(e) => setRest(Number(e.target.value))}
                  />
                </div>
                <div className="field">
                  <label htmlFor="orderInterval">实盘下单最小间隔（秒）</label>
                  <input
                    id="orderInterval"
                    className="mono"
                    type="number"
                    step="0.1"
                    min="0.2"
                    max="30"
                    value={orderInterval}
                    onChange={(e) => setOrderInterval(Number(e.target.value))}
                  />
                  <p className="settings-hint">
                    LIVE 私有下单/查单间隔，默认 1s（非高频建议 ≥1）。范围
                    0.2–30。保存后立即生效。
                  </p>
                </div>
                <div className="field">
                  <label htmlFor="skipWe">周六日跳过开仓（上海时区）</label>
                  <select
                    id="skipWe"
                    className="mono"
                    value={skipWeekends ? "1" : "0"}
                    onChange={(e) => setSkipWeekends(e.target.value === "1")}
                  >
                    <option value="1">开启（推荐）</option>
                    <option value="0">关闭</option>
                  </select>
                </div>
                <div className="field">
                  <label htmlFor="fee">手续费率</label>
                  <input
                    id="fee"
                    className="mono"
                    type="number"
                    step="0.0001"
                    value={fee}
                    onChange={(e) => setFee(Number(e.target.value))}
                  />
                </div>
              </div>
            </section>

            <div className="settings-actions">
              <button className="btn" type="submit">
                保存策略
              </button>
            </div>
          </form>
        </div>
      ) : null}

      {tab === "runtime" ? (
        <div className="card settings-card">
          <p className="settings-lead">
            SIM = 本地撮合；LIVE = 当前所选交易所真下单（OKX / 币安均已接入）。密钥只写入服务器{" "}
            <span className="mono">.env</span>，接口不回传明文。OKX 期权常需账户有 USDC；币安多为 USDT。
          </p>
          {runtimeOk ? <div className="settings-ok">{runtimeOk}</div> : null}
          {err && tab === "runtime" ? <div className="err">{err}</div> : null}
          <form onSubmit={onSaveRuntime}>
            <section className="settings-section">
              <h3>模式</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="mode">运行模式</label>
                  <select
                    id="mode"
                    className="mono"
                    value={mode}
                    onChange={(e) =>
                      setMode(e.target.value === "LIVE" ? "LIVE" : "SIM")
                    }
                  >
                    <option value="SIM">SIM 本地模拟</option>
                    <option value="LIVE">LIVE 实盘</option>
                  </select>
                  <p className="settings-hint">
                    当前：{runtime?.mode || "—"} · 交易所 {runtime?.exchange || "—"} ·{" "}
                    {runtime?.mode === "LIVE"
                      ? runtime.live_ready
                        ? "LIVE 就绪"
                        : `未就绪(${runtime.live_ready_reason})`
                      : "SIM"}
                    。有持仓时不可切换模式。
                  </p>
                </div>
              </div>
            </section>

            <section className="settings-section">
              <h3>OKX API</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="okxKey">API Key</label>
                  <input
                    id="okxKey"
                    className="mono"
                    type="password"
                    autoComplete="off"
                    placeholder={
                      runtime?.okx_api_key_masked
                        ? `已配置 ${runtime.okx_api_key_masked}`
                        : "未配置"
                    }
                    value={okxKey}
                    onChange={(e) => setOkxKey(e.target.value)}
                  />
                </div>
                <div className="field">
                  <label htmlFor="okxSecret">Secret</label>
                  <input
                    id="okxSecret"
                    className="mono"
                    type="password"
                    autoComplete="off"
                    placeholder={
                      runtime?.okx_api_secret_masked
                        ? `已配置 ${runtime.okx_api_secret_masked}`
                        : "未配置"
                    }
                    value={okxSecret}
                    onChange={(e) => setOkxSecret(e.target.value)}
                  />
                </div>
                <div className="field">
                  <label htmlFor="okxPass">Passphrase</label>
                  <input
                    id="okxPass"
                    className="mono"
                    type="password"
                    autoComplete="off"
                    placeholder={
                      runtime?.okx_api_passphrase_masked
                        ? `已配置 ${runtime.okx_api_passphrase_masked}`
                        : "未配置"
                    }
                    value={okxPass}
                    onChange={(e) => setOkxPass(e.target.value)}
                  />
                </div>
              </div>
            </section>

            <section className="settings-section">
              <h3>币安 API</h3>
              <div className="settings-fields">
                <div className="field">
                  <label htmlFor="bnKey">API Key</label>
                  <input
                    id="bnKey"
                    className="mono"
                    type="password"
                    autoComplete="off"
                    placeholder={
                      runtime?.binance_api_key_masked
                        ? `已配置 ${runtime.binance_api_key_masked}`
                        : "未配置"
                    }
                    value={bnKey}
                    onChange={(e) => setBnKey(e.target.value)}
                  />
                </div>
                <div className="field">
                  <label htmlFor="bnSecret">Secret</label>
                  <input
                    id="bnSecret"
                    className="mono"
                    type="password"
                    autoComplete="off"
                    placeholder={
                      runtime?.binance_api_secret_masked
                        ? `已配置 ${runtime.binance_api_secret_masked}`
                        : "未配置"
                    }
                    value={bnSecret}
                    onChange={(e) => setBnSecret(e.target.value)}
                  />
                </div>
                <p className="settings-hint">
                  留空保存=不覆盖已有密钥。交易所选币安且 LIVE 时用此密钥真下单（无
                  Passphrase）。
                </p>
              </div>
            </section>

            <div className="settings-actions">
              <button className="btn" type="submit" disabled={loading}>
                {loading ? "保存中…" : "保存模式与密钥"}
              </button>
            </div>
          </form>
        </div>
      ) : null}

      {tab === "account" ? (
        <div className="card settings-card settings-card-narrow">
          {err ? <div className="err">{err}</div> : null}
          {ok ? <div className="settings-ok">{ok}</div> : null}
          <form onSubmit={onSaveCreds} className="settings-account-form">
            <div className="settings-fields">
              <div className="field">
                <label htmlFor="user">新用户名</label>
                <input
                  id="user"
                  value={newUsername}
                  onChange={(e) => setNewUsername(e.target.value)}
                  required
                />
              </div>
              <div className="field">
                <label htmlFor="cur">当前密码</label>
                <input
                  id="cur"
                  type="password"
                  value={currentPassword}
                  onChange={(e) => setCurrentPassword(e.target.value)}
                  required
                />
              </div>
              <div className="field">
                <label htmlFor="np">新密码</label>
                <input
                  id="np"
                  type="password"
                  value={newPassword}
                  onChange={(e) => setNewPassword(e.target.value)}
                  required
                />
              </div>
              <div className="field">
                <label htmlFor="cp">确认新密码</label>
                <input
                  id="cp"
                  type="password"
                  value={confirmPassword}
                  onChange={(e) => setConfirmPassword(e.target.value)}
                  required
                />
              </div>
            </div>
            <div className="settings-actions">
              <button className="btn" type="submit" disabled={loading}>
                {loading ? "保存中…" : "保存账号"}
              </button>
            </div>
          </form>
        </div>
      ) : null}
    </div>
  );
}
