"""Characteristic Function Pricing pipeline functions.

Pipeline functions:
    pricing_signal - Price binary options under advanced models
"""

from __future__ import annotations

from typing import Any, Callable

from horizon.context import Context


def pricing_signal(
    feed: str,
    model: str = "heston",
) -> Callable[[Context], dict[str, Any]]:
    """Create a characteristic function pricing pipeline function.

    Prices binary options under Heston, Merton, or Variance Gamma
    models and compares to market price for edge detection.

    Args:
        feed: Feed name for price/strike data.
        model: Pricing model ("heston", "merton", "vg").

    Returns:
        Pipeline function: (Context) -> dict with keys:
            model_price, market_price, edge, delta, vega
    """
    from horizon._horizon import auth_require_pro
    auth_require_pro()

    def _pricing_signal(ctx: Context) -> dict[str, Any]:
        fd = ctx.feeds.get(feed)

        result = {
            "model_price": 0.0,
            "market_price": 0.0,
            "edge": 0.0,
            "delta": 0.0,
            "vega": 0.0,
        }

        if fd is None or fd.price <= 0:
            return result

        market_price = fd.price
        result["market_price"] = market_price

        # Use mid as underlying proxy
        s0 = (fd.bid + fd.ask) / 2.0 if fd.bid > 0 and fd.ask > 0 else 0.5
        strike = 0.5  # Default strike for binary markets
        t = max(ctx.params.get("time_to_expiry", 1.0), 0.01)

        try:
            if model == "heston":
                from horizon._horizon import binary_price_heston, HestonParams
                params = HestonParams()
                bp = binary_price_heston(strike, t, params, 0.0, s0)
            elif model == "merton":
                from horizon._horizon import binary_price_merton, MertonParams
                params = MertonParams()
                bp = binary_price_merton(strike, t, 0.2, params, 0.0, s0)
            elif model == "vg":
                from horizon._horizon import binary_price_vg, VGParams
                params = VGParams()
                bp = binary_price_vg(strike, t, params, 0.0, s0)
            else:
                return result

            result["model_price"] = bp.price
            result["delta"] = bp.delta
            result["vega"] = bp.vega
            result["edge"] = bp.price - market_price

        except (ValueError, RuntimeError):
            pass

        return result

    _pricing_signal.__name__ = "pricing_signal"
    return _pricing_signal
