import logging
from typing import Optional

from requests import RequestException

from django.contrib.auth import get_user_model
from django.template import Context, Template

from mentor.contrib.sender.client import sender
from mentor.users.enums import DEFAULT_USER_SETTINGS, NotificationEvent

from .models import Notification

log = logging.getLogger(__name__)
User = get_user_model()


def render_string(template_string: str, context: dict) -> str:
    context = Context(context)
    data = Template(template_string).render(context)
    return str(data).strip()


def send_notification(
    event: NotificationEvent, user: User, context: dict = None, **kwargs
) -> Optional[bool]:
    notify_enabled = user.settings.get(
        event.setting_name, DEFAULT_USER_SETTINGS.get(event.setting_name, True)
    )
    if not notify_enabled:
        log.info(f"User {user} disable notifications for event: {event}")
        return

    notification = Notification.objects.filter(
        event=event.value, is_active=True
    ).first()
    if not notification:
        log.info(f"No notification for event '{event}' found")
        return

    arguments = {}

    if isinstance(notification.arguments, dict):
        for name, tmpl in notification.arguments.items():
            arguments[name] = render_string(tmpl, context)

    try:
        log.debug(
            f"Send notification: {notification.newsletter} -> {user.email}\n {arguments}"
        )
        sender.send_transactional_email(notification.newsletter, user.email, arguments)
    except RequestException:
        log.exception(f"Sender error for {event} {user}")
        return

    return True
