"""
Celery задачи для уведомлений.
"""
from celery import shared_task
from django.core.mail import send_mail, EmailMultiAlternatives
from django.conf import settings
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.utils import timezone
import logging

logger = logging.getLogger(__name__)


@shared_task
def send_notification_task(notification_id):
    """
    Отправка уведомления асинхронно.
    
    Args:
        notification_id: ID уведомления для отправки
    """
    from .models import Notification
    
    try:
        notification = Notification.objects.select_related('recipient').get(id=notification_id)
        
        # Проверка настроек пользователя
        try:
            preferences = notification.recipient.notification_preferences
            
            # Проверка включены ли уведомления
            if not preferences.is_type_enabled(notification.notification_type, notification.channel):
                notification.mark_as_sent(error='Отключено в настройках')
                return f'Notification {notification_id} disabled by user preferences'
            
            # Проверка режима тишины
            if preferences.is_quiet_hours():
                # Перенести отправку
                return f'Notification {notification_id} delayed due to quiet hours'
        
        except:
            # Если нет настроек, используем дефолтные
            pass
        
        # Отправка в зависимости от канала
        if notification.channel == 'email':
            result = send_email_notification(notification)
        
        elif notification.channel == 'telegram':
            result = send_telegram_notification(notification)
        
        elif notification.channel == 'in_app':
            # Внутренние уведомления только создаются, не отправляются
            notification.mark_as_sent()
            result = 'In-app notification created'
        
        else:
            result = f'Unknown channel: {notification.channel}'
        
        return result
    
    except Notification.DoesNotExist:
        return f'Notification {notification_id} not found'
    
    except Exception as e:
        logger.error(f'Error sending notification {notification_id}: {str(e)}')
        try:
            notification = Notification.objects.get(id=notification_id)
            notification.mark_as_sent(error=str(e))
        except:
            pass
        return f'Error: {str(e)}'


def send_email_notification(notification):
    """Отправка Email уведомления."""
    try:
        recipient_email = notification.recipient.email
        
        # Пытаемся получить шаблон для этого типа уведомления
        from .models import NotificationTemplate
        
        try:
            template = NotificationTemplate.objects.get(
                notification_type=notification.notification_type,
                is_active=True
            )
            
            # Подготавливаем контекст для шаблона
            context = {
                'title': notification.title,
                'message': notification.message,
                'action_url': f"{settings.FRONTEND_URL}{notification.action_url}" if notification.action_url else None,
                'recipient_name': notification.recipient.get_full_name() or notification.recipient.email,
                'recipient_email': notification.recipient.email,
            }
            
            # Добавляем данные из notification.data, если есть
            if notification.data:
                context.update(notification.data)
            
            # Рендерим шаблон
            rendered = template.render('email', context)
            email_subject = rendered.get('subject', notification.title)
            email_body = rendered.get('body', '')
            
            # Если шаблон не содержит body, используем дефолтный
            if not email_body:
                email_body = f"""
                <html>
                    <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                        <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                            <h2 style="color: #333;">{notification.title}</h2>
                            <div style="background-color: white; padding: 20px; border-radius: 8px; margin: 20px 0;">
                                <p style="color: #666; line-height: 1.6;">{notification.message}</p>
                            </div>
                            {f'<a href="{settings.FRONTEND_URL}{notification.action_url}" style="display: inline-block; background-color: #3B82F6; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">Перейти</a>' if notification.action_url else ''}
                            <p style="color: #999; font-size: 12px; margin-top: 20px;">
                                Это автоматическое уведомление от образовательной платформы.
                            </p>
                        </div>
                    </body>
                </html>
                """
            else:
                # Если есть шаблон, оборачиваем его в базовую HTML структуру, если нужно
                if not email_body.strip().startswith('<html'):
                    email_body = f"""
                    <html>
                        <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                            <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                                {email_body}
                                {f'<a href="{settings.FRONTEND_URL}{notification.action_url}" style="display: inline-block; background-color: #3B82F6; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; margin-top: 20px;">Перейти</a>' if notification.action_url else ''}
                                <p style="color: #999; font-size: 12px; margin-top: 20px;">
                                    Это автоматическое уведомление от образовательной платформы.
                                </p>
                            </div>
                        </body>
                    </html>
                    """
        
        except NotificationTemplate.DoesNotExist:
            # Если шаблона нет, используем дефолтный
            email_subject = notification.title
            email_body = f"""
            <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                        <h2 style="color: #333;">{notification.title}</h2>
                        <div style="background-color: white; padding: 20px; border-radius: 8px; margin: 20px 0;">
                            <p style="color: #666; line-height: 1.6;">{notification.message}</p>
                        </div>
                        {f'<a href="{settings.FRONTEND_URL}{notification.action_url}" style="display: inline-block; background-color: #3B82F6; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">Перейти</a>' if notification.action_url else ''}
                        <p style="color: #999; font-size: 12px; margin-top: 20px;">
                            Это автоматическое уведомление от образовательной платформы.
                        </p>
                    </div>
                </body>
            </html>
            """
        
        plain_message = strip_tags(email_body)
        
        # Отправляем
        msg = EmailMultiAlternatives(
            subject=email_subject,
            body=plain_message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[recipient_email]
        )
        msg.attach_alternative(email_body, "text/html")
        msg.send()
        
        notification.mark_as_sent()
        logger.info(f'Email notification sent to {recipient_email}')
        
        return f'Email sent to {recipient_email}'
    
    except Exception as e:
        logger.error(f'Error sending email notification: {str(e)}')
        notification.mark_as_sent(error=str(e))
        raise


