"""期权限价挂单:展示 enrichment + 超时自动撤单."""
from __future__ import annotations

import time
from typing import Any


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


def order_age_seconds(order: dict[str, Any], *, now_ms: float | None = None) -> float | None:
    """根据交易所 cTime(ms) 估算挂单时长(秒)."""
    ct = _safe_float(order.get("c_time") or order.get("cTime"))
    if ct is None or ct <= 0:
        return None
    # OKX 一般为毫秒时间戳
    if ct < 1e12:
        ct *= 1000.0
    now = float(now_ms if now_ms is not None else time.time() * 1000.0)
    age = (now - ct) / 1000.0
    return age if age >= 0 else 0.0


def is_close_pending_order(order: dict[str, Any]) -> bool:
    """平仓向限价挂单:卖出 / reduceOnly."""
    side = str(order.get("side") or "").lower()
    if side == "sell":
        return True
    return bool(order.get("reduce_only"))


def enrich_pending_orders(
    orders: list[dict[str, Any]] | None,
    *,
    ttl_seconds: float = 600.0,
    now_ms: float | None = None,
) -> list[dict[str, Any]]:
    """为 UI 附加挂单时长与自动撤倒计时."""
    ttl = max(0.0, float(ttl_seconds or 0))
    now = float(now_ms if now_ms is not None else time.time() * 1000.0)
    out: list[dict[str, Any]] = []
    for raw in orders or []:
        o = dict(raw)
        age = order_age_seconds(o, now_ms=now)
        is_close = is_close_pending_order(o)
        o["age_sec"] = round(age, 1) if age is not None else None
        o["is_close_order"] = is_close
        o["auto_cancel_enabled"] = bool(is_close and ttl > 0)
        if age is not None and is_close and ttl > 0:
            remain = max(0.0, ttl - age)
            o["ttl_seconds"] = ttl
            o["expire_in_sec"] = round(remain, 1)
            o["stale"] = remain <= 0
        else:
            o["ttl_seconds"] = ttl if is_close else None
            o["expire_in_sec"] = None
            o["stale"] = False
        out.append(o)
    return out


def cancel_stale_close_pending_orders(
    *,
    fetch_pending: Any,
    cancel_order: Any,
    ttl_seconds: float = 600.0,
    now_ms: float | None = None,
    ex: Any = None,
) -> dict[str, Any]:
    """
    平仓限价挂单超过 ttl 自动撤销.
    fetch_pending(ex) -> list; cancel_order(ex, inst_id=..., ord_id=...).
    """
    ttl = float(ttl_seconds or 0)
    if ttl <= 0:
        return {"ok": True, "cancelled": 0, "checked": 0, "skipped": "ttl_disabled"}
    try:
        orders = fetch_pending(ex) if ex is not None else fetch_pending()
    except TypeError:
        orders = fetch_pending(ex)
    except Exception as e:
        return {"ok": False, "msg": str(e), "cancelled": 0, "checked": 0}
    enriched = enrich_pending_orders(orders or [], ttl_seconds=ttl, now_ms=now_ms)
    cancelled: list[dict[str, Any]] = []
    errors: list[str] = []
    checked = 0
    for o in enriched:
        if not o.get("is_close_order"):
            continue
        checked += 1
        if not o.get("stale"):
            continue
        inst = str(o.get("inst_id") or "").strip()
        oid = str(o.get("ord_id") or "").strip()
        if not inst or not oid:
            continue
        try:
            if ex is not None:
                res = cancel_order(ex, inst_id=inst, ord_id=oid)
            else:
                res = cancel_order(inst_id=inst, ord_id=oid)
        except TypeError:
            res = cancel_order(ex, inst_id=inst, ord_id=oid)
        except Exception as e:
            errors.append(f"{oid}:{e}")
            continue
        if res.get("ok"):
            cancelled.append({"inst_id": inst, "ord_id": oid, "age_sec": o.get("age_sec")})
        else:
            errors.append(f"{oid}:{res.get('msg') or 'cancel_failed'}")
    return {
        "ok": True,
        "cancelled": len(cancelled),
        "checked": checked,
        "orders": cancelled,
        "errors": errors,
        "ttl_seconds": ttl,
    }
