"""中控只读聚合:OKX 期权持仓 / 资金(轻量,不含历史统计)."""

from __future__ import annotations

import os
from typing import Any


def build_options_hub_snapshot(cfg: dict[str, Any]) -> dict[str, Any]:
    if not cfg.get("enabled"):
        return {"ok": True, "enabled": False}
    ex = cfg.get("exchange_options")
    ready_fn = cfg.get("options_api_ready")
    if not callable(ready_fn):
        return {"ok": False, "enabled": True, "msg": "期权模块未就绪"}
    ok, reason = ready_fn(ex)
    if not ok:
        return {"ok": False, "enabled": True, "msg": reason or "期权 API 未配置"}
    try:
        from lib.options.options_position_limit_lib import options_max_active_positions
        from lib.options.options_positions_lib import build_display_option_positions

        raw = cfg["fetch_option_positions"](ex)
        if raw is None:
            return {"ok": False, "enabled": True, "msg": "获取期权持仓失败"}
        positions = build_display_option_positions(cfg, ex, raw)
        target_monitors: list[dict[str, Any]] = []
        try:
            conn = cfg["get_db"]()
            try:
                from lib.hedge_plan.hedge_plan_db import active_options_targets_by_inst
                from lib.options.options_profit_exit_lib import profit_exit_by_inst
                from lib.options.options_target_lib import list_active_targets, list_closing_targets, targets_by_inst

                target_monitors = list_active_targets(conn) + list_closing_targets(conn)
                tgt_map = targets_by_inst(conn)
                hedge_target_map = active_options_targets_by_inst(conn)
                profit_exit_map = profit_exit_by_inst(conn)
                target_monitors.extend(hedge_target_map.values())
                for pe in profit_exit_map.values():
                    if pe.get("profit_exit_enabled"):
                        target_monitors.append(
                            {
                                "inst_id": pe.get("inst_id"),
                                "exit_mode": "profit_exit",
                                "profit_exit_mult": pe.get("profit_exit_mult"),
                                "profit_exit_enabled": True,
                            }
                        )
                for p in positions:
                    mon = tgt_map.get(str(p.get("inst_id") or ""))
                    if mon:
                        p["target_index"] = mon.get("target_index")
                        p["target_monitor_id"] = mon.get("id")
                        p["target_monitor"] = mon
                    pe = profit_exit_map.get(str(p.get("inst_id") or ""))
                    if pe:
                        p["profit_exit_enabled"] = pe.get("profit_exit_enabled")
                        p["profit_exit_mult"] = pe.get("profit_exit_mult")
                        p["profit_exit_state"] = pe.get("profit_exit_state")
                        p["profit_exit_required_recycle"] = pe.get("required_recycle")
                    hedge_target = hedge_target_map.get(str(p.get("inst_id") or ""))
                    if hedge_target:
                        p["hedge_plan_target"] = hedge_target
                        if not mon:
                            # 中控卡片共用 target_index 只读展示；实际平仓仍由对冲计划监控处理。
                            p["target_index"] = hedge_target.get("target_index")
                    try:
                        from lib.instance.instance_dashboard_lib import (
                            _format_options_target,
                            _resolve_options_source,
                        )

                        inst = str(p.get("inst_id") or "")
                        source_key, source_label, source_plan_id = _resolve_options_source(conn, inst)
                        p["source"] = source_key
                        p["source_label"] = source_label
                        p["source_plan_id"] = source_plan_id
                        p["target_monitor_text"] = _format_options_target(p)
                    except Exception:
                        p.setdefault("source_label", "—")
                        p.setdefault("source_plan_id", None)
                        p.setdefault("target_monitor_text", "—")
            finally:
                conn.close()
        except Exception:
            target_monitors = []
        from lib.options.options_positions_lib import display_pnl_from_option_row

        upl_total = 0.0
        has_upl = False
        for p in positions:
            # 与持仓卡展示一致:优先买一净盈亏,残档回退交易所 upl
            pnl = display_pnl_from_option_row(p)
            if pnl is None:
                continue
            has_upl = True
            upl_total += float(pnl)
        bal = cfg["fetch_options_balances"](ex)
        from lib.options.options_margin_mode_lib import (
            is_coin_margin_mode,
            normalize_options_margin_mode,
            premium_ccy_for_mode,
        )

        margin_mode = normalize_options_margin_mode()
        for p in positions:
            mid = str(p.get("inst_id") or "")
            from lib.options.options_margin_mode_lib import margin_mode_from_inst_id

            row_mode = margin_mode_from_inst_id(mid) if mid else margin_mode
            p["margin_mode"] = row_mode
            p["premium_ccy"] = p.get("premium_ccy") or premium_ccy_for_mode(
                row_mode, str(p.get("underlying") or mid.split("-")[0] if mid else "ETH")
            )
            p["margin_mode_label"] = "币本位" if row_mode == "coin" else "USDC"

        underly = (os.getenv("OKX_OPTIONS_DEFAULT_UNDERLY") or "ETH").strip().upper() or "ETH"
        options_index_px = None
        try:
            from lib.exchange.okx_options_lib import fetch_index_price

            options_index_px = fetch_index_price(ex, underly)
        except Exception:
            options_index_px = None
        if options_index_px is None:
            for p in positions:
                try:
                    px = float(p.get("idx_px") or p.get("idxPx") or 0)
                except (TypeError, ValueError):
                    px = 0
                if px > 0:
                    options_index_px = px
                    break

        coin_budget = None
        bridge_status = None
        open_bridges = []
        if is_coin_margin_mode():
            try:
                from lib.options.options_coin_open_lib import coin_budget_preview

                coin_budget = coin_budget_preview(cfg, ex)
            except Exception:
                coin_budget = None
            try:
                conn_b = cfg["get_db"]()
                try:
                    from lib.options.options_spot_bridge_lib import list_open_bridges

                    open_bridges = list_open_bridges(conn_b)
                    if open_bridges:
                        bridge_status = str(open_bridges[0].get("status") or "")
                finally:
                    conn_b.close()
            except Exception:
                open_bridges = []

        return {
            "ok": True,
            "enabled": True,
            "positions": positions,
            "position_count": len(positions),
            "target_monitors": target_monitors,
            "upl_total_usdc": round(upl_total, 4) if has_upl else None,
            "balances": bal,
            "funding_usdc": bal.get("funding_usdc"),
            "funding_usdt": bal.get("funding_usdt"),
            "trading_usdc": bal.get("trading_usdc"),
            "trading_usdt": bal.get("trading_usdt"),
            # 监控区不用历史统计;保留空对象兼容旧调用方
            "stats": {},
            "trade_budget": cfg.get("trade_budget"),
            "account_label": cfg.get("account_label") or "OKX期权",
            "max_active_positions": options_max_active_positions(),
            "options_margin_mode": margin_mode,
            "options_margin_mode_label": "币本位" if margin_mode == "coin" else "USDC",
            "options_underly": underly,
            "options_index_px": options_index_px,
            "coin_budget": coin_budget,
            "bridge_status": bridge_status,
            "open_bridges": open_bridges,
        }
    except Exception as e:
        return {"ok": False, "enabled": True, "msg": str(e)}
