import os
from datetime import date, datetime, time

from django.test import TestCase

from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.importer.services import (
    create_or_update_student,
    sanitize_json_data_input,
    sync_students_from_t2l,
)

test_dir = os.path.dirname(os.path.abspath(__file__))


class SyncT2lTestCase(TestCase):
    def setUp(self):
        self.course = create_test_course(include_vv=False)
        self.course_session_a = CourseSession.objects.create(
            course=self.course,
            title="Deutschschweiz 2023 A",
            import_id="DE 2023 A",
            group="A",
        )

        self.user_dict = {
            "Name": "Rascher",
            "Vorname": "Barbara",
            "Email": "barbara.rascher@vbv-afa.ch",
            "Sprache": "de",
            "Durchführungen": "DE 2023 A",
            "Lehrvertragsnummer": "1234",
            "Tel. Privat": "079 593 83 43",
            "Geburtsdatum": "01.01.2000",
        }
        create_or_update_student(self.user_dict)

    def test_updates_field(self):
        user_dict = {
            "Name": "Rascher",
            "Vorname": "Barbara",
            "Email": "barbara.rascher@vbv-afa.ch",
            "Sprache": "de",
            "Durchführungen": "DE 2023 A",
            "Lehrvertragsnummer": "1234",
            "Tel. Privat": "079 593 83 65",
            "Geburtsdatum": "01.01.2000",
        }

        sync_students_from_t2l(user_dict)
        updated_user = CourseSessionUser.objects.get(
            user__email=self.user_dict["Email"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Tel. Privat"],
            user_dict["Tel. Privat"],
        )

    def test_adds_field(self):
        user_dict = {
            "Name": "Rascher",
            "Vorname": "Barbara",
            "Email": "barbara.rascher@vbv-afa.ch",
            "Sprache": "de",
            "Durchführungen": "DE 2023 A",
            "Lehrvertragsnummer": "1234",
            "Tel. Privat": "079 593 83 43",
            "Firma": "VBV",
            "Geburtsdatum": "01.01.2000",
        }

        sync_students_from_t2l(user_dict)
        updated_user = CourseSessionUser.objects.get(
            user__email=self.user_dict["Email"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Firma"], user_dict["Firma"]
        )

    def test_ignors_defined_field(self):
        user_dict = {
            "Name": "Rascher2",
            "Vorname": "Barbara2",
            "Email": "barbara.rascher2@vbv-afa.ch",
            "Sprache": "fr",
            "Durchführungen": "DE 2023 B",
            "Lehrvertragsnummer": "1234",
            "Tel. Privat": "079 593 83 43",
            "Geburtsdatum": "01.01.2000",
        }

        sync_students_from_t2l(user_dict)
        updated_user = CourseSessionUser.objects.get(
            user__email=self.user_dict["Email"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Name"], self.user_dict["Name"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Vorname"], self.user_dict["Vorname"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Durchführungen"],
            self.user_dict["Durchführungen"],
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Sprache"], self.user_dict["Sprache"]
        )

    def test_ignors_missing_defined_field(self):
        user_dict = {
            "Name": "Rascher2",
            "Vorname": "Barbara2",
            "Email": "barbara.rascher2@vbv-afa.ch",
            "Sprache": "fr",
            "Lehrvertragsnummer": "1234",
            "Tel. Privat": "079 593 83 43",
        }

        sync_students_from_t2l(user_dict)
        updated_user = CourseSessionUser.objects.get(
            user__email=self.user_dict["Email"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Name"], self.user_dict["Name"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Vorname"], self.user_dict["Vorname"]
        )
        self.assertEqual(
            updated_user.user.additional_json_data["Sprache"], self.user_dict["Sprache"]
        )

    def test_ignors_wrong_contract_nummer(self):
        user_dict = {
            "Name": "Rascher2",
            "Vorname": "Barbara2",
            "Email": "barbara.rascher2@vbv-afa.ch",
            "Sprache": "fr",
            "Lehrvertragsnummer": "12345",
            "Tel. Privat": "079 593 83 43",
        }

        try:
            sync_students_from_t2l(user_dict)
            updated_user = CourseSessionUser.objects.get(
                user__email=self.user_dict["Email"]
            )
        except Exception as e:
            self.fail(
                f"SyncT2lTestCase.test_ignors_wrong_contract_number: An exception was unexpectedly raised: {str(e)}"
            )


class SanitizerTestCase(TestCase):
    def test_date(self):
        a_date = date(2021, 1, 1)
        user_dict = {"Name": "Rascher", "Datum": a_date}

        expected_sanitized_data = {"Name": "Rascher", "Datum": a_date.isoformat()}

        sanitized_data = sanitize_json_data_input(user_dict)
        self.assertEqual(sanitized_data, expected_sanitized_data)

    def test_datetime(self):
        a_date = datetime(2021, 1, 1)
        user_dict = {"Name": "Rascher", "Datum": a_date}

        expected_sanitized_data = {"Name": "Rascher", "Datum": a_date.isoformat()}

        sanitized_data = sanitize_json_data_input(user_dict)
        self.assertEqual(sanitized_data, expected_sanitized_data)

    def test_time(self):
        a_date = time(23, 59, 59)
        user_dict = {"Name": "Rascher", "Datum": a_date}

        expected_sanitized_data = {"Name": "Rascher", "Datum": a_date.isoformat()}

        sanitized_data = sanitize_json_data_input(user_dict)
        self.assertEqual(sanitized_data, expected_sanitized_data)
