import datetime

from django.core import mail
from django.urls import reverse

from web.models import Item, Appointment, AppointmentTypeLink
from web.tests import LoggedInTestCase
from web.tests.functions import create_appointment_type, create_appointment, create_visit, create_appointment_without_visit
from web.views.kit import get_kit_requests
from web.views.notifications import get_today_midnight_date


class ViewFunctionsTests(LoggedInTestCase):

    def test_kit_requests(self):
        response = self.client.get(reverse('web.views.kit_requests'))
        self.assertEqual(response.status_code, 200)

    def test_kit_requests_2(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        appointment = create_appointment()
        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment, appointment_type=appointment_type)

        response = self.client.get(reverse('web.views.kit_requests'))
        self.assertEqual(response.status_code, 200)

        self.assertTrue(item_name in response.content)

    def test_kit_requests_4(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        appointment = create_appointment()
        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
        appointment.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment, appointment_type=appointment_type)

        response = self.client.get(reverse('web.views.kit_requests'))
        self.assertEqual(response.status_code, 200)

        self.assertFalse(item_name in response.content)

    def test_kit_requests_3(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        appointment = create_appointment()
        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment, appointment_type=appointment_type)

        response = self.client.get(reverse('web.views.kit_requests'))
        self.assertEqual(response.status_code, 200)

        self.assertTrue(item_name in response.content)

    def test_kit_requests_order(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        visit = create_visit()

        appointment1 = create_appointment(visit)
        appointment1.datetime_when = get_today_midnight_date() + datetime.timedelta(days=3)
        appointment1.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment1, appointment_type=appointment_type)

        appointment2 = create_appointment(visit)
        appointment2.datetime_when = get_today_midnight_date() + datetime.timedelta(days=4)
        appointment2.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment2, appointment_type=appointment_type)

        appointment3 = create_appointment(visit)
        appointment3.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment3.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment3, appointment_type=appointment_type)

        result = get_kit_requests(self.user)
        self.assertEqual(appointment3, result['appointments'][0])
        self.assertEqual(appointment1, result['appointments'][1])
        self.assertEqual(appointment2, result['appointments'][2])

    def test_kit_requests_for_appointment_with_two_types(self):
        item = Item.objects.create(disposable=True, name="item 1")
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        item = Item.objects.create(disposable=True, name="item 2")
        appointment_type2 = create_appointment_type()
        appointment_type2.required_equipment.add(item)
        appointment_type2.save()

        visit = create_visit()

        appointment1 = create_appointment(visit)
        appointment1.datetime_when = get_today_midnight_date() + datetime.timedelta(days=3)
        appointment1.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment1, appointment_type=appointment_type)
        AppointmentTypeLink.objects.create(
            appointment=appointment1, appointment_type=appointment_type2)

        result = get_kit_requests(self.user)

        self.assertEqual(1, len(result["appointments"]))

    def test_kit_requests_send_email(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()

        appointment = create_appointment()
        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment, appointment_type=appointment_type)

        response = self.client.get(reverse('web.views.kit_requests_send_mail',
                                           kwargs={'start_date': str(get_today_midnight_date().strftime("%Y-%m-%d"))}))
        self.assertEqual(response.status_code, 200)

        self.assertTrue(item_name in response.content)

        self.assertEqual(1, len(mail.outbox))

    def test_kit_request_send_mail_with_general_appointment(self):
        item_name = "Test item to be ordered"
        item = Item.objects.create(disposable=True, name=item_name)
        appointment_type = create_appointment_type()
        appointment_type.required_equipment.add(item)
        appointment_type.save()
        appointment = create_appointment_without_visit()
        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
        appointment.save()
        AppointmentTypeLink.objects.create(
            appointment=appointment, appointment_type=appointment_type)
        response = self.client.get(reverse('web.views.kit_requests_send_mail',
                                           kwargs={'start_date': str(get_today_midnight_date().strftime("%Y-%m-%d"))}))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(item_name in response.content)
        self.assertEqual(1, len(mail.outbox))