from django.db import models, transaction
from django.dispatch import receiver

from lms.courses.services import refresh_course_module_weight_sum_cache

from .models import Scorm, ScormFile, ScormResourceStudentAttempt, ScormStudentAttempt
from .services import create_resource_attempts, update_scaled_score, update_scorm_progress
from .tasks import prepare_scorm_task


@receiver(signal=models.signals.post_delete, sender=Scorm)
def scorm_post_delete_handler(instance: Scorm, **kwargs):
    transaction.on_commit(lambda: refresh_course_module_weight_sum_cache(course_id=instance.course_id))


@receiver(signal=models.signals.post_save, sender=Scorm)
def scorm_post_save_handler(instance: Scorm, created: bool, **kwargs):
    if created or instance.field_tracker.has_changed('weight') or instance.field_tracker.has_changed('is_active'):
        transaction.on_commit(lambda: refresh_course_module_weight_sum_cache(course_id=instance.course_id))


@receiver(signal=models.signals.post_save, sender=ScormFile)
def scorm_file_post_save_handler(instance: ScormFile, **kwargs):
    if instance.tracker.has_changed('scorm_status') and instance.scorm_status == ScormFile.SCORM_MODULE_STATUS_READY:
        instance.scorm.current_file = instance
        instance.scorm.save()
        return

    if instance.scorm_status == ScormFile.SCORM_MODULE_STATUS_PENDING:
        transaction.on_commit(lambda: prepare_scorm_task.delay(scorm_file_id=instance.id))


@receiver(signal=models.signals.post_save, sender=ScormStudentAttempt)
def scorm_student_attempt_post_save_handler(instance: ScormStudentAttempt, created: bool, **kwargs):
    if created or instance.tracker.has_changed('current_attempt'):
        create_resource_attempts(attempt=instance)


@receiver(signal=models.signals.pre_save, sender=ScormResourceStudentAttempt)
def scorm_resource_student_attempt_pre_save_handler(instance: ScormResourceStudentAttempt, **kwargs):
    update_scaled_score(attempt=instance)


@receiver(signal=models.signals.post_save, sender=ScormResourceStudentAttempt)
def scorm_resource_student_attempt_post_save_handler(instance: ScormResourceStudentAttempt, **kwargs):
    update_scorm_progress(attempt=instance)
