"""
Signals для приложения schedule.
Автоматические действия при изменении расписания.
"""

from django.db.models.signals import post_save, pre_delete, pre_save
from django.dispatch import receiver
from django.utils import timezone
from datetime import timedelta

from .models import Lesson
from apps.notifications.tasks import send_lesson_notification, send_lesson_completion_confirmation_telegram


@receiver(post_save, sender=Lesson)
def lesson_saved(sender, instance, created, **kwargs):
    """
    Обработка создания или изменения занятия.
    
    При создании:
    - Отправка уведомления ментору и клиенту
    - Планирование напоминания перед занятием
    
    При изменении:
    - Отправка уведомления об изменении времени/статуса
    """
    if created:
        # Новое занятие создано
        send_lesson_notification.delay(
            lesson_id=instance.id,
            notification_type='lesson_created'
        )
        # Если занятие создано сразу в статусе completed (задним числом) — отправляем подтверждение в Telegram
        if instance.status == 'completed':
            send_lesson_completion_confirmation_telegram.delay(instance.id)
        # Напоминания отправляются периодической задачей send_lesson_reminders
        # (проверяет флаги reminder_24h_sent, reminder_1h_sent, reminder_15m_sent)
    else:
        # Занятие изменено
        # Проверяем, что именно изменилось
        if instance.tracker.has_changed('start_time') or instance.tracker.has_changed('end_time'):
            # Время изменилось
            send_lesson_notification.delay(
                lesson_id=instance.id,
                notification_type='lesson_rescheduled'
            )
        
        if instance.tracker.has_changed('status'):
            # При переводе в completed — всегда отправляем подтверждение в Telegram (с кнопками «состоялось»/«отменилось»)
            # Работает для ручного завершения и для занятий, созданных/завершённых задним числом
            if instance.status == 'completed':
                send_lesson_completion_confirmation_telegram.delay(instance.id)

            # Общие уведомления — не отправляем, если занятие уже в прошлом
            # (коррекция статуса/стоимости после факта, например отмена задним числом)
            ref_time = instance.end_time or instance.start_time
            if ref_time and ref_time < timezone.now():
                return  # Занятие уже прошло — пропускаем lesson_cancelled / lesson_completed
            if instance.status == 'cancelled':
                send_lesson_notification.delay(
                    lesson_id=instance.id,
                    notification_type='lesson_cancelled'
                )
            elif instance.status == 'completed':
                send_lesson_notification.delay(
                    lesson_id=instance.id,
                    notification_type='lesson_completed'
                )


@receiver(pre_delete, sender=Lesson)
def lesson_deleted(sender, instance, **kwargs):
    """
    Обработка удаления занятия.
    Отправка уведомления об отмене.
    """
    if instance.status != 'cancelled':
        send_lesson_notification.delay(
            lesson_id=instance.id,
            notification_type='lesson_cancelled'
        )


@receiver(pre_save, sender=Lesson)
def lesson_before_save(sender, instance, **kwargs):
    """
    Действия перед сохранением занятия.
    Инициализация tracker для отслеживания изменений.
    """
    if not hasattr(instance, 'tracker'):
        # Создаем простой tracker для отслеживания изменений
        if instance.pk:
            try:
                old_instance = Lesson.objects.get(pk=instance.pk)
                instance.tracker = type('obj', (object,), {
                    'has_changed': lambda field: getattr(old_instance, field) != getattr(instance, field)
                })
            except Lesson.DoesNotExist:
                instance.tracker = type('obj', (object,), {
                    'has_changed': lambda field: False
                })
        else:
            instance.tracker = type('obj', (object,), {
                'has_changed': lambda field: False
            })
