"""ACD (Autoregressive Conditional Duration) pipeline functions.

Pipeline functions:
    duration_monitor - Real-time trade duration analysis per-market
"""

from __future__ import annotations

import time
from typing import Any, Callable

from horizon._horizon import AcdModel
from horizon.context import Context


def duration_monitor(
    feed: str,
    omega: float = 0.1,
    alpha: float = 0.1,
    beta: float = 0.8,
) -> Callable[[Context], dict[str, Any]]:
    """Create an ACD duration monitoring pipeline function.

    Tracks inter-trade durations and detects unusual activity patterns
    using autoregressive conditional duration models.

    Args:
        feed: Feed name to read trade data from.
        omega: ACD intercept parameter.
        alpha: ACD ARCH parameter (weight on last duration).
        beta: ACD GARCH parameter (weight on last expected duration).

    Returns:
        Pipeline function: (Context) -> dict with keys:
            expected_duration, surprise, hazard_rate, is_unusual
    """
    from horizon._horizon import auth_require_pro
    auth_require_pro()

    models: dict[str, AcdModel] = {}
    last_trade_times: dict[str, float] = {}

    def _duration_monitor(ctx: Context) -> dict[str, Any]:
        market_id = ctx.market.id if ctx.market else "__default__"
        fd = ctx.feeds.get(feed)

        if market_id not in models:
            models[market_id] = AcdModel(omega, alpha, beta)
            last_trade_times[market_id] = 0.0

        model = models[market_id]
        now = time.time()

        result = {
            "expected_duration": model.expected_duration(),
            "surprise": model.surprise(),
            "hazard_rate": 0.0,
            "is_unusual": False,
        }

        # Detect new trade via trade size
        if fd is not None and fd.last_trade_size > 0:
            last_time = last_trade_times[market_id]
            if last_time > 0:
                state = model.update(now)
                result["expected_duration"] = state.expected_duration
                result["surprise"] = state.surprise
                result["is_unusual"] = state.is_unusual
            else:
                model.update(now)

            last_trade_times[market_id] = now

        # Compute hazard rate based on elapsed time
        last_time = last_trade_times[market_id]
        if last_time > 0:
            elapsed = now - last_time
            result["hazard_rate"] = model.hazard_rate(elapsed)

        return result

    _duration_monitor.__name__ = "duration_monitor"
    return _duration_monitor
