import { useEffect, useId, useState } from "react";
import { apiFetch } from "../api/client";
import {
  closeReasonZh,
  fillDescZh,
  positionSidesZh,
  statusZh,
} from "../labels";

type PnlSummary = {
  option_pnl: number | null;
  perp_pnl: number | null;
  fees_total: number;
  gross_pnl: number | null;
  net_pnl: number | null;
};

type ExpirySettle = {
  settle_index_px: number | null;
  strike: number | null;
  intrinsic: number | null;
  formula: string;
  perp_note: string;
};

type Group = {
  group_id: string;
  status: string;
  bias: string | null;
  option_side: string | null;
  perp_side: string | null;
  initial_premium: number;
  realized_pnl: number;
  net_pnl?: number | null;
  close_reason: string | null;
  open_at_ms: number | null;
  close_at_ms: number | null;
  hold_open_at_ms?: number | null;
  hold_close_at_ms?: number | null;
  hold_ms?: number | null;
  hold_basis?: string | null;
  strike?: number | null;
  settle_index_px?: number | null;
  expiry_settle?: ExpirySettle | null;
  pnl_summary?: PnlSummary;
};

type Fill = {
  id: number;
  leg: string;
  action: string;
  side: string;
  fill_px: number;
  fee: number;
  qty_eth: number;
};

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

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

/** 上海时区开/平仓时间 */
function fmtTime(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,
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
  });
}

