"""Pipeline integration: compliance_gate function for hz.run() pipelines."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from horizon.compliance import ComplianceManager
    from horizon.context import Context


def compliance_gate(
    ctx: Any,
    compliance: Any = None,
) -> Any:
    """Pipeline function that enforces compliance checks before order submission.

    Insert this at the start of your pipeline to gate all orders through
    the compliance system. It runs regulatory limit checks, approval workflow,
    and surveillance recording on each cycle.

    Usage::

        hz.run(
            name="my_strategy",
            pipeline=[compliance_gate, my_signal, my_sizer],
            params={"compliance": compliance_manager},
        )

    The function is a no-op if no compliance manager is provided, so it's
    safe to include in pipelines used for both compliant and non-compliant runs.

    Args:
        ctx: Pipeline context (automatically injected).
        compliance: ComplianceManager instance. Can also be passed via
                    ``ctx.params["compliance"]``.

    Returns:
        The context, unmodified (pass-through for downstream pipeline stages).
        Returns ``None`` if the kill switch is active (halts pipeline).
    """
    mgr = compliance or (ctx.params.get("compliance") if hasattr(ctx, "params") else None)
    if mgr is None:
        return ctx

    # Kill switch check -- halt pipeline entirely
    if mgr.kill_switch.is_active:
        return None

    # Run per-cycle surveillance analysis
    try:
        engine = ctx.params.get("_engine") if hasattr(ctx, "params") else None
        mgr.surveillance.analyze_cycle(engine)
    except Exception:
        pass  # Surveillance failure must never block trading

    # Expire stale approval requests
    try:
        mgr.approval.expire_stale()
    except Exception:
        pass

    # Drain approved orders and submit them
    try:
        approved = mgr.approval.drain_approved()
        if approved and hasattr(ctx, "params"):
            engine = ctx.params.get("_engine")
            if engine is not None:
                for order_data in approved:
                    try:
                        market_id = order_data.get("market_id", "")
                        size = float(order_data.get("size", 1))

                        # Approvals with side+price => single-sided OrderRequest
                        side_str = order_data.get("side")
                        price = order_data.get("price")
                        if side_str is not None and price is not None:
                            from horizon._horizon import (
                                OrderRequest, OrderSide, Side,
                            )
                            price = float(price)
                            if price > 0 and size > 0 and market_id:
                                order_side = (
                                    OrderSide.Buy
                                    if str(side_str).lower() in ("buy", "yes")
                                    else OrderSide.Sell
                                )
                                side = Side.Yes  # default; overridden if specified
                                req = OrderRequest(
                                    market_id=market_id,
                                    side=side,
                                    order_side=order_side,
                                    size=size,
                                    price=price,
                                )
                                engine.submit_order(req)
                        else:
                            # Approvals with bid+ask => Quote path
                            from horizon._horizon import Quote
                            bid = float(order_data.get("bid", 0))
                            ask = float(order_data.get("ask", 0))
                            if bid > 0 and ask > 0 and market_id:
                                engine.submit_quotes(
                                    market_id,
                                    [Quote(bid=bid, ask=ask, size=size)],
                                )
                    except Exception:
                        pass
    except Exception:
        pass

    return ctx
