"""中控资金统计:期权 USDC/USDT 按 1:1 计入 USDT 合计."""
from __future__ import annotations

from typing import Any, Optional


def _safe_float(value: Any) -> Optional[float]:
    try:
        if value is None or value == "":
            return None
        v = float(value)
        return v if v >= 0 else None
    except (TypeError, ValueError):
        return None


def _account_total_usdt(funding: Any, trading: Any) -> Optional[float]:
    fu = _safe_float(funding)
    tu = _safe_float(trading)
    if fu is None or tu is None:
        return None
    return round(fu + tu, 4)


def stablecoin_usdt_equiv(value: Any) -> Optional[float]:
    """USDC / USDT 按 1:1 折算为 USDT 统计口径."""
    return _safe_float(value)


def _sum_optional(*values: Any) -> Optional[float]:
    parts = [_safe_float(v) for v in values]
    present = [p for p in parts if p is not None]
    if not present:
        return None
    return round(sum(present), 4)


def options_balances_usdt_equiv(options_snap: dict[str, Any] | None) -> dict[str, Any]:
    """从期权 snapshot 提取资金户/交易户 USDT 等价余额.

    - funding_usdt / trading_usdt: USDT+USDC(+USDG) 全账户(勿与永续 USDT 再加总)
    - funding_usdc_equiv / trading_usdc_equiv: 仅非 USDT 稳定币,可安全加到永续 USDT 上
    """
    snap = options_snap if isinstance(options_snap, dict) else {}
    if snap.get("enabled") is False:
        return {
            "ok": False,
            "funding_usdt": None,
            "trading_usdt": None,
            "funding_usdc_equiv": None,
            "trading_usdc_equiv": None,
        }
    if snap.get("ok") is False:
        return {
            "ok": False,
            "funding_usdt": None,
            "trading_usdt": None,
            "funding_usdc_equiv": None,
            "trading_usdc_equiv": None,
        }
    bal = snap.get("balances") if isinstance(snap.get("balances"), dict) else snap
    funding_usdc_equiv = _sum_optional(bal.get("funding_usdc"), bal.get("funding_usdg"))
    trading_usdc_equiv = _sum_optional(bal.get("trading_usdc"), bal.get("trading_usdg"))
    funding = _sum_optional(bal.get("funding_usdt"), funding_usdc_equiv)
    trading = _sum_optional(bal.get("trading_usdt"), trading_usdc_equiv)
    ok = funding is not None and trading is not None
    return {
        "ok": ok,
        "funding_usdt": funding,
        "trading_usdt": trading,
        "funding_usdc_equiv": funding_usdc_equiv,
        "trading_usdc_equiv": trading_usdc_equiv,
    }


def options_float_pnl_usdt(options_snap: dict[str, Any] | None) -> Optional[float]:
    """期权浮盈合计(USDT).币本位按指数换算,勿把 ETH/BTC 数量当 U."""
    snap = options_snap if isinstance(options_snap, dict) else {}
    if snap.get("enabled") is False or snap.get("ok") is False:
        return None

    def _safe(v: Any) -> float | None:
        if v is None or v == "":
            return None
        try:
            return float(v)
        except (TypeError, ValueError):
            return None

    def _index_px() -> float | None:
        px = _safe(snap.get("options_index_px") or snap.get("index_px"))
        if px is not None and px > 0:
            return px
        for p in snap.get("positions") or []:
            if not isinstance(p, dict):
                continue
            px = _safe(p.get("idx_px") or p.get("idxPx"))
            if px is not None and px > 0:
                return px
        return None

    def _row_is_coin(p: dict[str, Any]) -> bool:
        ccy = str(p.get("premium_ccy") or "").strip().upper()
        if ccy in ("ETH", "BTC"):
            return True
        if str(p.get("margin_mode") or "").strip().lower() == "coin":
            return True
        mid = str(p.get("inst_id") or "")
        return "-USD-" in mid.upper() and "_UM" not in mid.upper()

    mode = str(snap.get("options_margin_mode") or snap.get("margin_mode") or "").strip().lower()
    snap_coin = mode == "coin"
    idx = _index_px()

    try:
        from lib.options.options_positions_lib import display_pnl_from_option_row

        total_u = 0.0
        found = False
        missing_fx = False
        for p in snap.get("positions") or []:
            if not isinstance(p, dict):
                continue
            pnl = display_pnl_from_option_row(p)
            if pnl is None:
                continue
            found = True
            if snap_coin or _row_is_coin(p):
                px = _safe(p.get("idx_px") or p.get("idxPx"))
                if px is None or px <= 0:
                    px = idx
                if px is None or px <= 0:
                    missing_fx = True
                    continue
                total_u += float(pnl) * float(px)
            else:
                total_u += float(pnl)
        if found and not missing_fx:
            return round(total_u, 4)
        if found and missing_fx and abs(total_u) > 1e-12:
            # 部分腿已换算成功时仍返回可得合计
            return round(total_u, 4)
    except Exception:
        pass

    upl = snap.get("upl_total_usdc")
    if upl is not None:
        try:
            raw = float(upl)
        except (TypeError, ValueError):
            return None
        if snap_coin or any(
            isinstance(p, dict) and _row_is_coin(p) for p in (snap.get("positions") or [])
        ):
            if idx is None or idx <= 0:
                return None
            return round(raw * float(idx), 4)
        return round(raw, 4)
    return None