/** 持仓周期：x时y分z秒 */
function fmtHold(ms: number | null | undefined) {
  if (ms == null || !Number.isFinite(ms) || ms < 0) return "—";
  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}秒`;
}

export default function TradesPage() {
  const titleId = useId();
  const [groups, setGroups] = useState<Group[]>([]);
  const [selected, setSelected] = useState<string | null>(null);
  const [selectedGroup, setSelectedGroup] = useState<Group | null>(null);
  const [fills, setFills] = useState<Fill[]>([]);
  const [summary, setSummary] = useState<PnlSummary | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailErr, setDetailErr] = useState("");
  const [err, setErr] = useState("");

  useEffect(() => {
    apiFetch<{ groups: Group[] }>("/api/trades/groups")
      .then((r) => setGroups(r.groups))
      .catch((e) => setErr(e instanceof Error ? e.message : String(e)));
  }, []);

  useEffect(() => {
    if (!selected) return;
    const onKey = (ev: KeyboardEvent) => {
      if (ev.key === "Escape") closeDetail();
    };
    window.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [selected]);

  function closeDetail() {
    setSelected(null);
    setSelectedGroup(null);
    setFills([]);
    setSummary(null);
    setDetailErr("");
    setDetailLoading(false);
  }

  async function openGroup(id: string) {
    setSelected(id);
    setSummary(null);
    setSelectedGroup(null);
    setFills([]);
    setDetailErr("");
    setDetailLoading(true);
    try {
      const r = await apiFetch<{
        group: Group;
        fills: Fill[];
        pnl_summary: PnlSummary;
      }>(`/api/trades/groups/${id}`);
      setFills(r.fills);
      setSummary(r.pnl_summary);
      setSelectedGroup(r.group);
    } catch (e) {
      setDetailErr(e instanceof Error ? e.message : String(e));
    } finally {
      setDetailLoading(false);
    }
  }

  return (
    <div className="trades-page">
      <h2 style={{ marginTop: 0 }}>交易记录</h2>
      <p className="trade-hold-note">
        持仓周期按目标平仓计时；净盈利达标且只平永续时，以永续平仓时间为准（不含期权残留至到期）。点击一条可查看明细。
      </p>
      {err ? <div className="err">{err}</div> : null}
      <div className="card trade-list" style={{ marginBottom: 12 }}>
        {groups.length === 0 ? (
          <p style={{ color: "var(--muted)" }}>暂无成交组</p>
        ) : (
          groups.map((g) => {
            const listPnl =
              g.net_pnl ?? g.pnl_summary?.net_pnl ?? g.realized_pnl;
            const openMs = g.hold_open_at_ms ?? g.open_at_ms;
            const closeMs = g.hold_close_at_ms ?? g.close_at_ms;
            return (
              <button
                key={g.group_id}
                type="button"
                className="trade-row"
                onClick={() => openGroup(g.group_id)}
              >
                <div className="trade-row-main mono">
                  <span className="trade-row-id">{g.group_id}</span>
                  <span className="trade-row-meta">
                    {statusZh(g.status)} ·{" "}
                    {positionSidesZh(g.perp_side, g.option_side)}
                  </span>
                  <span className="trade-row-times">
                    开 {fmtTime(openMs)} · 平 {fmtTime(closeMs)} · 周期{" "}
                    {fmtHold(g.hold_ms)}
                  </span>
                </div>
                <div className={`trade-row-pnl mono ${pnlClass(listPnl)}`}>
                  <span>净盈亏 {fmt(listPnl)}</span>
                  {g.close_reason ? (
                    <span className="trade-row-reason">
                      {closeReasonZh(g.close_reason)}
                    </span>
                  ) : null}
                </div>
              </button>
            );
          })
        )}
      </div>

      {selected ? (
        <div
          className="modal-backdrop"
          role="presentation"
          onClick={closeDetail}
        >
          <div
            className="modal-dialog trade-detail-modal"
            role="dialog"
            aria-modal="true"
            aria-labelledby={titleId}
            onClick={(ev) => ev.stopPropagation()}
          >
            <div className="modal-head">
              <h3 id={titleId} className="modal-title mono">
                {selected}
              </h3>
              <button
                type="button"
                className="btn ghost modal-close"
                onClick={closeDetail}
                aria-label="关闭"
              >
                关闭
              </button>
            </div>

            <div className="modal-body">
              {detailLoading ? (
                <p className="meta">加载明细…</p>
              ) : null}
              {detailErr ? <div className="err">{detailErr}</div> : null}

              {!detailLoading && !detailErr && selectedGroup ? (
                <>
                  <div className="trade-hold-summary">
                    <div className="kv">
                      <span>状态</span>
                      <span className="mono">
                        {statusZh(selectedGroup.status)}
                        {selectedGroup.close_reason
                          ? ` · ${closeReasonZh(selectedGroup.close_reason)}`
                          : ""}
                      </span>
                    </div>
                    <div className="kv">
                      <span>方向</span>
                      <span className="mono">
                        {positionSidesZh(
                          selectedGroup.perp_side,
                          selectedGroup.option_side,
                        )}
                      </span>
                    </div>
                    <div className="kv">
                      <span>开仓时间</span>
                      <span className="mono">
                        {fmtTime(
                          selectedGroup.hold_open_at_ms ??
                            selectedGroup.open_at_ms,
                        )}
                      </span>
                    </div>
                    <div className="kv">
                      <span>平仓时间</span>
                      <span className="mono">
                        {fmtTime(
                          selectedGroup.hold_close_at_ms ??
                            selectedGroup.close_at_ms,
                        )}
                        {selectedGroup.hold_basis === "perp" ? (
                          <span className="trade-hold-basis">（永续）</span>
                        ) : null}
                      </span>
                    </div>
                    <div className="kv">
                      <span>持仓周期</span>
                      <span className="mono">
                        {fmtHold(selectedGroup.hold_ms)}
                      </span>
                    </div>
                  </div>

                  <p className="trade-detail-hint">
                    {selectedGroup.close_reason === "expiry"
                      ? "到期结算：期权按「指数 vs 行权价」的内在价值入账（非盘口）；永续仍按市价平。净盈亏 = 期权盈亏 + 永续盈亏 − 全部手续费。"
                      : "成交价为成交均价（未预先扣费）；手续费单独列出。净盈亏 = 期权盈亏 + 永续盈亏 − 全部手续费。"}
                  </p>

                  {selectedGroup.expiry_settle ? (
                    <div className="trade-hold-summary" style={{ marginBottom: 10 }}>
                      <div className="kv">
                        <span>结算指数</span>
                        <span className="mono">
                          {fmt(selectedGroup.expiry_settle.settle_index_px)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>行权价</span>
                        <span className="mono">
                          {fmt(selectedGroup.expiry_settle.strike, 0)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>内在价值</span>
                        <span className="mono">
                          {fmt(selectedGroup.expiry_settle.intrinsic)}
                          {selectedGroup.expiry_settle.formula
                            ? ` · ${selectedGroup.expiry_settle.formula}`
                            : ""}
                        </span>
                      </div>
                    </div>
                  ) : null}

                  {fills.map((f) => (
                    <div key={f.id} className="trade-fill kv">
                      <span className="mono">
                        {fillDescZh(
                          f.leg,
                          f.action,
                          f.side,
                          selectedGroup.close_reason,
                        )}
                      </span>
                      <span className="mono">
                        价 {f.fill_px.toFixed(4)} · 数量 {f.qty_eth} · 手续费{" "}
                        {f.fee.toFixed(4)}
                      </span>
                    </div>
                  ))}

                  {summary ? (
                    <div className="trade-pnl-block">
                      <div className="kv">
                        <span>期权盈亏</span>
                        <span className={`mono ${pnlClass(summary.option_pnl)}`}>
                          {fmt(summary.option_pnl)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>永续盈亏</span>
                        <span className={`mono ${pnlClass(summary.perp_pnl)}`}>
                          {fmt(summary.perp_pnl)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>手续费合计</span>
                        <span className="mono">{fmt(summary.fees_total, 4)}</span>
                      </div>
                      <div className="kv">
                        <span>
                          <strong>净盈亏（扣费后）</strong>
                        </span>
                        <span className={`mono ${pnlClass(summary.net_pnl)}`}>
                          <strong>{fmt(summary.net_pnl)}</strong>
                        </span>
                      </div>
                    </div>
                  ) : null}
                </>
              ) : null}
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}
