import json
from typing import List

from django.test import TestCase

from vbv_lernwelt.core.models import User
from vbv_lernwelt.core.tests.factories import UserFactory
from vbv_lernwelt.notify.models import Notification, NotificationType
from vbv_lernwelt.notify.service import NotificationService


class TestNotificationService(TestCase):
    def setUp(self) -> None:
        self.notification_service = NotificationService
        self.notification_service._send_email = lambda a, b, c: True

        self.admin = UserFactory(username="admin", email="admin")
        self.sender_username = "Bob"
        UserFactory(username=self.sender_username, email="bob@gmail.com")
        self.sender = User.objects.get(username=self.sender_username)

        self.recipient_username = "Alice"
        UserFactory(username=self.recipient_username, email="alice@gmail.com")
        self.recipient = User.objects.get(username=self.recipient_username)
        self.recipient.additional_json_data["email_notification_types"] = json.dumps(
            ["USER_INTERACTION", "INFORMATION"]
        )
        self.recipient.save()

        self.client.login(username=self.recipient, password="pw")

    def test_send_information_notification(self):
        verb = "Wartungsarbeiten: 13.12 10:00 - 13:00 Uhr"
        target_url = "https://www.vbv.ch"
        self.notification_service.send_information_notification(
            recipient=self.recipient,
            verb=verb,
            target_url=target_url,
        )

        notifications: List[Notification] = Notification.objects.all()
        self.assertEqual(1, len(notifications))
        notification = notifications[0]
        self.assertEqual(self.admin, notification.actor)
        self.assertEqual(verb, notification.verb)
        self.assertEqual(target_url, notification.target_url)
        self.assertEqual(
            str(NotificationType.INFORMATION), notification.notification_type
        )
        self.assertTrue(notification.emailed)

    def test_send_progress_notification(self):
        verb = "Super Fortschritt! Melde dich jetzt an."
        target_url = "https://www.vbv.ch"
        course = "Versicherungsvermittler/in"
        self.notification_service.send_progress_notification(
            recipient=self.recipient, verb=verb, target_url=target_url, course=course
        )

        notifications: List[Notification] = Notification.objects.all()
        self.assertEqual(1, len(notifications))
        notification = notifications[0]
        self.assertEqual(self.admin, notification.actor)
        self.assertEqual(verb, notification.verb)
        self.assertEqual(target_url, notification.target_url)
        self.assertEqual(course, notification.course)
        self.assertEqual(str(NotificationType.PROGRESS), notification.notification_type)
        self.assertFalse(notification.emailed)

    def test_send_user_interaction_notification(self):
        verb = "Anne hat deinen Auftrag bewertet"
        target_url = "https://www.vbv.ch"
        course = "Versicherungsvermittler/in"
        self.notification_service.send_user_interaction_notification(
            sender=self.sender,
            recipient=self.recipient,
            verb=verb,
            target_url=target_url,
            course=course,
        )

        notifications: List[Notification] = Notification.objects.all()
        self.assertEqual(1, len(notifications))
        notification = notifications[0]
        self.assertEqual(self.sender, notification.actor)
        self.assertEqual(verb, notification.verb)
        self.assertEqual(target_url, notification.target_url)
        self.assertEqual(course, notification.course)
        self.assertEqual(
            str(NotificationType.USER_INTERACTION), notification.notification_type
        )
        self.assertTrue(notification.emailed)