def send_telegram_notification(notification):
    """Отправка Telegram уведомления."""
    try:
        telegram_id = notification.recipient.telegram_id
        
        if not telegram_id:
            notification.mark_as_sent(error='Telegram ID not linked')
            return 'Telegram ID not linked'
        
        # Формируем сообщение в HTML формате
        message_text = f"<b>{notification.title}</b>\n\n{notification.message}"
        
        if notification.action_url:
            full_url = f"{settings.FRONTEND_URL}{notification.action_url}"
            message_text += f'\n\n<a href="{full_url}">Перейти на платформу</a>'
        
        # Отправляем через Telegram Bot API
        from .telegram_bot import send_telegram_message
        import asyncio
        
        try:
            # Запускаем асинхронную отправку
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            success = loop.run_until_complete(
                send_telegram_message(telegram_id, message_text, parse_mode='HTML')
            )
            loop.close()
            
            if success:
                notification.mark_as_sent()
                logger.info(f'Telegram notification sent to {telegram_id}')
                return f'Telegram notification sent to {telegram_id}'
            else:
                notification.mark_as_sent(error='Failed to send message')
                return 'Failed to send Telegram message'
        
        except Exception as e:
            logger.error(f'Error sending telegram message: {str(e)}')
            notification.mark_as_sent(error=str(e))
            return f'Error: {str(e)}'
    
    except Exception as e:
        logger.error(f'Error sending telegram notification: {str(e)}')
        notification.mark_as_sent(error=str(e))
        raise


@shared_task
def send_bulk_notifications(notification_ids):
    """
    Массовая отправка уведомлений.
    
    Args:
        notification_ids: Список ID уведомлений
    """
    results = []
    for notification_id in notification_ids:
        result = send_notification_task.delay(notification_id)
        results.append(result)
    
    return f'Scheduled {len(results)} notifications'


@shared_task
def cleanup_old_notifications():
    """
    Очистка старых уведомлений по правилам:
    - прочитанные: удалять если старше 5 дней (по created_at);
    - непрочитанные: удалять если старше 14 дней (по created_at).
    Запускается периодически через Celery Beat (ежедневно в 3:00).
    """
    from .models import Notification
    from datetime import timedelta

    now = timezone.now()
    read_threshold = now - timedelta(days=5)
    unread_threshold = now - timedelta(days=14)

    deleted_read = Notification.objects.filter(
        is_read=True,
        created_at__lt=read_threshold,
    ).delete()[0]

    deleted_unread = Notification.objects.filter(
        is_read=False,
        created_at__lt=unread_threshold,
    ).delete()[0]

    total = deleted_read + deleted_unread
    logger.info(
        'cleanup_old_notifications: deleted read (older than 5 days)=%s, unread (older than 14 days)=%s, total=%s',
        deleted_read, deleted_unread, total,
    )
    return f'Deleted {total} notifications (read >5d: {deleted_read}, unread >14d: {deleted_unread})'


@shared_task
def send_scheduled_notifications():
    """
    Отправка отложенных уведомлений.
    Запускается каждую минуту через Celery Beat.
    """
    from .models import Notification
    
    # Находим уведомления которые нужно отправить
    notifications = Notification.objects.filter(
        is_sent=False,
        scheduled_for__lte=timezone.now()
    )
    
    count = 0
    for notification in notifications:
        send_notification_task.delay(notification.id)
        count += 1
    
    return f'Scheduled {count} notifications'


@shared_task
def send_lesson_notification(lesson_id, notification_type):
    """
    Отправка уведомления о занятии по типу события.
    Вызывается из schedule.signals.
    """
    from apps.schedule.models import Lesson
    from .services import NotificationService

    try:
        lesson = Lesson.objects.select_related('mentor', 'client', 'client__user').get(id=lesson_id)
    except Lesson.DoesNotExist:
        logger.warning(f'Lesson {lesson_id} not found for notification {notification_type}')
        return f'Lesson {lesson_id} not found'

    if notification_type == 'lesson_created':
        NotificationService.send_lesson_created(lesson)
    elif notification_type == 'lesson_cancelled':
        NotificationService.send_lesson_cancelled(lesson)
    elif notification_type == 'lesson_reminder':
        NotificationService.send_lesson_reminder(lesson)
    elif notification_type == 'lesson_rescheduled':
        NotificationService.send_lesson_rescheduled(lesson)
    elif notification_type == 'lesson_completed':
        NotificationService.send_lesson_completed(lesson)
    else:
        logger.warning(f'Unknown lesson notification type: {notification_type}')
        return f'Unknown type: {notification_type}'

    return f'Lesson notification {notification_type} sent for lesson {lesson_id}'


@shared_task
def send_lesson_reminder(lesson_id, minutes_before=30):
    """
    Отправка напоминания о занятии.
    
    Args:
        lesson_id: ID занятия
        minutes_before: За сколько минут до занятия напоминать
    """
    from apps.schedule.models import Lesson
    from .services import NotificationService
    
    try:
        lesson = Lesson.objects.select_related('mentor', 'client', 'client__user').get(id=lesson_id)
        
        # Проверяем не отправили ли уже
        if lesson.reminder_sent:
            return 'Reminder already sent'
        
        # Отправляем напоминания
        NotificationService.send_lesson_reminder(lesson)
        
        # Отмечаем что напоминание отправлено
        lesson.reminder_sent = True
        # reminder_sent_at временно отключено
        # lesson.reminder_sent_at = timezone.now()
        lesson.save(update_fields=['reminder_sent'])
        
        return f'Lesson reminder sent for lesson {lesson_id}'
    
    except Lesson.DoesNotExist:
        return f'Lesson {lesson_id} not found'
    except Exception as e:
        logger.error(f'Error sending lesson reminder: {str(e)}')
        return f'Error: {str(e)}'