def options_open_position_count(options_snap: dict[str, Any] | None) -> int:
    snap = options_snap if isinstance(options_snap, dict) else {}
    if snap.get("enabled") is False or snap.get("ok") is False:
        return 0
    if snap.get("position_count") is not None:
        try:
            return max(0, int(snap.get("position_count")))
        except (TypeError, ValueError):
            pass
    pos = snap.get("positions")
    return len(pos) if isinstance(pos, list) else 0


def merge_perp_options_balances(
    perpetual_funding_usdt: Any,
    perpetual_trading_usdt: Any,
    options_snap: dict[str, Any] | None,
) -> dict[str, Any]:
    """永续 USDT + 期权非 USDT 稳定币合并为中控总资金(避免 OKX 同账户 USDT 双计).

    与实例顶栏 total_funds_usdt(..., options_usdc, None, None) 口径一致:
    期权 snapshot 里的 USDT 与永续资金/交易户是同一钱包,只把 USDC/USDG 加上.
    """
    opt = options_balances_usdt_equiv(options_snap)
    # 展示用期权户:优先非 USDT 稳定币;若仅有 USDT 则仍给出全量以便辨识
    opt_fund_disp = opt.get("funding_usdc_equiv")
    opt_trade_disp = opt.get("trading_usdc_equiv")
    if opt_fund_disp is None and opt_trade_disp is None and opt.get("ok"):
        opt_fund_disp = opt.get("funding_usdt")
        opt_trade_disp = opt.get("trading_usdt")

    if opt.get("ok"):
        if perpetual_funding_usdt is None and perpetual_trading_usdt is None:
            # 永续账户未取到时,期权 snapshot 已含同账户 USDT+USDC,直接用全量
            funding = opt.get("funding_usdt")
            trading = opt.get("trading_usdt")
        else:
            funding = _sum_optional(perpetual_funding_usdt, opt.get("funding_usdc_equiv"))
            trading = _sum_optional(perpetual_trading_usdt, opt.get("trading_usdc_equiv"))
    else:
        funding = _safe_float(perpetual_funding_usdt)
        trading = _safe_float(perpetual_trading_usdt)

    total = _account_total_usdt(funding, trading)
    # 任一侧齐全即可展示;永续缺一侧但有期权 USDC 时仍尽量给出合计
    if total is None:
        total = _sum_optional(funding, trading)
    perp_total = _account_total_usdt(perpetual_funding_usdt, perpetual_trading_usdt)
    opt_total = _account_total_usdt(opt.get("funding_usdt"), opt.get("trading_usdt"))
    data_ok = total is not None
    return {
        "perpetual_funding_usdt": _safe_float(perpetual_funding_usdt),
        "perpetual_trading_usdt": _safe_float(perpetual_trading_usdt),
        "options_funding_usdt": opt_fund_disp,
        "options_trading_usdt": opt_trade_disp,
        "options_funding_full_usdt": opt.get("funding_usdt"),
        "options_trading_full_usdt": opt.get("trading_usdt"),
        "options_ok": bool(opt.get("ok")),
        "funding_usdt": funding,
        "trading_usdt": trading,
        "total_usdt": total,
        "perpetual_total_usdt": perp_total,
        "options_total_usdt": opt_total,
        "data_ok": data_ok,
    }


def repair_double_counted_fund_entry(ac: dict[str, Any]) -> dict[str, Any]:
    """识别并修复历史快照中「永续 USDT + 期权(USDT+USDC)」的双计.

    旧口径 options_* 存的是 USDT+USDC 全量,且 funding≈2×期权资金户 USDT 部分.
    新口径 options_* 多为纯 USDC,不会误伤.
    """
    if not isinstance(ac, dict):
        return {}
    out = dict(ac)
    ofu = _safe_float(ac.get("options_funding_usdt"))
    otu = _safe_float(ac.get("options_trading_usdt"))
    fu = _safe_float(ac.get("funding_usdt"))
    tu = _safe_float(ac.get("trading_usdt"))
    if ofu is None or otu is None or fu is None or tu is None:
        return out
    if ofu < 1.0:
        return out
    ratio = fu / ofu if ofu > 0 else 0.0
    # 经典双计:合并资金户 ≈ 2 × 期权资金户(同钱包 USDT 加了两遍)
    if 1.8 <= ratio <= 2.25:
        out["funding_usdt"] = ofu
        out["trading_usdt"] = otu
        out["total_usdt"] = round(ofu + otu, 4)
        out["repaired_double_count"] = True
    return out


def merge_board_row_balances(row: dict[str, Any]) -> dict[str, Any]:
    """监控板行 → 含期权的资金统计."""
    caps = row.get("capabilities") or []
    options_snap = row.get("options") if "options" in caps else None
    merged = merge_perp_options_balances(
        row.get("funding_usdt") if row.get("account_ok") else None,
        row.get("trading_usdt") if row.get("account_ok") else None,
        options_snap,
    )
    merged["options_float_pnl_u"] = options_float_pnl_usdt(options_snap)
    merged["options_open_position_count"] = options_open_position_count(options_snap)
    return merged
