import { useEffect, useState } from "react";
import { apiFetch, MarketSnapshot, PlanState } from "../api/client";

function fmt(n: number | null | undefined, d = 2) {
  if (n == null || Number.isNaN(n)) return "—";
  return n.toFixed(d);
}

function pnlClass(n: number | null | undefined) {
  if (n == null || Number.isNaN(n) || n === 0) return "";
  return n > 0 ? "pos-pnl-profit" : "pos-pnl-loss";
}

/** OKX 期权到期：YYMMDD 当日 08:00 UTC（上海 16:00） */
function expiryMsFromYmd(ymd: string | null | undefined): number | null {
  if (!ymd || ymd.length !== 6) return null;
  const yy = 2000 + Number(ymd.slice(0, 2));
  const mm = Number(ymd.slice(2, 4));
  const dd = Number(ymd.slice(4, 6));
  if (![yy, mm, dd].every((x) => Number.isFinite(x))) return null;
  return Date.UTC(yy, mm - 1, dd, 8, 0, 0);
}

function formatCountdown(msLeft: number): string {
  if (msLeft <= 0) return "已到期";
  const s = Math.floor(msLeft / 1000);
  const d = Math.floor(s / 86400);
  const h = Math.floor((s % 86400) / 3600);
  const m = Math.floor((s % 3600) / 60);
  const sec = s % 60;
  if (d > 0) return `${d}天 ${h}时 ${String(m).padStart(2, "0")}分`;
  if (h > 0) return `${h}时 ${String(m).padStart(2, "0")}分 ${String(sec).padStart(2, "0")}秒`;
  return `${m}分 ${String(sec).padStart(2, "0")}秒`;
}

const PHASE_ZH: Record<string, string> = {
  idle: "空闲",
  wait_signal: "等待信号",
  opening: "开仓中",
  open: "持仓中",
  closing: "平仓中",
  resting: "休息中",
  paused: "已暂停",
  stopped: "已停开",
  outside_window: "窗外",
  liquidity_wait: "流动性等待",
};

