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);
}

/** 卖一/买一 + 对应档量：8.80(12.5) / 7.20(8.0) */
function fmtTop(px: number | null | undefined, sz: number | null | undefined) {
  if (px == null || Number.isNaN(px)) return "—";
  if (sz == null || Number.isNaN(sz)) return fmt(px);
  const s = sz >= 100 ? sz.toFixed(0) : sz >= 10 ? sz.toFixed(1) : sz.toFixed(2);
  return `${fmt(px)}(${s})`;
}

/** 持仓买一：价格/流动性张数，如 17.00/4000 */
function fmtBidLiq(px: number | null | undefined, sz: number | null | undefined) {
  if (px == null || Number.isNaN(px)) return "—";
  if (sz == null || Number.isNaN(sz)) return fmt(px);
  const s = sz >= 100 ? sz.toFixed(0) : sz >= 10 ? sz.toFixed(1) : sz.toFixed(2);
  return `${fmt(px)}/${s}`;
}

/** 期权杠杆 = 标的 ÷ 权利金 */
function optionLevLabel(
  underlying: number | null | undefined,
  premium: number | null | undefined,
) {
  if (
    underlying == null ||
    premium == null ||
    !Number.isFinite(underlying) ||
    !Number.isFinite(premium) ||
    underlying <= 0 ||
    premium <= 0
  ) {
    return "—";
  }
  return `${(underlying / premium).toFixed(0)}x`;
}

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")}秒`;
}

/** 上海时区开仓时间 */
function fmtOpenTime(ms: number | null | undefined) {
  if (ms == null || !Number.isFinite(ms) || ms <= 0) return "—";
  return new Date(ms).toLocaleString("zh-CN", {
    timeZone: "Asia/Shanghai",
    hour12: false,
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
  });
}

