"""Unified notification service supporting multiple backends.

This module provides a unified interface for sending notifications through
different channels (email, Pushover, etc.) for alerts and daily reports.
"""

from typing import Any, Protocol

from .logging_config import get_logger

_LOGGER = get_logger(__name__)


class NotificationBackend(Protocol):
    """Protocol for notification backends."""

    async def send_alert(self, title: str, message: str, **kwargs) -> bool:
        """Send an alert notification.

        Args:
            title: Alert title/subject
            message: Alert message/body
            **kwargs: Backend-specific parameters

        Returns:
            True if sent successfully, False otherwise

        """
        ...

    async def send_daily_report(
        self,
        stats: dict[str, Any],
        errors: list[dict[str, Any]] | None = None,
        **kwargs,
    ) -> bool:
        """Send a daily report notification.

        Args:
            stats: Statistics dictionary
            errors: Optional list of errors
            **kwargs: Backend-specific parameters

        Returns:
            True if sent successfully, False otherwise

        """
        ...


class NotificationService:
    """Unified notification service that supports multiple backends.

    This service can send notifications through multiple channels simultaneously
    (email, Pushover, etc.) based on configuration.
    """

    def __init__(self):
        """Initialize the notification service."""
        self.backends: dict[str, NotificationBackend] = {}

    def register_backend(self, name: str, backend: NotificationBackend) -> None:
        """Register a notification backend.

        Args:
            name: Backend name (e.g., "email", "pushover")
            backend: Backend instance implementing NotificationBackend protocol

        """
        self.backends[name] = backend
        _LOGGER.info("Registered notification backend: %s", name)

    async def send_alert(
        self,
        title: str,
        message: str,
        backends: list[str] | None = None,
        **kwargs,
    ) -> dict[str, bool]:
        """Send an alert through specified backends.

        Args:
            title: Alert title/subject
            message: Alert message/body
            backends: List of backend names to use (None = all registered)
            **kwargs: Backend-specific parameters

        Returns:
            Dictionary mapping backend names to success status

        """
        if backends is None:
            backends = list(self.backends.keys())

        results = {}
        for backend_name in backends:
            backend = self.backends.get(backend_name)
            if backend is None:
                _LOGGER.warning("Backend not found: %s", backend_name)
                results[backend_name] = False
                continue

            try:
                success = await backend.send_alert(title, message, **kwargs)
                results[backend_name] = success
            except Exception:
                _LOGGER.exception(
                    "Error sending alert through backend %s", backend_name
                )
                results[backend_name] = False

        return results

    async def send_daily_report(
        self,
        stats: dict[str, Any],
        errors: list[dict[str, Any]] | None = None,
        backends: list[str] | None = None,
        **kwargs,
    ) -> dict[str, bool]:
        """Send a daily report through specified backends.

        Args:
            stats: Statistics dictionary
            errors: Optional list of errors
            backends: List of backend names to use (None = all registered)
            **kwargs: Backend-specific parameters

        Returns:
            Dictionary mapping backend names to success status

        """
        if backends is None:
            backends = list(self.backends.keys())

        results = {}
        for backend_name in backends:
            backend = self.backends.get(backend_name)
            if backend is None:
                _LOGGER.warning("Backend not found: %s", backend_name)
                results[backend_name] = False
                continue

            try:
                success = await backend.send_daily_report(stats, errors, **kwargs)
                results[backend_name] = success
            except Exception:
                _LOGGER.exception(
                    "Error sending daily report through backend %s", backend_name
                )
                results[backend_name] = False

        return results

    def get_backend(self, name: str) -> NotificationBackend | None:
        """Get a specific notification backend.

        Args:
            name: Backend name

        Returns:
            Backend instance or None if not found

        """
        return self.backends.get(name)

    def has_backend(self, name: str) -> bool:
        """Check if a backend is registered.

        Args:
            name: Backend name

        Returns:
            True if backend is registered

        """
        return name in self.backends
