"""SIM 资金钱包：资金账户 / 交易账户 × USDT|USDC（对齐 OKX，无期权分账户）。"""

from __future__ import annotations

import time
from typing import Any

from ..models.db import Database, get_db

# DB 列名（历史兼容：USDC 存在 options_*_usdc 列，语义为资金/交易账户 USDC）
WALLET_KEYS = (
    "funding_usdt",
    "trading_usdt",
    "options_funding_usdc",  # = funding_usdc
    "options_trading_usdc",  # = trading_usdc
    "options_funding_usdt",  # 废弃，恒为 0
    "options_trading_usdt",  # 废弃，恒为 0
)

_ACCT_MAP = {
    ("funding", "usdt"): "funding_usdt",
    ("trading", "usdt"): "trading_usdt",
    ("funding", "usdc"): "options_funding_usdc",
    ("trading", "usdc"): "options_trading_usdc",
}


def _now_ms() -> int:
    return int(time.time() * 1000)


class SimFundsWallets:
    def __init__(self, db: Database | None = None) -> None:
        self.db = db or get_db()

    def snapshot(self) -> dict[str, float]:
        row = self.db.fetchone("SELECT * FROM funds_wallets WHERE id=1")
        if row is None:
            return {k: 0.0 for k in WALLET_KEYS}
        return {k: float(row[k] or 0) for k in WALLET_KEYS}

    def view(self) -> dict[str, float]:
        """对外口径：funding/trading × usdt/usdc。"""
        s = self.snapshot()
        return {
            "funding_usdt": float(s["funding_usdt"]),
            "trading_usdt": float(s["trading_usdt"]),
            "funding_usdc": float(s["options_funding_usdc"]),
            "trading_usdc": float(s["options_trading_usdc"]),
        }

    def total_usdt_equiv(self, snap: dict[str, float] | None = None) -> float:
        """USDC 按 1:1 计入总资金。"""
        if snap is None:
            v = self.view()
        elif "funding_usdc" in snap:
            v = snap
        else:
            v = {
                "funding_usdt": float(snap.get("funding_usdt") or 0),
                "trading_usdt": float(snap.get("trading_usdt") or 0),
                "funding_usdc": float(snap.get("options_funding_usdc") or 0),
                "trading_usdc": float(snap.get("options_trading_usdc") or 0),
            }
        return round(
            float(v.get("funding_usdt") or 0)
            + float(v.get("trading_usdt") or 0)
            + float(v.get("funding_usdc") or 0)
            + float(v.get("trading_usdc") or 0),
            8,
        )

    def reset_from_equity(self, equity: float) -> dict[str, float]:
        """重置：全部放入资金账户 USDT。"""
        amt = max(0.0, float(equity))
        now = _now_ms()
        self.db.execute(
            """UPDATE funds_wallets SET
                funding_usdt=?, trading_usdt=0, options_funding_usdc=0, options_trading_usdc=0,
                options_funding_usdt=0, options_trading_usdt=0, updated_at_ms=?
             WHERE id=1""",
            (amt, now),
        )
        return self.snapshot()

    def _set(self, **kwargs: float) -> dict[str, float]:
        snap = self.snapshot()
        for k, v in kwargs.items():
            if k in WALLET_KEYS:
                snap[k] = float(v)
        now = _now_ms()
        self.db.execute(
            """UPDATE funds_wallets SET
                funding_usdt=?, trading_usdt=?, options_funding_usdc=?, options_trading_usdc=?,
                options_funding_usdt=0, options_trading_usdt=0, updated_at_ms=?
             WHERE id=1""",
            (
                snap["funding_usdt"],
                snap["trading_usdt"],
                snap["options_funding_usdc"],
                snap["options_trading_usdc"],
                now,
            ),
        )
        return snap

    def mirror_cash(self, amount: float, *, kind: str) -> None:
        """策略账本变动镜像到交易账户（永续 USDT / 期权 USDC）。"""
        amt = float(amount)
        if abs(amt) < 1e-12:
            return
        snap = self.snapshot()
        k = (kind or "").lower()
        if "option" in k:
            key = "options_trading_usdc"
        else:
            key = "trading_usdt"
        snap[key] = float(snap.get(key) or 0) + amt
        self._set(**snap)

    def sync_ledger_equity(self) -> float:
        total = self.total_usdt_equiv()
        now = _now_ms()
        self.db.execute(
            "UPDATE ledger_meta SET equity=?, available=?, updated_at_ms=? WHERE id=1",
            (total, total, now),
        )
        return total

    def convert(
        self,
        *,
        direction: str,
        amount: float,
        rate: float = 1.0,
        account: str = "funding",
    ) -> dict[str, Any]:
        """USDT↔USDC 兑换。默认资金账户；account=trading 时在交易账户内兑（对齐 OKX 现货）。"""
        amt = float(amount)
        if amt <= 0:
            return {"ok": False, "detail": "数量须大于 0"}
        r = float(rate) if rate and rate > 0 else 1.0
        d = (direction or "").strip().lower()
        acct = (account or "funding").strip().lower()
        if acct not in ("funding", "trading"):
            return {"ok": False, "detail": "account 须为 funding / trading"}
        snap = self.snapshot()
        if acct == "funding":
            usdt_key, usdc_key = "funding_usdt", "options_funding_usdc"
            label = "资金账户"
        else:
            usdt_key, usdc_key = "trading_usdt", "options_trading_usdc"
            label = "交易账户"
        if d == "usdt_to_usdc":
            src = float(snap[usdt_key])
            if amt > src + 1e-9:
                return {"ok": False, "detail": f"{label} USDT 不足（可用 {src:.4f}）"}
            usdc = amt / r
            snap[usdt_key] = src - amt
            snap[usdc_key] = float(snap[usdc_key]) + usdc
        elif d == "usdc_to_usdt":
            src = float(snap[usdc_key])
            if amt > src + 1e-9:
                return {"ok": False, "detail": f"{label} USDC 不足（可用 {src:.4f}）"}
            usdt = amt * r
            snap[usdc_key] = src - amt
            snap[usdt_key] = float(snap[usdt_key]) + usdt
        else:
            return {"ok": False, "detail": "direction 须为 usdt_to_usdc 或 usdc_to_usdt"}
        self._set(**snap)
        total = self.sync_ledger_equity()
        return {
            "ok": True,
            "detail": "converted",
            "direction": d,
            "amount": amt,
            "rate": r,
            "account": acct,
            "wallets": self.view(),
            "total_usdt_equiv": total,
        }

    def transfer(
        self,
        *,
        ccy: str,
        amount: float,
        from_account: str,
        to_account: str,
    ) -> dict[str, Any]:
        """仅资金账户 ↔ 交易账户。"""
        amt = float(amount)
        if amt <= 0:
            return {"ok": False, "detail": "划转金额须大于 0"}
        ccy_l = (ccy or "USDC").strip().lower()
        fa = (from_account or "").strip().lower()
        ta = (to_account or "").strip().lower()
        allowed = {"funding", "trading"}
        if fa not in allowed or ta not in allowed:
            return {"ok": False, "detail": "账户仅支持 funding / trading"}
        if fa == ta:
            return {"ok": False, "detail": "来源与目标账户不能相同"}
        src_key = _ACCT_MAP.get((fa, ccy_l))
        dst_key = _ACCT_MAP.get((ta, ccy_l))
        if not src_key or not dst_key:
            return {"ok": False, "detail": "币种须为 USDT 或 USDC"}
        snap = self.snapshot()
        src_bal = float(snap[src_key])
        if amt > src_bal + 1e-9:
            return {"ok": False, "detail": f"余额不足（可用 {src_bal:.4f}）"}
        snap[src_key] = src_bal - amt
        snap[dst_key] = float(snap[dst_key]) + amt
        self._set(**snap)
        total = self.sync_ledger_equity()
        return {
            "ok": True,
            "detail": "transferred",
            "ccy": ccy_l.upper(),
            "amount": amt,
            "from": fa,
            "to": ta,
            "wallets": self.view(),
            "total_usdt_equiv": total,
        }