/** 持仓时长（实时） */
function fmtHoldDuration(openAtMs: number | null | undefined, now: number) {
  if (openAtMs == null || !Number.isFinite(openAtMs) || openAtMs <= 0) return "—";
  const ms = Math.max(0, now - openAtMs);
  const totalSec = Math.floor(ms / 1000);
  const h = Math.floor(totalSec / 3600);
  const m = Math.floor((totalSec % 3600) / 60);
  const s = totalSec % 60;
  if (h > 0) return `${h}时${m}分${s}秒`;
  if (m > 0) return `${m}分${s}秒`;
  return `${s}秒`;
}

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

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 === "strike_below_spot" ||
    bias === "call_ask_gt_put" ||
    bias === "fixed_short_call" ? (
      <span className="tag up">买 Call + 永续空</span>
    ) : bias === "strike_above_spot" ||
      bias === "put_ask_gt_call" ||
      bias === "fixed_long_put" ? (
      <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 riskBased =
    plan?.risk_based === true || plan?.sizing_mode === "risk_based";
  const riskLocked =
    open &&
    (plan?.risk_sizing_locked === true ||
      plan?.risk_sizing_preview?.locked === true);
  const riskLiveOk =
    !riskBased || riskLocked || plan?.risk_sizing_preview?.ok === true;
  const displayPerpQty = riskLiveOk ? (plan?.perp_qty_eth ?? 1) : null;
  const displayOptQty = riskLiveOk ? (plan?.option_qty_eth ?? 2) : null;
  const exitTarget = riskLiveOk
    ? (plan?.exit_target_usdt ?? plan?.net_profit_target ?? 15)
    : null;
  const netPnl = pos?.net_pnl ?? 0;
  const movePct = pos?.move_pct ?? 0;
  const exitRuleLabel =
    exitMode === "premium_multiple"
      ? `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
      : riskBased
        ? exitTarget != null
          ? `${riskLocked ? "锁定 " : "固定 "}${fmt(exitTarget)} U（基数${fmt(plan?.risk_exit_unit ?? 15)}）`
          : `待估算（基数${fmt(plan?.risk_exit_unit ?? 15)}）`
        : `固定 ${fmt(plan?.net_profit_target ?? 15)} U`;
  const riskRatioLabel = `比例${Number(plan?.risk_perp_unit ?? 1)}:${Number(plan?.risk_option_unit ?? 2)}`;
  const sizingModeLabel = riskBased
    ? [
        "以损定仓",
        riskRatioLabel,
        plan?.risk_last_k != null ? `k=${fmt(plan.risk_last_k, 1)}` : null,
        riskLocked
          ? exitTarget != null
            ? `目标锁定${fmt(exitTarget, 2)}U`
            : "目标已锁定"
          : plan?.risk_sizing_preview?.budget != null
            ? `预算${fmt(plan.risk_sizing_preview.budget, 2)}U`
            : null,
        !riskLocked && plan?.risk_sizing_preview?.ok === false
          ? String(plan.risk_sizing_preview.detail || "预览失败")
          : null,
      ]
        .filter(Boolean)
        .join("  ")
    : "手动仓位";
  const phaseLabel = PHASE_ZH[plan?.phase || ""] || plan?.phase || "—";
  const atmRule = plan?.fixed_direction_enabled
    ? plan?.fixed_perp_side === "short"
      ? "固定：永续空+买Call(实/平)"
      : "固定：永续多+买Put(实/平)"
    : plan?.atm_open_offset_enabled
      ? `ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
      : "ATM偏差关";
  const exitDetail =
    exitMode === "premium_multiple"
      ? `净盈利≥初始权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
      : `净盈利≥${fmt(plan?.net_profit_target ?? 15)} U`;
  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;

  const venueShort =
    plan?.mode === "LIVE"
      ? `实盘·${(snap?.exchange || "okx").toUpperCase()}`
      : "模拟盘";
  const openAtMs = pos?.open_at_ms ?? null;
  const openTimeLabel = fmtOpenTime(openAtMs);
  const holdDurationLabel = open ? fmtHoldDuration(openAtMs, nowMs) : "—";

  return (
    <div className="plan-page">
      {/* 手机端一屏监控卡：状态 / 净利 / 倒计时 */}
      <section className="plan-mobile-hero" aria-label="监控摘要">
        <div className="plan-mobile-hero-top">
          <span
            className={
              plan?.running
                ? "plan-pill plan-pill-on"
                : plan?.phase === "paused"
                  ? "plan-pill plan-pill-pause"
                  : "plan-pill plan-pill-off"
            }
          >
            {plan?.running ? "启动中" : plan?.phase === "paused" ? "已暂停" : "已停"}
          </span>
          <span className="plan-pill plan-pill-muted mono">{venueShort}</span>
          <span className="plan-mobile-phase mono">{phaseLabel}</span>
        </div>
        <div className="plan-mobile-hero-pnl">
          <div className="plan-mobile-pnl-block">
            <span className="plan-mobile-label">净盈利</span>
            <span className={`plan-mobile-pnl-num mono ${pnlClass(open ? netPnl : null)}`}>
              {open ? fmt(netPnl) : "—"}
            </span>
            <span className="plan-mobile-sub mono">
              目标 {exitTarget != null ? `${fmt(exitTarget)} U` : "—"}
            </span>
          </div>
          <div className="plan-mobile-pnl-block">
            <span className="plan-mobile-label">到期</span>
            <span
              className={`plan-mobile-countdown mono ${countdownUrgent ? "pos-countdown-urgent" : ""}`}
            >
              {countdown}
            </span>
            <span className="plan-mobile-sub mono">
              {open ? pos?.group_id || "持仓中" : "空仓"}
            </span>
          </div>
        </div>
        {plan?.last_error ? (
          <div className="plan-mobile-err">{plan.last_error}</div>
        ) : null}
      </section>

      {err ? <div className="err">{err}</div> : null}

      <div className="plan-rules-fold">
        <details>
          <summary>规则说明</summary>
          <div className="plan-rules-body">
            <p>
              <span className="plan-rules-k">行情</span>
              {String(plan?.exchange || "okx").toUpperCase()} · ETH-USDT-SWAP
            </p>
            <p>
              <span className="plan-rules-k">模式</span>
              {sizingModeLabel}
            </p>
            <p>
              <span className="plan-rules-k">开仓</span>
              永续{" "}
              {displayPerpQty != null
                ? `${fmt(displayPerpQty, 2)} ETH`
                : "—"}{" "}
              / {fmt(plan?.leverage, 0)}x
              · 期权{" "}
              {displayOptQty != null
                ? `${fmt(displayOptQty, 2)} ETH`
                : "—"}{" "}
              名义 · 剩余≥
              {fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥
              {fmt(plan?.min_option_leverage, 0)}x · {atmRule}
              {plan?.skip_weekends ? " · 周末跳过开仓" : ""}
              {plan?.one_expiry_per_day !== false
                ? " · 同到期日一天只开一次"
                : ""}
            </p>
            <p>
              <span className="plan-rules-k">平仓</span>
              {exitDetail} → 双腿全平；期权远虚则只平永续、期权到期结算；未达标拖到期
            </p>
            <p>
              <span className="plan-rules-k">节奏</span>
              组间休息 {plan?.rest_seconds ?? "—"}s · 可开判定看交易账户
              {plan?.one_expiry_per_day !== false
                ? " · 同到期平仓后改开下一到期"
                : ""}
            </p>
          </div>
        </details>
      </div>

      <div className="plan-actions">
        <button
          className={plan?.running ? "btn btn-running" : "btn"}
          type="button"
          disabled={
            !!busy ||
            !!plan?.running ||
            (plan?.mode === "LIVE" && plan.live_ready === false)
          }
          title={
            plan?.mode === "LIVE" && plan.live_ready === false
              ? plan.live_ready_reason || "LIVE 未就绪"
              : undefined
          }
          onClick={() => act("/api/plan/start", "start")}
        >
          {plan?.running ? "启动中" : "启动策略"}
        </button>
        <button
          className="btn ghost"
          type="button"
          disabled={!!busy || !plan?.running}
          onClick={() => act("/api/plan/pause", "pause")}
        >
          暂停
        </button>
        {plan?.show_manual_trade_buttons ? (
          <>
            <button
              className="btn ghost"
              type="button"
              disabled={
                !!busy ||
                !!plan?.running ||
                (plan?.mode === "LIVE" && plan.live_ready === false)
              }
              title={
                plan?.running
                  ? "策略自动运行中，禁止手动开仓"
                  : plan?.mode === "LIVE" && plan.live_ready === false
                    ? plan.live_ready_reason || "LIVE 未就绪"
                    : undefined
              }
              onClick={() => act("/api/sim/open-group", "open")}
            >
              手动开一组
            </button>
            <button
              className="btn ghost"
              type="button"
              disabled={!!busy}
              onClick={() => act("/api/sim/close-group", "close")}
            >
              手动全平
            </button>
          </>
        ) : null}
        <button
          className="btn danger"
          type="button"
          disabled={!!busy}
          onClick={() => act("/api/plan/emergency-close", "emg")}
        >
          紧急全平
        </button>
        {busy ? <span className="meta">{busy}…</span> : null}
      </div>

      <div className="plan-shell">
        <div className="plan-board">
          <div className="card plan-strategy">
            <h3 className="plan-panel-title">策略</h3>
            <div className="plan-metrics">
              <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">
                  {riskBased ? (
                    <span className="status-running">{sizingModeLabel}</span>
                  ) : (
                    sizingModeLabel
                  )}
                </span>
              </div>
              <div className="kv">
                <span>选约条件</span>
                <span className="mono">
                  永续
                  {displayPerpQty != null
                    ? `${fmt(displayPerpQty, 2)}ETH`
                    : "—"}
                  /期权
                  {displayOptQty != null
                    ? `${fmt(displayOptQty, 2)}ETH`
                    : "—"}{" "}
                  · 剩余≥
                  {fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥
                  {fmt(plan?.min_option_leverage, 0)}x
                  {plan?.fixed_direction_enabled
                    ? plan?.fixed_perp_side === "short"
                      ? " · 固定空+Call(实/平)"
                      : " · 固定多+Put(实/平)"
                    : plan?.atm_open_offset_enabled
                      ? ` · ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
                      : " · ATM偏差关"}
                </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="open-cap-row">
                  <span
                    className={
                      plan?.open_capacity?.perp_can_open === true
                        ? "open-cap-ok"
                        : plan?.open_capacity?.perp_can_open === false
                          ? "open-cap-bad"
                          : "mono"
                    }
                    title={
                      plan?.open_capacity?.perp_need_usdt != null
                        ? `需≈${plan.open_capacity.perp_need_usdt}U / 有${plan.open_capacity.perp_have_usdt ?? "—"}U`
                        : undefined
                    }
                  >
                    {plan?.open_capacity?.perp_label ||
                      `永续${fmt(plan?.leverage, 0)}x —`}
                  </span>
                  <span className="open-cap-sep">·</span>
                  <span
                    className={
                      plan?.open_capacity?.option_can_open === true
                        ? "open-cap-ok"
                        : plan?.open_capacity?.option_can_open === false
                          ? "open-cap-bad"
                          : "mono"
                    }
                    title={
                      plan?.open_capacity?.option_need_usdc != null
                        ? `需≈${plan.open_capacity.option_need_usdc}U / 有${plan.open_capacity.option_have_usdc ?? "—"}U`
                        : undefined
                    }
                  >
                    {plan?.open_capacity?.option_label || "期权 —"}
                  </span>
                </span>
              </div>
              <div className="kv">
                <span>当前组</span>
                <span className="mono">{pos?.group_id || "—"}</span>
              </div>
              <div className="kv kv-residuals">
                <span>残留期权(待到期)</span>
                {plan?.residuals && plan.residuals.length > 0 ? (
                  <div className="residual-list mono">
                    {plan.residuals.map((r) => (
                      <div
                        key={`${r.group_id}:${r.option_inst_id || ""}`}
                        className="residual-item"
                      >
                        {r.group_id}:{r.option_inst_id || "?"}@{r.expiry_ymd || "?"}
                      </div>
                    ))}
                  </div>
                ) : (
                  <span className="mono">无</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"
                    ? exitTarget != null
                      ? 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?.mode === "LIVE" && open ? (
                <>
                  <div className="kv">
                    <span>已付手续费</span>
                    <span className="mono">{fmt(pos?.fees_paid)}</span>
                  </div>
                  <div className="kv">
                    <span>资金费</span>
                    <span className={`mono ${pnlClass(pos?.funding_usdt)}`}>
                      {fmt(pos?.funding_usdt)}
                    </span>
                  </div>
                </>
              ) : null}
              {plan?.last_error ? (
                <div className="kv">
                  <span>最近错误</span>
                  <span className="err" style={{ margin: 0 }}>
                    {plan.last_error}
                  </span>
                </div>
              ) : null}
            </div>
          </div>

          <div className="plan-positions">
            {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 className="pos-cell">
                      <span className="pos-label">开仓时间</span>
                      <span className="pos-value mono">{openTimeLabel}</span>
                    </div>
                    <div className="pos-cell">
                      <span className="pos-label">持仓时长</span>
                      <span className="pos-value mono">{holdDurationLabel}</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
                      className={`pos-countdown mono ${countdownUrgent ? "pos-countdown-urgent" : ""}`}
                      title="到期倒计时"
                    >
                      {countdown}
                    </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>
                    <span className="pos-meta-item mono" title="开仓指数÷开仓均价">
                      杠杆 {fmt(pos?.option_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?.option_entry_px)}</span>
                    </div>
                    <div className="pos-cell">
                      <span className="pos-label">买一</span>
                      <span className="pos-value mono">
                        {fmtBidLiq(pos?.option_mark_px, pos?.option_bid_sz)}
                      </span>
                    </div>
                    <div className="pos-cell">
                      <span className="pos-label">
                        {plan?.mode === "LIVE" ? "净盈亏" : "浮盈亏"}
                      </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 className="pos-cell">
                      <span className="pos-label">开仓时间</span>
                      <span className="pos-value mono">{openTimeLabel}</span>
                    </div>
                    <div className="pos-cell">
                      <span className="pos-label">持仓时长</span>
                      <span className="pos-value mono">{holdDurationLabel}</span>
                    </div>
                  </div>
                </div>
              </>
            ) : (
              <>
                <div className="pos-empty">永续持仓 · 暂无</div>
                <div className="pos-empty">期权持仓 · 暂无</div>
              </>
            )}
          </div>
        </div>

        <div className="plan-market">
          <div className="card">
            <h3 className="plan-panel-title">永续行情</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?.perp?.mark_px ??
                    (snap?.perp?.bid != null && snap?.perp?.ask != null
                      ? (snap.perp.bid + snap.perp.ask) / 2
                      : null),
                )}
              </span>
            </div>
            <div className="kv">
              <span>指数</span>
              <span className="mono">{fmt(snap?.index_px)}</span>
            </div>
          </div>
          <div className="card">
            <h3 className="plan-panel-title">
              {open ? "持仓期权" : "期权 ATM"}
              {snap?.pair ? ` @ ${snap.pair.strike}` : ""}
            </h3>
            {(() => {
              const under =
                snap?.index_px ??
                (snap?.perp?.bid != null && snap?.perp?.ask != null
                  ? (snap.perp.bid + snap.perp.ask) / 2
                  : snap?.perp?.mark_px ?? null);
              const callPx = open ? snap?.call?.bid : snap?.call?.ask;
              const callSz = open ? snap?.call?.bid_sz : snap?.call?.ask_sz;
              const putPx = open ? snap?.put?.bid : snap?.put?.ask;
              const putSz = open ? snap?.put?.bid_sz : snap?.put?.ask_sz;
              const sideLabel = open ? "买一/流动性" : "卖一/流动性";
              const callLev = optionLevLabel(under, callPx);
              const putLev = optionLevLabel(under, putPx);
              const heldSide = String(pos?.option_side || "").toLowerCase();
              const heldLev =
                open && pos?.option_leverage != null
                  ? `${fmt(pos.option_leverage, 0)}x`
                  : open && heldSide === "call"
                    ? callLev
                    : open && heldSide === "put"
                      ? putLev
                      : null;
              return (
                <>
                  <div className="kv">
                    <span>Call {sideLabel}</span>
                    <span className="mono">
                      {fmtTop(callPx, callSz)}
                      {!open ? ` · 杠杆 ${callLev}` : ""}
                    </span>
                  </div>
                  <div className="kv">
                    <span>Put {sideLabel}</span>
                    <span className="mono">
                      {fmtTop(putPx, putSz)}
                      {!open ? ` · 杠杆 ${putLev}` : ""}
                    </span>
                  </div>
                  <div className="kv">
                    <span>实际杠杆</span>
                    <span className="mono">
                      {open
                        ? heldLev ||
                          (heldSide
                            ? "—"
                            : `Call ${callLev} · Put ${putLev}`)
                        : `Call ${callLev} · Put ${putLev}`}
                    </span>
                  </div>
                </>
              );
            })()}
            <div className="kv">
              <span>距现价</span>
              <span className="mono">
                {(() => {
                  const strike = snap?.pair?.strike;
                  const px =
                    snap?.index_px ??
                    (snap?.perp?.bid != null && snap?.perp?.ask != null
                      ? (snap.perp.bid + snap.perp.ask) / 2
                      : null);
                  if (strike == null || px == null) return "—";
                  const abs = Math.abs(strike - px);
                  const sign = strike - px > 0 ? "+" : "";
                  const delta = `${sign}${(strike - px).toFixed(0)}`;
                  if (!plan?.atm_open_offset_enabled) {
                    return `${delta} · 偏差限制关`;
                  }
                  const lim = plan?.max_atm_open_offset ?? 3;
                  const ok = abs <= lim + 1e-9;
                  return `${delta} · 开仓${ok ? "可" : "不可"}(|Δ|≤${lim})`;
                })()}
              </span>
            </div>
            <div className="kv">
              <span>到期</span>
              <span className="mono">{snap?.pair?.expiry_ymd || "—"}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