export default function PlanPage() {
  const [snap, setSnap] = useState<MarketSnapshot | null>(null);
  const [plan, setPlan] = useState<PlanState | null>(null);
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState("");
  const [nowMs, setNowMs] = useState(() => Date.now());

  async function refresh() {
    try {
      const [m, p] = await Promise.all([
        apiFetch<MarketSnapshot>("/api/market/snapshot"),
        apiFetch<PlanState>("/api/plan/state"),
      ]);
      setSnap(m);
      setPlan(p);
      setErr("");
    } catch (e) {
      setErr(e instanceof Error ? e.message : String(e));
    }
  }

  useEffect(() => {
    refresh();
    const t = window.setInterval(refresh, 1500);
    return () => window.clearInterval(t);
  }, []);

  useEffect(() => {
    const t = window.setInterval(() => setNowMs(Date.now()), 1000);
    return () => window.clearInterval(t);
  }, []);

  async function act(path: string, label: string) {
    setBusy(label);
    setErr("");
    try {
      await apiFetch(path, { method: "POST", body: "{}" });
      await refresh();
    } catch (e) {
      setErr(e instanceof Error ? e.message : String(e));
    } finally {
      setBusy("");
    }
  }

  const bias = snap?.ask_compare?.bias;
  const biasTag =
    bias === "call_ask_gt_put" ? (
      <span className="tag up">买 Call + 永续空</span>
    ) : bias === "put_ask_gt_call" ? (
      <span className="tag down">买 Put + 永续多</span>
    ) : (
      <span className="tag">等待 / 相等</span>
    );

  const pos = plan?.position;
  const open = !!pos?.has_position;
  const exitMode = plan?.exit_mode ?? "fixed_usdt";
  const exitTarget = plan?.exit_target_usdt ?? plan?.net_profit_target ?? 15;
  const netPnl = pos?.net_pnl ?? 0;
  const movePct = pos?.move_pct ?? 0;
  const exitRuleLabel =
    exitMode === "premium_multiple"
      ? `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
      : `固定 ${fmt(plan?.net_profit_target ?? 15)} U`;
  const phaseLabel = PHASE_ZH[plan?.phase || ""] || plan?.phase || "—";
  const expiryMs =
    pos?.expiry_ms ?? expiryMsFromYmd(pos?.expiry_ymd) ?? null;
  const countdown =
    open && expiryMs != null ? formatCountdown(expiryMs - nowMs) : "—";
  const countdownUrgent =
    open && expiryMs != null && expiryMs - nowMs > 0 && expiryMs - nowMs < 6 * 3600_000;

  return (
    <div>
      <h2 style={{ marginTop: 0 }}>自动对冲计划</h2>
      <p style={{ color: "var(--muted)", marginTop: -8 }}>
        SIM 本地撮合 · 期权只买 · 剩余时长选到期 · 净盈利达标全平
      </p>
      {err ? <div className="err">{err}</div> : null}

      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
        <button
          className="btn"
          type="button"
          disabled={!!busy || plan?.running}
          onClick={() => act("/api/plan/start", "start")}
        >
          启动策略
        </button>
        <button
          className="btn ghost"
          type="button"
          disabled={!!busy || !plan?.running}
          onClick={() => act("/api/plan/pause", "pause")}
        >
          暂停
        </button>
        <button
          className="btn ghost"
          type="button"
          disabled={!!busy}
          onClick={() => act("/api/sim/open-group", "open")}
        >
          手动开一组
        </button>
        <button
          className="btn ghost"
          type="button"
          disabled={!!busy}
          onClick={() => act("/api/sim/close-group", "close")}
        >
          手动全平
        </button>
        <button
          className="btn ghost"
          type="button"
          disabled={!!busy}
          onClick={() => act("/api/plan/emergency-close", "emg")}
        >
          紧急全平
        </button>
        {busy ? <span className="meta">{busy}…</span> : null}
      </div>

      <div className="card plan-summary" style={{ marginBottom: 12 }}>
        <div className="kv">
          <span>策略</span>
          <span>
            {plan?.running ? (
              <span className="status-running">启动中</span>
            ) : (
              <span className="status-stopped">已停</span>
            )}
            <span className="mono">
              {" "}
              · {phaseLabel} · 已完成 {plan?.rounds_done ?? 0} 组
            </span>
          </span>
        </div>
        <div className="kv">
          <span>选约条件</span>
          <span className="mono">
            剩余≥{fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥{fmt(plan?.min_option_leverage, 0)}x
          </span>
        </div>
        <div className="kv">
          <span>休息</span>
          <span className="mono">
            {plan?.rest_left_sec ? `${plan.rest_left_sec}s / ${plan.rest_seconds}s` : "—"}
          </span>
        </div>
        <div className="kv">
          <span>权益 / 杠杆</span>
          <span className="mono">
            {fmt(plan?.ledger?.equity)} / 可用 {fmt(plan?.ledger?.available)} ·{" "}
            {fmt(plan?.leverage, 0)}x
          </span>
        </div>
        <div className="kv">
          <span>当前组</span>
          <span className="mono">{pos?.group_id || "—"}</span>
        </div>
        <div className="kv">
          <span>信号方向</span>
          <span className="mono">{biasTag}</span>
        </div>
        <div className="kv">
          <span>出场规则</span>
          <span className="mono">{exitRuleLabel}</span>
        </div>
        <div className="kv">
          <span>净盈利 / 目标</span>
          <span className="mono">
            <span className={pnlClass(open ? netPnl : null)}>
              {open ? fmt(netPnl) : "—"}
            </span>
            {" / "}
            {open || exitMode === "fixed_usdt" ? fmt(exitTarget) : "—"}
          </span>
        </div>
        <div className="kv">
          <span>永续浮盈 / 期权浮盈</span>
          <span className="mono">
            <span className={pnlClass(pos?.perp_upl)}>{fmt(pos?.perp_upl)}</span>
            {" / "}
            <span className={pnlClass(pos?.option_upl)}>{fmt(pos?.option_upl)}</span>
          </span>
        </div>
        {plan?.last_error ? (
          <div className="kv">
            <span>最近错误</span>
            <span className="err" style={{ margin: 0 }}>
              {plan.last_error}
            </span>
          </div>
        ) : null}

        <div className="pos-embed-grid">
          {open ? (
            <>
              <div className="pos-card">
                <div className="pos-card-head">
                  <div className="pos-card-symbol">
                    <strong>{pos?.perp_inst_id || "ETH-USDT-SWAP"}</strong>
                    <span
                      className={
                        pos?.perp_side === "long"
                          ? "pos-side-badge pos-side-long"
                          : "pos-side-badge pos-side-short"
                      }
                    >
                      {pos?.perp_side === "long" ? "做多" : "做空"}
                    </span>
                  </div>
                </div>
                <div className="pos-meta">
                  <span className="pos-meta-item">永续持仓</span>
                  <span className="pos-meta-item">组 {pos?.group_id}</span>
                  <span className="pos-meta-item mono">数量 {fmt(pos?.perp_qty_eth, 2)} ETH</span>
                  <span className="pos-meta-item mono">
                    {fmt(pos?.leverage ?? plan?.leverage, 0)}x
                  </span>
                </div>
                <div className="pos-grid">
                  <div className="pos-cell">
                    <span className="pos-label">开仓价</span>
                    <span className="pos-value mono">{fmt(pos?.perp_entry_px)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">可平价</span>
                    <span className="pos-value mono">{fmt(pos?.perp_mark_px)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">浮盈亏</span>
                    <span className={`pos-value mono ${pnlClass(pos?.perp_upl)}`}>
                      {fmt(pos?.perp_upl)}
                    </span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">保证金</span>
                    <span className="pos-value mono">{fmt(pos?.perp_margin)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">名义价值</span>
                    <span className="pos-value mono">{fmt(pos?.perp_notional)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">波动比例</span>
                    <span className="pos-value mono">{fmt(movePct, 2)}%</span>
                  </div>
                </div>
              </div>

              <div className="pos-card">
                <div className="pos-card-head">
                  <div className="pos-card-symbol">
                    <strong>{pos?.option_inst_id || "期权"}</strong>
                    <span
                      className={
                        pos?.option_side === "call"
                          ? "pos-side-badge pos-side-long"
                          : "pos-side-badge pos-side-short"
                      }
                    >
                      {pos?.option_side === "call" ? "看涨 Call" : "看跌 Put"}
                    </span>
                  </div>
                </div>
                <div className="pos-meta">
                  <span className="pos-meta-item">期权持仓</span>
                  <span className="pos-meta-item">到期 {pos?.expiry_ymd || "—"}</span>
                  <span className="pos-meta-item">行权 {fmt(pos?.strike, 0)}</span>
                  <span className="pos-meta-item mono">
                    {fmt(pos?.option_qty_eth, 2)} ETH · {fmt(pos?.option_qty_contracts, 0)} 张
                  </span>
                </div>
                <div className="pos-grid">
                  <div className="pos-cell pos-cell-wide">
                    <span className="pos-label">到期倒计时</span>
                    <span
                      className={`pos-value mono ${countdownUrgent ? "pos-countdown-urgent" : ""}`}
                    >
                      {countdown}
                    </span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">开仓均价</span>
                    <span className="pos-value mono">{fmt(pos?.option_entry_px)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">标记/买一</span>
                    <span className="pos-value mono">{fmt(pos?.option_mark_px)}</span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">浮盈亏</span>
                    <span className={`pos-value mono ${pnlClass(pos?.option_upl)}`}>
                      {fmt(pos?.option_upl)}
                    </span>
                  </div>
                  <div className="pos-cell">
                    <span className="pos-label">初始权利金</span>
                    <span className="pos-value mono">{fmt(pos?.initial_premium)}</span>
                  </div>
                </div>
              </div>
            </>
          ) : (
            <>
              <div className="pos-empty">永续持仓 · 暂无</div>
              <div className="pos-empty">期权持仓 · 暂无</div>
            </>
          )}
        </div>
      </div>

      <div className="grid-2">
        <div className="card">
          <h3 style={{ marginTop: 0 }}>永续</h3>
          <div className="kv">
            <span>买一</span>
            <span className="mono">{fmt(snap?.perp?.bid)}</span>
          </div>
          <div className="kv">
            <span>卖一</span>
            <span className="mono">{fmt(snap?.perp?.ask)}</span>
          </div>
          <div className="kv">
            <span>指数</span>
            <span className="mono">{fmt(snap?.index_px)}</span>
          </div>
        </div>
        <div className="card">
          <h3 style={{ marginTop: 0 }}>
            期权 ATM {snap?.pair ? `@ ${snap.pair.strike}` : ""}
          </h3>
          <div className="kv">
            <span>Call 卖一/买一</span>
            <span className="mono">
              {fmt(snap?.call?.ask)} / {fmt(snap?.call?.bid)}
            </span>
          </div>
          <div className="kv">
            <span>Put 卖一/买一</span>
            <span className="mono">
              {fmt(snap?.put?.ask)} / {fmt(snap?.put?.bid)}
            </span>
          </div>
          <div className="kv">
            <span>到期</span>
            <span className="mono">{snap?.pair?.expiry_ymd || "—"}</span>
          </div>
        </div>
      </div>
    </div>
  );
}
