"""Risk hooks — event callbacks for risk engine lifecycle."""

from __future__ import annotations

import logging
import time
from typing import Any, Protocol, runtime_checkable

from pyfortis._types import BreachRecord, GateResult, MetricResult, Order

logger = logging.getLogger(__name__)


@runtime_checkable
class RiskHook(Protocol):
    """Protocol for risk engine lifecycle hooks."""

    def on_order_evaluated(self, order: Order, result: GateResult) -> None: ...
    def on_breach(self, breach: BreachRecord) -> None: ...
    def on_metric_computed(self, result: MetricResult) -> None: ...
    def on_halt(self, reason: str) -> None: ...


class LoggingHook:
    """Logs all risk engine events."""

    def __init__(self, logger_name: str = "pyfortis.hooks") -> None:
        self._log = logging.getLogger(logger_name)

    def on_order_evaluated(self, order: Order, result: GateResult) -> None:
        self._log.info(
            "Order %s: %s (%s)",
            order.order_id,
            result.verdict.value,
            result.message,
        )

    def on_breach(self, breach: BreachRecord) -> None:
        self._log.warning(
            "Breach [%s] %s: %s",
            breach.severity.value,
            breach.limit_name,
            breach.message,
        )

    def on_metric_computed(self, result: MetricResult) -> None:
        self._log.info(
            "Metric %s = %.4f%s",
            result.metric_name,
            result.value,
            " [BREACH]" if result.breach else "",
        )

    def on_halt(self, reason: str) -> None:
        self._log.critical("TRADING HALTED: %s", reason)


class MetricsCollector:
    """Collects risk engine metrics for monitoring/export."""

    def __init__(self) -> None:
        self.orders_evaluated: int = 0
        self.orders_approved: int = 0
        self.orders_rejected: int = 0
        self.breaches: int = 0
        self.halts: int = 0
        self.metrics_computed: int = 0
        self._start_time: float = time.monotonic()

    def on_order_evaluated(self, order: Order, result: GateResult) -> None:
        self.orders_evaluated += 1
        if result.is_approved:
            self.orders_approved += 1
        elif result.is_rejected:
            self.orders_rejected += 1

    def on_breach(self, breach: BreachRecord) -> None:
        self.breaches += 1

    def on_metric_computed(self, result: MetricResult) -> None:
        self.metrics_computed += 1

    def on_halt(self, reason: str) -> None:
        self.halts += 1

    def to_dict(self) -> dict[str, Any]:
        return {
            "orders_evaluated": self.orders_evaluated,
            "orders_approved": self.orders_approved,
            "orders_rejected": self.orders_rejected,
            "breaches": self.breaches,
            "halts": self.halts,
            "metrics_computed": self.metrics_computed,
            "uptime_seconds": time.monotonic() - self._start_time,
        }
