from datetime import datetime, timedelta

from django.test import TestCase
from django.utils import timezone
from freezegun import freeze_time

from vbv_lernwelt.core.constants import TEST_COURSE_SESSION_BERN_ID
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse
from vbv_lernwelt.notify.email.reminders.attendance import (
    send_attendance_reminder_notifications,
)
from vbv_lernwelt.notify.models import Notification


class TestAttendanceCourseReminders(TestCase):
    def setUp(self):
        create_default_users()
        create_test_course(with_sessions=True)
        CourseSessionAttendanceCourse.objects.all().delete()

        cs_bern = CourseSession.objects.get(
            id=TEST_COURSE_SESSION_BERN_ID,
        )
        self.csac = CourseSessionAttendanceCourse.objects.create(
            course_session=cs_bern,
            learning_content=LearningContentAttendanceCourse.objects.get(
                slug="test-lehrgang-lp-circle-fahrzeug-lc-präsenzkurs-fahrzeug"
            ),
            location="Handelsschule KV Bern, Zimmer 123, Eigerstrasse 16, 3012 Bern",
            trainer="Roland Grossenbacher",
        )
        ref_date_time = timezone.make_aware(datetime(2023, 8, 29))
        self.csac.due_date.start = ref_date_time.replace(
            hour=7, minute=30, second=0, microsecond=0
        )
        self.csac.due_date.end = ref_date_time.replace(
            hour=16, minute=15, second=0, microsecond=0
        )
        self.csac.due_date.save()

        # Attendance course more than two weeks in the future
        self.csac_future = CourseSessionAttendanceCourse.objects.create(
            course_session=cs_bern,
            learning_content=LearningContentAttendanceCourse.objects.get(
                slug="test-lehrgang-lp-circle-fahrzeug-lc-präsenzkurs-fahrzeug"
            ),
            location="Handelsschule BV Bern, Zimmer 122",
            trainer="Thomas Berger",
        )

    @freeze_time("2023-08-25 13:02:01")
    def test_happy_day(self):
        in_two_weeks = datetime.now() + timedelta(weeks=2, days=1)
        self.csac_future.due_date.start = timezone.make_aware(
            in_two_weeks.replace(hour=5, minute=20, second=0, microsecond=0)
        )
        self.csac_future.due_date.end = timezone.make_aware(
            in_two_weeks.replace(hour=15, minute=20, second=0, microsecond=0)
        )
        self.csac_future.due_date.save()

        send_attendance_reminder_notifications()

        self.assertEqual(4, len(Notification.objects.all()))
        notification = Notification.objects.get(
            recipient__username="test-student1@example.com"
        )

        self.assertEqual(
            "Erinnerung: Bald findet ein Präsenzkurs statt",
            notification.verb,
        )
        self.assertEqual(
            "INFORMATION",
            notification.notification_category,
        )
        self.assertEqual(
            "ATTENDANCE_COURSE_REMINDER",
            notification.notification_trigger,
        )
        self.assertEqual(
            self.csac,
            notification.action_object,
        )
        self.assertEqual(
            self.csac.course_session,
            notification.course_session,
        )
        self.assertEqual(
            "/course/test-lehrgang/learn/fahrzeug/präsenzkurs-fahrzeug",
            notification.target_url,
        )
        self.assertEqual(
            self.csac.learning_content.title,
            notification.data["template_data"]["attendance_course"],
        )
        self.assertEqual(
            self.csac.location,
            notification.data["template_data"]["location"],
        )
        self.assertEqual(
            self.csac.trainer,
            notification.data["template_data"]["trainer"],
        )
        self.assertEqual(
            self.csac.due_date.start.strftime("%d.%m.%Y %H:%M"),
            notification.data["template_data"]["start"],
        )
        self.assertEqual(
            self.csac.due_date.end.strftime("%d.%m.%Y %H:%M"),
            notification.data["template_data"]["end"],
        )
