import { useEffect, useId, useMemo, 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_perp?: number;
  fees_option?: number;
  fees_total: number;
  slip_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;
  option_inst_id?: string | null;
  perp_inst_id?: string | null;
  expiry_ymd?: 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;
  entry_index_px?: number | null;
  close_index_px?: number | null;
  move_points?: number | null;
  option_leverage?: number | null;
  exec_mode?: string | null;
  expiry_settle?: ExpirySettle | null;
  pnl_summary?: PnlSummary;
};

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

const PAGE_SIZE = 10;

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

function groupPnl(g: Group) {
  return g.net_pnl ?? g.pnl_summary?.net_pnl ?? g.realized_pnl;
}

/** 开仓→平仓指数点数（带符号） */
function fmtMovePoints(n: number | null | undefined) {
  if (n == null || Number.isNaN(n)) return "—";
  const s = n > 0 ? `+${n.toFixed(1)}` : n.toFixed(1);
  return s;
}

/** 期权到期日 YYMMDD / YYYYMMDD → 可读日期 */
function fmtExpiryYmd(ymd: string | null | undefined) {
  if (!ymd) return "—";
  const s = String(ymd).trim();
  if (/^\d{6}$/.test(s)) {
    return `20${s.slice(0, 2)}-${s.slice(2, 4)}-${s.slice(4, 6)}`;
  }
  if (/^\d{8}$/.test(s)) {
    return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}`;
  }
  return s;
}

/** 从成交明细回退取期权合约 ID */
function optionInstFromFills(fills: Fill[]) {
  for (const f of fills) {
    if (f.leg === "option" && f.inst_id) return String(f.inst_id);
  }
  return null;
}

/** 从合约 ID 解析 YYMMDD（ETH-260801-1875-C / ETH-260801-1875-C） */
function expiryYmdFromInstId(instId: string | null | undefined) {
  if (!instId) return null;
  const m = String(instId).match(/(?:^|-)(\d{6})(?:-|$)/);
  return m ? m[1] : null;
}

export default function TradesPage() {
  const titleId = useId();
  const [groups, setGroups] = useState<Group[]>([]);
  const [page, setPage] = useState(1);
  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);
        setPage(1);
      })
      .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]);

  const totalPages = Math.max(1, Math.ceil(groups.length / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);
  const pageGroups = useMemo(() => {
    const start = (safePage - 1) * PAGE_SIZE;
    return groups.slice(start, start + PAGE_SIZE);
  }, [groups, safePage]);

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

  function renderMobileRow(g: Group) {
    const listPnl = groupPnl(g);
    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)}
            {g.move_points != null ? ` · 波动 ${fmtMovePoints(g.move_points)}` : ""}
            {g.option_leverage != null
              ? ` · 期权杠杆 ${fmt(g.option_leverage, 0)}x`
              : ""}
          </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>
    );
  }

  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 trade-list-mobile" style={{ marginBottom: 12 }}>
        {groups.length === 0 ? (
          <p style={{ color: "var(--muted)" }}>暂无成交组</p>
        ) : (
          groups.map((g) => renderMobileRow(g))
        )}
      </div>

      {/* 电脑端：表格 + 翻页 */}
      <div className="card trade-table-card trade-list-desktop">
        {groups.length === 0 ? (
          <p style={{ color: "var(--muted)" }}>暂无成交组</p>
        ) : (
          <>
            <div className="trade-table-wrap">
              <table className="trade-table">
                <thead>
                  <tr>
                    <th>序号</th>
                    <th>组名</th>
                    <th>方向</th>
                    <th>持仓状态</th>
                    <th>开仓时间</th>
                    <th>平仓时间</th>
                    <th>持仓时长</th>
                    <th>期权杠杆</th>
                    <th>波动点数</th>
                    <th>盈亏金额</th>
                    <th>平仓方式</th>
                  </tr>
                </thead>
                <tbody>
                  {pageGroups.map((g, i) => {
                    const listPnl = groupPnl(g);
                    const openMs = g.hold_open_at_ms ?? g.open_at_ms;
                    const closeMs = g.hold_close_at_ms ?? g.close_at_ms;
                    const seq = (safePage - 1) * PAGE_SIZE + i + 1;
                    return (
                      <tr
                        key={g.group_id}
                        className="trade-table-row"
                        onClick={() => openGroup(g.group_id)}
                      >
                        <td className="mono">{seq}</td>
                        <td className="mono trade-table-id">{g.group_id}</td>
                        <td className="mono">
                          {positionSidesZh(g.perp_side, g.option_side)}
                        </td>
                        <td className="mono">{statusZh(g.status)}</td>
                        <td className="mono">{fmtTime(openMs)}</td>
                        <td className="mono">{fmtTime(closeMs)}</td>
                        <td className="mono">{fmtHold(g.hold_ms)}</td>
                        <td className="mono">
                          {g.option_leverage != null
                            ? `${fmt(g.option_leverage, 0)}x`
                            : "—"}
                        </td>
                        <td className="mono">{fmtMovePoints(g.move_points)}</td>
                        <td className={`mono ${pnlClass(listPnl)}`}>
                          {fmt(listPnl)}
                        </td>
                        <td className="mono">
                          {g.close_reason
                            ? closeReasonZh(g.close_reason)
                            : "—"}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
            <div className="trade-pager">
              <button
                type="button"
                className="btn ghost"
                disabled={safePage <= 1}
                onClick={() => setPage((p) => Math.max(1, p - 1))}
              >
                上一页
              </button>
              <span className="mono trade-pager-info">
                {safePage} / {totalPages} · 共 {groups.length} 组
              </span>
              <button
                type="button"
                className="btn ghost"
                disabled={safePage >= totalPages}
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
              >
                下一页
              </button>
            </div>
          </>
        )}
      </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">
                        {selectedGroup.option_inst_id ||
                          optionInstFromFills(fills) ||
                          "—"}
                      </span>
                    </div>
                    <div className="kv">
                      <span>期权到期日</span>
                      <span className="mono">
                        {fmtExpiryYmd(
                          selectedGroup.expiry_ymd ||
                            expiryYmdFromInstId(
                              selectedGroup.option_inst_id ||
                                optionInstFromFills(fills),
                            ),
                        )}
                      </span>
                    </div>
                    {selectedGroup.strike != null &&
                    !selectedGroup.expiry_settle ? (
                      <div className="kv">
                        <span>行权价</span>
                        <span className="mono">
                          {fmt(selectedGroup.strike, 0)}
                        </span>
                      </div>
                    ) : null}
                    <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 className="kv">
                      <span>期权杠杆</span>
                      <span className="mono">
                        {selectedGroup.option_leverage != null
                          ? `${fmt(selectedGroup.option_leverage, 0)}x`
                          : "—"}
                      </span>
                    </div>
                    <div className="kv">
                      <span>初始权利金</span>
                      <span className="mono">
                        {selectedGroup.initial_premium != null
                          ? `${fmt(selectedGroup.initial_premium)} USDT`
                          : "—"}
                      </span>
                    </div>
                    <div className="kv">
                      <span>波动点数</span>
                      <span className="mono">
                        {fmtMovePoints(selectedGroup.move_points)}
                        {selectedGroup.entry_index_px != null &&
                        selectedGroup.close_index_px != null
                          ? `（${fmt(selectedGroup.entry_index_px, 1)}→${fmt(selectedGroup.close_index_px, 1)}）`
                          : ""}
                      </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) => {
                    const isOpt = f.leg === "option";
                    const pxLabel = isOpt ? "权利金" : "价";
                    const notional =
                      isOpt && f.action === "open"
                        ? Number(f.fill_px) * Number(f.qty_eth)
                        : null;
                    return (
                      <div key={f.id} className="trade-fill kv">
                        <span className="mono">
                          {fillDescZh(
                            f.leg,
                            f.action,
                            f.side,
                            selectedGroup.close_reason,
                          )}
                          {f.inst_id ? (
                            <span className="meta"> · {f.inst_id}</span>
                          ) : null}
                        </span>
                        <span className="mono">
                          {pxLabel} {f.fill_px.toFixed(4)} · 数量 {f.qty_eth}
                          {notional != null && Number.isFinite(notional)
                            ? ` · 合计 ${notional.toFixed(2)}`
                            : ""}{" "}
                          · 手续费 {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_perp ?? 0, 4)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>期权手续费</span>
                        <span className="mono">
                          {fmt(summary.fees_option ?? 0, 4)}
                        </span>
                      </div>
                      <div className="kv">
                        <span>手续费合计</span>
                        <span className="mono">{fmt(summary.fees_total, 4)}</span>
                      </div>
                      {String(selectedGroup.exec_mode || "").toUpperCase() !==
                      "LIVE" ? (
                        <div className="kv">
                          <span>滑点</span>
                          <span className="mono">
                            {fmt(summary.slip_total ?? 0, 4)}
                          </span>
                        </div>
                      ) : null}
                      <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>
  );
}
