import logging

from django.db import models, transaction
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _

from lms.classrooms.models import Classroom, StudentSlot, Timeslot

from .models import CalendarEvent
from .tasks import (
    create_event_for_timeslot_task, create_layer_for_course_task, delete_calendar_event_task,
    update_event_for_timeslot_task, update_student_event_attendance_task, update_timeslot_dates_from_calendar_task,
)

log = logging.getLogger(__name__)


@receiver(signal=models.signals.post_save, sender=Classroom)
def classroom_post_save_handler(instance: Classroom, created: bool, **kwargs):
    if created and instance.calendar_enabled:
        transaction.on_commit(lambda: create_layer_for_course_task.delay(course_id=instance.course_id))


@receiver(signal=models.signals.post_save, sender=Timeslot)
def timeslot_post_save_handler(instance: Timeslot, created: bool, **kwargs):
    if created and instance.classroom.calendar_enabled:
        transaction.on_commit(lambda: create_event_for_timeslot_task.delay(timeslot_id=instance.pk))
    if not created and instance.classroom.calendar_enabled:
        if instance.tracker.has_changed('begin_date') or instance.tracker.has_changed('end_date'):
            transaction.on_commit(lambda: update_timeslot_dates_from_calendar_task.delay(timeslot_id=instance.pk))
        if instance.tracker.has_changed('summary'):
            transaction.on_commit(lambda: update_event_for_timeslot_task.delay(timeslot_id=instance.pk))


@receiver(signal=models.signals.post_save, sender=StudentSlot)
def student_slot_post_save_handler(instance: StudentSlot, created: bool, **kwargs):
    if created or instance.tracker.has_changed('status'):
        transaction.on_commit(
            lambda: update_student_event_attendance_task.delay(
                timeslot_id=instance.timeslot_id,
                student_id=instance.student_id
            )
        )


@receiver(signal=models.signals.pre_delete, sender=CalendarEvent)
def calendar_event_pre_delete_handler(instance: CalendarEvent, **kwargs):
    instance._event_id = instance.id


@receiver(signal=models.signals.post_delete, sender=CalendarEvent)
def calendar_event_post_delete_handler(instance: CalendarEvent, **kwargs):
    # в post_delete наш instance уже удалён из базы и у него нет id, поэтому сохранем его в pre_delete
    event_id = getattr(instance, '_event_id')
    if not event_id:
        log.error(_("Не найден event_id для встречи в календаре с course_id=%s и timeslot_id=%s")
                  % instance.course_id, instance.timeslot_id)
        return
    transaction.on_commit(lambda: delete_calendar_event_task.delay(event_id=event_id))
