"""
EmailBackend – sends notifications via Django's email framework.

No extra dependencies required beyond Django itself.

Users must have an ``email`` attribute on their User model.
The subject / body are derived from the notification payload.
"""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any

from django.core.mail import send_mail

from django_notify_hub.backends.base import AbstractNotificationBackend
from django_notify_hub.exceptions import BackendError
from django_notify_hub.types import NotificationChannel

if TYPE_CHECKING:
    from django_notify_hub.types import NotificationPayload

logger = logging.getLogger("django_notify_hub")


class EmailBackend(AbstractNotificationBackend):
    """
    Delivers notifications as Django emails.

    Configuration (all optional)::

        DJANGO_NOTIFY = {
            "EMAIL_FROM": "noreply@example.com",   # defaults to DEFAULT_FROM_EMAIL
            "EMAIL_LANG": "en",                     # language to render title/body
        }
    """

    channel = NotificationChannel.EMAIL

    def setup(self, **kwargs: Any) -> None:
        from django.conf import settings as django_settings
        from django_notify_hub.conf import app_settings

        self._from_email: str = getattr(
            app_settings, "EMAIL_FROM", None
        ) or getattr(django_settings, "DEFAULT_FROM_EMAIL", "noreply@localhost")
        self._lang: str = getattr(app_settings, "EMAIL_LANG", "en")

    def _deliver(self, payload: "NotificationPayload", recipient: Any) -> bool:
        email_address = getattr(recipient, "email", None)
        if not email_address:
            logger.warning(
                "EmailBackend: user %s has no email address, skipping.",
                getattr(recipient, "pk", recipient),
            )
            return False

        subject = payload.get_title(self._lang)
        message = payload.get_body(self._lang)

        try:
            send_mail(
                subject=subject,
                message=message,
                from_email=self._from_email,
                recipient_list=[email_address],
                fail_silently=False,
            )
            logger.info(
                "EmailBackend: sent to %s (%s)",
                getattr(recipient, "pk", recipient),
                email_address,
            )
            return True
        except Exception as exc:
            raise BackendError(
                "EmailBackend",
                f"send_mail failed for {email_address}",
                exc,
            ) from exc

