"""运行时交易所配置：DB 覆盖 env，切换时套用合约默认。"""

from __future__ import annotations

from ..config import EXCHANGE_MARKET_DEFAULTS, Settings, get_settings


def normalize_exchange_name(name: str | None) -> str:
    n = (name or "okx").strip().lower()
    if n in ("bn", "binance"):
        return "binance"
    return "okx"


def load_runtime_settings() -> Settings:
    """启动 / 切换后使用的有效 Settings（含 DB 覆盖）。"""
    base = get_settings()
    try:
        from ..models.db import get_db

        db = get_db()
    except Exception:
        return base

    ex = normalize_exchange_name(db.get_setting("exchange", base.exchange))
    defs = EXCHANGE_MARKET_DEFAULTS[ex]
    ct_default = float(defs["option_ct_mult_default"])
    raw_ct = db.get_setting("option_ct_mult_default")
    if raw_ct not in (None, ""):
        try:
            ct_default = float(raw_ct)
        except ValueError:
            pass
    return base.model_copy(
        update={
            "exchange": ex,
            "perp_inst_id": str(
                db.get_setting("perp_inst_id") or defs["perp_inst_id"]
            ),
            "option_inst_family": str(
                db.get_setting("option_inst_family") or defs["option_inst_family"]
            ),
            "index_inst_id": str(
                db.get_setting("index_inst_id") or defs["index_inst_id"]
            ),
            "option_ct_mult_default": ct_default,
        }
    )


def persist_exchange_choice(name: str) -> Settings:
    """写入 exchange + 该所合约默认，返回 runtime settings。"""
    from ..models.db import get_db

    ex = normalize_exchange_name(name)
    defs = EXCHANGE_MARKET_DEFAULTS[ex]
    db = get_db()
    db.set_setting("exchange", ex)
    db.set_setting("perp_inst_id", str(defs["perp_inst_id"]))
    db.set_setting("option_inst_family", str(defs["option_inst_family"]))
    db.set_setting("index_inst_id", str(defs["index_inst_id"]))
    db.set_setting("option_ct_mult_default", str(defs["option_ct_mult_default"]))
    return load_runtime_settings()


async def reload_market_session(settings: Settings | None = None):
    """停旧会话、按 settings 重建交易所与策略会话并 start。"""
    from .factory import set_exchange
    from ..strategy.session import bootstrap_session, get_session, set_session

    s = settings or load_runtime_settings()
    old = None
    try:
        old = get_session()
    except Exception:
        old = None
    if old is not None:
        try:
            await old.stop()
        except Exception:
            pass
    set_session(None)
    set_exchange(None)
    sess = bootstrap_session(s)
    await sess.start()
    return sess
