"""
币安订单推送事件日志：将 ORDER_TRADE_UPDATE / ALGO_UPDATE 等写入日志文件，便于与 DB 对账。
每行一条 JSON，含 event_type、account_id、时间、关键字段，方便 grep / 脚本分析。
"""
import json
import logging
import os
import time
from pathlib import Path
from typing import Any, Dict, Optional

logger = logging.getLogger(__name__)

_LOG_DIR: Optional[Path] = None
_LOG_PATH: Optional[Path] = None


def _get_log_path() -> Optional[Path]:
    global _LOG_DIR, _LOG_PATH
    if _LOG_PATH is not None:
        return _LOG_PATH
    try:
        root = Path(__file__).resolve().parent.parent
        _LOG_DIR = root / "logs"
        _LOG_DIR.mkdir(parents=True, exist_ok=True)
        _LOG_PATH = _LOG_DIR / "binance_order_events.log"
        return _LOG_PATH
    except Exception as e:
        logger.debug(f"binance_order_event_logger 无法创建日志路径: {e}")
        return None


def _default_serializer(obj):
    if hasattr(obj, "isoformat"):
        return obj.isoformat()
    raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")


def log_order_event(account_id: int, event_type: str, event_time_ms: Optional[int], data: Dict[str, Any]) -> None:
    """
    将币安订单推送事件写入日志文件（每行一条 JSON）。
    
    Args:
        account_id: 账号 ID
        event_type: ORDER_TRADE_UPDATE / ALGO_UPDATE 等
        event_time_ms: 事件时间（毫秒）
        data: 原始 payload（如 o 或 a 部分），会提取关键字段
    """
    path = _get_log_path()
    if not path:
        return
    try:
        # 提取关键字段便于对账
        row = {
            "ts": int(time.time() * 1000),
            "event_type": event_type,
            "account_id": account_id,
            "E": event_time_ms,
        }
        if event_type == "ORDER_TRADE_UPDATE" and data:
            o = data
            row["symbol"] = (o.get("s") or "").strip()
            row["orderId"] = o.get("i")
            row["clientOrderId"] = (o.get("c") or "").strip() or None
            row["event"] = (o.get("x") or "").strip()  # NEW/TRADE/CANCELED
            row["status"] = (o.get("X") or "").strip()  # NEW/FILLED/CANCELED
            row["reduceOnly"] = o.get("R") is True
            if row["status"] == "FILLED":
                row["avgPrice"] = o.get("ap")
                row["executedQty"] = o.get("z")
                row["realizedPnl"] = o.get("rp")
        elif event_type == "ALGO_UPDATE" and data:
            o = data
            row["symbol"] = (o.get("s") or "").strip()
            # 币安文档：aid=Algo Id，兼容 i/algoId；caid=Client Algo Id，兼容 c/clientAlgoId
            row["algoId"] = o.get("aid") or o.get("i") or o.get("algoId")
            row["clientAlgoId"] = (o.get("caid") or o.get("c") or o.get("clientAlgoId") or "").strip() or None
            row["algoStatus"] = (o.get("X") or "").strip()  # TRIGGERED/FINISHED
            row["triggeredOrderId"] = o.get("ai") or o.get("triggeredOrderId") or None
        else:
            row["raw"] = data
        line = json.dumps(row, ensure_ascii=False, default=_default_serializer) + "\n"
        with open(path, "a", encoding="utf-8") as f:
            f.write(line)
    except Exception as e:
        logger.debug(f"binance_order_event_logger 写入失败: {e}")
