"""Notification service for the autonomous trading engine.

Pure computation module for notification logic. Actual delivery (AWS SNS,
Gmail API) is deferred to integration code — this module handles formatting,
rate-limit decisions, and record creation.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime, timezone

from services.trading.models import PerformanceMetrics

# ---------------------------------------------------------------------------
# Supported event types
# ---------------------------------------------------------------------------

SUPPORTED_EVENT_TYPES: frozenset[str] = frozenset(
    {
        "circuit_breaker_triggered",
        "circuit_breaker_resumed",
        "risk_tier_changed",
        "emergency_liquidation",
        "large_trade_pnl",
        "daily_summary",
        "weekly_digest",
    }
)


# ---------------------------------------------------------------------------
# Data model
# ---------------------------------------------------------------------------


@dataclass
class NotificationRecord:
    """A single notification record for audit persistence."""

    channel: str
    event_type: str
    message: str
    delivery_status: str = "pending"
    retry_count: int = 0
    created_at: datetime = field(default_factory=lambda: datetime.now(tz=timezone.utc))


# ---------------------------------------------------------------------------
# Notification service (pure computation)
# ---------------------------------------------------------------------------


class NotificationService:
    """Pure-computation notification service.

    Handles formatting, rate-limit checking, and record creation.
    Actual delivery is the caller's responsibility.
    """

    def __init__(
        self,
        sms_enabled: bool = False,
        email_enabled: bool = False,
        rate_limit_sms_per_hour: int = 10,
        rate_limit_email_per_hour: int = 20,
    ) -> None:
        self.sms_enabled = sms_enabled
        self.email_enabled = email_enabled
        self.rate_limit_sms_per_hour = rate_limit_sms_per_hour
        self.rate_limit_email_per_hour = rate_limit_email_per_hour

    # ------------------------------------------------------------------
    # Rate limiting
    # ------------------------------------------------------------------

    def should_send(self, channel: str, current_hour_count: int) -> bool:
        """Check whether a notification on *channel* is within the rate limit.

        Args:
            channel: ``"sms"`` or ``"email"``.
            current_hour_count: Number of notifications already sent on this
                channel during the current hour window.

        Returns:
            ``True`` if the notification may be sent, ``False`` if it should
            be rate-limited.
        """
        if channel == "sms":
            if not self.sms_enabled:
                return False
            return current_hour_count < self.rate_limit_sms_per_hour
        elif channel == "email":
            if not self.email_enabled:
                return False
            return current_hour_count < self.rate_limit_email_per_hour
        return False

    # ------------------------------------------------------------------
    # Formatting helpers
    # ------------------------------------------------------------------

    def format_daily_summary(self, metrics: PerformanceMetrics) -> str:
        """Format a daily performance summary message.

        Args:
            metrics: Current performance metrics snapshot.

        Returns:
            Human-readable summary string.
        """
        total_trades = metrics.win_count + metrics.loss_count
        return (
            f"Daily Summary — "
            f"P&L: ${metrics.daily_pnl:+.2f} | "
            f"Portfolio: ${metrics.total_portfolio_value:,.2f} | "
            f"Active: ${metrics.active_pool:,.2f} | "
            f"Reserve: ${metrics.reserve_pool:,.2f} | "
            f"Trades: {total_trades} | "
            f"Win Rate: {metrics.win_rate:.0%} | "
            f"Heat: {metrics.portfolio_heat:.2%}"
        )

    def format_alert(self, event_type: str, details: str) -> str:
        """Format an alert message for a specific event type.

        Args:
            event_type: One of the supported event types.
            details: Free-form detail string.

        Returns:
            Formatted alert string.
        """
        label = event_type.replace("_", " ").title()
        return f"[Stonks Alert] {label}: {details}"

    # ------------------------------------------------------------------
    # Record creation
    # ------------------------------------------------------------------

    def create_notification(
        self,
        channel: str,
        event_type: str,
        message: str,
    ) -> NotificationRecord:
        """Create a ``NotificationRecord`` ready for persistence.

        Args:
            channel: ``"sms"`` or ``"email"``.
            event_type: One of the supported event types.
            message: The formatted message body.

        Returns:
            A new ``NotificationRecord`` with ``delivery_status="pending"``.
        """
        return NotificationRecord(
            channel=channel,
            event_type=event_type,
            message=message,
            delivery_status="pending",
            retry_count=0,
        )
