"""
Сервисы для уведомлений и Telegram интеграции.
"""
import secrets
import string
from django.core.cache import cache
from django.utils import timezone
from datetime import timedelta
import logging
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

logger = logging.getLogger(__name__)


class TelegramLinkService:
    """Сервис для связывания Telegram аккаунтов."""
    
    @staticmethod
    def generate_link_code(user_id: int) -> str:
        """
        Генерация кода для связывания Telegram аккаунта.
        
        Args:
            user_id: ID пользователя
        
        Returns:
            str: Код связывания (6 символов)
        """
        # Генерируем случайный код из цифр и букв
        code = ''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(6))
        
        # Сохраняем в кэш на 15 минут
        cache_key = f'telegram_link_{code}'
        cache.set(cache_key, user_id, timeout=900)  # 15 минут
        
        logger.info(f"Generated link code {code} for user {user_id}")
        
        return code
    
    @staticmethod
    def link_account(link_code: str, telegram_id: int, telegram_username: str = '') -> dict:
        """
        Связывание Telegram аккаунта с аккаунтом на платформе.
        
        Args:
            link_code: Код связывания
            telegram_id: ID пользователя в Telegram
            telegram_username: Username в Telegram
        
        Returns:
            dict: Результат связывания
        """
        from apps.users.models import User
        
        # Проверяем код в кэше
        cache_key = f'telegram_link_{link_code}'
        user_id = cache.get(cache_key)
        
        if not user_id:
            return {
                'success': False,
                'error': 'Неверный или истекший код связывания'
            }
        
        try:
            # Находим пользователя
            user = User.objects.get(id=user_id)
            
            # Проверяем не привязан ли уже этот Telegram ID к другому аккаунту
            existing_user = User.objects.filter(telegram_id=telegram_id).first()
            if existing_user and existing_user.id != user.id:
                return {
                    'success': False,
                    'error': 'Этот Telegram аккаунт уже привязан к другому пользователю'
                }
            
            # Связываем аккаунты
            user.telegram_id = telegram_id
            user.telegram_username = telegram_username
            user.save(update_fields=['telegram_id', 'telegram_username'])
            
            # Удаляем код из кэша
            cache.delete(cache_key)
            
            # Включаем Telegram уведомления
            try:
                preferences = user.notification_preferences
                if not preferences.telegram_enabled:
                    preferences.telegram_enabled = True
                    preferences.save(update_fields=['telegram_enabled'])
            except:
                # Если нет настроек, создаем
                create_notification_preferences(user)
            
            logger.info(f"Linked Telegram {telegram_id} to user {user.id}")
            
            return {
                'success': True,
                'user_name': user.get_full_name() or user.email,
                'user_email': user.email
            }
        
        except User.DoesNotExist:
            return {
                'success': False,
                'error': 'Пользователь не найден'
            }
        except Exception as e:
            logger.error(f"Error linking Telegram account: {e}")
            return {
                'success': False,
                'error': 'Ошибка связывания аккаунта'
            }
    
    @staticmethod
    def unlink_account(telegram_id: int) -> dict:
        """
        Отвязка Telegram аккаунта.
        
        Args:
            telegram_id: ID пользователя в Telegram
        
        Returns:
            dict: Результат отвязки
        """
        from apps.users.models import User
        
        try:
            user = User.objects.get(telegram_id=telegram_id)
            
            user.telegram_id = None
            user.telegram_username = ''
            user.save(update_fields=['telegram_id', 'telegram_username'])
            
            # Выключаем Telegram уведомления
            try:
                preferences = user.notification_preferences
                preferences.telegram_enabled = False
                preferences.save(update_fields=['telegram_enabled'])
            except:
                pass
            
            logger.info(f"Unlinked Telegram {telegram_id} from user {user.id}")
            
            return {
                'success': True,
                'message': 'Аккаунт успешно отвязан'
            }
        
        except User.DoesNotExist:
            return {
                'success': False,
                'error': 'Аккаунт не найден'
            }
        except Exception as e:
            logger.error(f"Error unlinking Telegram account: {e}")
            return {
                'success': False,
                'error': 'Ошибка отвязки аккаунта'
            }


class NotificationService:
    """Сервис для работы с уведомлениями."""
    
    @staticmethod
    def create_notification(recipient, notification_type, title, message, **kwargs):
        """
        Создание уведомления.
        
        Args:
            recipient: Получатель (User)
            notification_type: Тип уведомления
            title: Заголовок
            message: Сообщение
            **kwargs: Дополнительные параметры (channel, priority, action_url, content_object и т.д.)
        """
        from .models import Notification
        from .tasks import send_notification_task
        from .serializers import NotificationSerializer
        
        # Получаем канал из kwargs или используем 'in_app' по умолчанию
        channel = kwargs.pop('channel', 'in_app')
        
        # Создаем уведомление
        notification = Notification.create_notification(
            recipient=recipient,
            notification_type=notification_type,
            title=title,
            message=message,
            channel=channel,
            **kwargs
        )
        
        # Отправляем асинхронно (кроме in_app, они уже в БД)
        if channel != 'in_app':
            send_notification_task.delay(notification.id)
        elif channel == 'in_app':
            # Отправляем через WebSocket для real-time уведомлений
            WebSocketNotificationService.send_notification_via_websocket(notification)
        
        return notification
    
    @staticmethod
    def create_notification_with_telegram(recipient, notification_type, title, message, **kwargs):
        """
        Создание уведомления с автоматической отправкой в Telegram и Email (если возможно).
        Создает уведомления только если они включены в настройках пользователя.
        
        Args:
            recipient: Получатель (User)
            notification_type: Тип уведомления
            title: Заголовок
            message: Сообщение
            **kwargs: Дополнительные параметры (priority, action_url, content_object, child_id и т.д.)
        """
        from .models import Notification, ParentChildNotificationSettings
        from .tasks import send_notification_task
        
        # Проверяем настройки уведомлений родителя для конкретного ребенка
        if recipient.role == 'parent':
            child_id = kwargs.get('child_id') or kwargs.get('data', {}).get('child_id')
            if child_id:
                try:
                    from apps.users.models import Client, Parent
                    parent = recipient.parent_profile
                    if not parent:
                        logger.warning(f'Parent profile not found for user {recipient.id}')
                        # Продолжаем без фильтрации, если профиль родителя не найден
                    else:
                        # Получаем ребенка по user_id
                        try:
                            child = Client.objects.get(user_id=child_id)
                        except Client.DoesNotExist:
                            logger.warning(f'Child with user_id {child_id} not found')
                            # Продолжаем без фильтрации, если ребенок не найден
                            child = None
                        
                        if child:
                            # Проверяем, что ребенок связан с этим родителем
                            if child in parent.children.all():
                                # Получаем настройки для этого ребенка
                                try:
                                    child_settings = ParentChildNotificationSettings.objects.get(
                                        parent=parent,
                                        child=child
                                    )
                                    # Проверяем, включены ли уведомления для этого ребенка
                                    if not child_settings.enabled:
                                        logger.info(f'Notifications disabled for parent {recipient.id} and child {child_id}, skipping notification {notification_type}')
                                        return None
                                    
                                    # Проверяем, включен ли конкретный тип уведомления для этого ребенка
                                    if not child_settings.is_type_enabled(notification_type):
                                        logger.info(f'Notification type {notification_type} disabled for parent {recipient.id} and child {child_id}')
                                        return None
                                except ParentChildNotificationSettings.DoesNotExist:
                                    # Если настройки не созданы, используем дефолтные (включено)
                                    logger.debug(f'No notification settings found for parent {recipient.id} and child {child_id}, using defaults (enabled)')
                                    pass
                            else:
                                logger.warning(f'Child {child_id} is not associated with parent {recipient.id}')
                                # Продолжаем без фильтрации, если ребенок не связан с родителем
                except Exception as e:
                    logger.warning(f'Error checking parent-child notification settings: {e}', exc_info=True)
        
        # Проверяем настройки уведомлений
        try:
            preferences = recipient.notification_preferences
        except:
            preferences = None
        
        # Если уведомления полностью отключены, не создаем ничего
        if preferences and not preferences.enabled:
            logger.info(f'Notifications disabled for user {recipient.id}, skipping notification {notification_type}')
            return None
        
        # Создаем in_app уведомление, если включено
        in_app_notification = None
        in_app_enabled = True
        if preferences:
            in_app_enabled = preferences.is_type_enabled(notification_type, 'in_app')
        else:
            # Если нет настроек, создаем по умолчанию
            in_app_enabled = True
        
        if in_app_enabled:
            in_app_notification = Notification.create_notification(
                recipient=recipient,
                notification_type=notification_type,
                title=title,
                message=message,
                channel='in_app',
                **kwargs
            )
            # Отправляем через WebSocket для real-time уведомлений
            WebSocketNotificationService.send_notification_via_websocket(in_app_notification)
        
        # Создаем email уведомление, если включено
        email_enabled = True
        if preferences:
            email_enabled = preferences.is_type_enabled(notification_type, 'email')
        else:
            # Если нет настроек, проверяем есть ли email у пользователя
            email_enabled = bool(recipient.email)
        
        if email_enabled and recipient.email:
            # Создаем email уведомление
            email_notification = Notification.create_notification(
                recipient=recipient,
                notification_type=notification_type,
                title=title,
                message=message,
                channel='email',
                **kwargs
            )
            # Отправляем асинхронно
            send_notification_task.delay(email_notification.id)
        
        # Создаем telegram уведомление, если возможно
        if recipient.telegram_id:
            telegram_enabled = True
            if preferences:
                telegram_enabled = preferences.is_type_enabled(notification_type, 'telegram')
            else:
                # Если нет настроек, считаем что telegram включен по умолчанию
                telegram_enabled = True
            
            if telegram_enabled:
                # Создаем telegram уведомление
                telegram_notification = Notification.create_notification(
                    recipient=recipient,
                    notification_type=notification_type,
                    title=title,
                    message=message,
                    channel='telegram',
                    **kwargs
                )
                # Отправляем асинхронно
                send_notification_task.delay(telegram_notification.id)
        
        return in_app_notification
    
    @staticmethod
    def send_lesson_created(lesson):
        """
        Отправка уведомления о создании занятия.
        
        Args:
            lesson: Объект занятия
        """
        from django.utils import timezone
        import pytz
        
        # Уведомление клиенту
        if lesson.client and lesson.client.user:
            # Используем часовой пояс пользователя
            from apps.users.utils import get_user_timezone
            user_timezone = get_user_timezone(lesson.client.user.timezone or 'UTC')
            if timezone.is_aware(lesson.start_time):
                local_time = lesson.start_time.astimezone(user_timezone)
            else:
                # Если время не aware, считаем что оно в UTC
                utc_time = timezone.make_aware(lesson.start_time, pytz.UTC)
                local_time = utc_time.astimezone(user_timezone)
            
            start_time = local_time.strftime('%d.%m.%Y в %H:%M')
            
            # Проверяем, является ли занятие постоянным
            is_recurring = getattr(lesson, 'is_recurring', False)
            recurring_text = ' (постоянное занятие)' if is_recurring else ''
            
            NotificationService.create_notification_with_telegram(
                recipient=lesson.client.user,
                notification_type='lesson_created',
                title='📅 Новое занятие',
                message=f'Запланировано занятие{recurring_text}: {lesson.title} на {start_time}',
                priority='normal',
                action_url=f'/schedule?lesson={lesson.id}',
                content_object=lesson
            )
            
            # Отправляем уведомление родителям ребенка
            from apps.users.models import Parent
            child_user = lesson.client.user
            child_id = child_user.id
            
            # Находим всех родителей этого ребенка
            try:
                child_client = lesson.client
                # Оптимизация: используем list() для кеширования запроса
                parents = list(child_client.parents.select_related('user').all())
                
                for parent in parents:
                    if parent.user:
                        NotificationService.create_notification_with_telegram(
                            recipient=parent.user,
                            notification_type='lesson_created',
                            title='📅 Новое занятие для вашего ребенка',
                            message=f'Запланировано занятие{recurring_text} для {child_user.get_full_name() or child_user.email}: {lesson.title} на {start_time}',
                            priority='normal',
                            action_url=f'/schedule?lesson={lesson.id}',
                            content_object=lesson,
                            child_id=child_id,
                            data={'child_id': child_id}
                        )
            except Exception as e:
                logger.warning(f'Error sending notification to parents for lesson {lesson.id}: {e}')
    
    @staticmethod
    def send_lesson_cancelled(lesson):
        """
        Отправка уведомления об отмене занятия.
        
        Args:
            lesson: Объект занятия
        """
        # Уведомление клиенту
        if lesson.client and lesson.client.user:
            child_user = lesson.client.user
            child_id = child_user.id
            
            NotificationService.create_notification_with_telegram(
                recipient=child_user,
                notification_type='lesson_cancelled',
                title='❌ Занятие отменено',
                message=f'Занятие "{lesson.title}" отменено',
                priority='high',
                action_url='/schedule',
                content_object=lesson
            )
            
            # Отправляем уведомление родителям ребенка
            try:
                child_client = lesson.client
                # Оптимизация: используем list() для кеширования запроса
                parents = list(child_client.parents.select_related('user').all())
                
                for parent in parents:
                    if parent.user:
                        NotificationService.create_notification_with_telegram(
                            recipient=parent.user,
                            notification_type='lesson_cancelled',
                            title='❌ Занятие отменено',
                            message=f'Занятие "{lesson.title}" для {child_user.get_full_name() or child_user.email} отменено',
                            priority='high',
                            action_url='/schedule',
                            content_object=lesson,
                            child_id=child_id,
                            data={'child_id': child_id}
                        )
            except Exception as e:
                logger.warning(f'Error sending notification to parents for cancelled lesson {lesson.id}: {e}')
    
    @staticmethod
    def send_lesson_rescheduled(lesson):
        """Уведомление о переносе занятия."""
        from django.utils import timezone
        import pytz
        from apps.users.utils import get_user_timezone
        user_tz = get_user_timezone(lesson.mentor.timezone or 'UTC')
        if timezone.is_aware(lesson.start_time):
            local_time = lesson.start_time.astimezone(user_tz)
        else:
            local_time = timezone.make_aware(lesson.start_time, pytz.UTC).astimezone(user_tz)
        start_str = local_time.strftime('%d.%m.%Y в %H:%M')
        msg = f'Занятие "{lesson.title}" перенесено на {start_str}'
        NotificationService.create_notification_with_telegram(
            recipient=lesson.mentor,
            notification_type='lesson_rescheduled',
            title='📅 Занятие перенесено',
            message=msg,
            priority='normal',
            action_url=f'/schedule?lesson={lesson.id}',
            content_object=lesson
        )
        if lesson.client and lesson.client.user:
            child_user = lesson.client.user
            child_tz = get_user_timezone(child_user.timezone or 'UTC')
            if timezone.is_aware(lesson.start_time):
                local_time = lesson.start_time.astimezone(child_tz)
            else:
                local_time = timezone.make_aware(lesson.start_time, pytz.UTC).astimezone(child_tz)
            start_str = local_time.strftime('%d.%m.%Y в %H:%M')
            NotificationService.create_notification_with_telegram(
                recipient=child_user,
                notification_type='lesson_rescheduled',
                title='📅 Занятие перенесено',
                message=f'Занятие "{lesson.title}" перенесено на {start_str}',
                priority='normal',
                action_url=f'/schedule?lesson={lesson.id}',
                content_object=lesson
            )
            try:
                parents = list(lesson.client.parents.select_related('user').all())
                for parent in parents:
                    if parent.user:
                        NotificationService.create_notification_with_telegram(
                            recipient=parent.user,
                            notification_type='lesson_rescheduled',
                            title='📅 Занятие перенесено',
                            message=f'Занятие "{lesson.title}" для {child_user.get_full_name() or child_user.email} перенесено на {start_str}',
                            priority='normal',
                            action_url=f'/schedule?lesson={lesson.id}',
                            content_object=lesson,
                            child_id=child_user.id,
                            data={'child_id': child_user.id}
                        )
            except Exception as e:
                logger.warning(f'Error sending rescheduled notification to parents for lesson {lesson.id}: {e}')
    
    @staticmethod
    def send_lesson_completed(lesson):
        """Уведомление о завершении занятия."""
        NotificationService.create_notification_with_telegram(
            recipient=lesson.mentor,
            notification_type='lesson_completed',
            title='✅ Занятие завершено',
            message=f'Занятие "{lesson.title}" завершено',
            priority='normal',
            action_url=f'/schedule?lesson={lesson.id}',
            content_object=lesson
        )
        if lesson.client and lesson.client.user:
            child_user = lesson.client.user
            NotificationService.create_notification_with_telegram(
                recipient=child_user,
                notification_type='lesson_completed',
                title='✅ Занятие завершено',
                message=f'Занятие "{lesson.title}" завершено',
                priority='normal',
                action_url=f'/schedule?lesson={lesson.id}',
                content_object=lesson
            )
            try:
                parents = list(lesson.client.parents.select_related('user').all())
                for parent in parents:
                    if parent.user:
                        NotificationService.create_notification_with_telegram(
                            recipient=parent.user,
                            notification_type='lesson_completed',
                            title='✅ Занятие завершено',
                            message=f'Занятие "{lesson.title}" для {child_user.get_full_name() or child_user.email} завершено',
                            priority='normal',
                            action_url=f'/schedule?lesson={lesson.id}',
                            content_object=lesson,
                            child_id=child_user.id,
                            data={'child_id': child_user.id}
                        )
            except Exception as e:
                logger.warning(f'Error sending completed notification to parents for lesson {lesson.id}: {e}')
    
    @staticmethod
    def send_lesson_deleted(lesson, is_recurring_series=False):
        """
        Отправка уведомления об удалении занятия.
        
        Args:
            lesson: Объект занятия
            is_recurring_series: Если True, отправляет уведомление о удалении цепочки постоянных занятий
        """
        # Уведомление клиенту
        if lesson.client and lesson.client.user:
            if is_recurring_series:
                # Уведомление об удалении цепочки постоянных занятий
                NotificationService.create_notification_with_telegram(
                    recipient=lesson.client.user,
                    notification_type='lesson_cancelled',
                    title='🗑️ Постоянные занятия удалены',
                    message=f'Цепочка постоянных занятий "{lesson.title}" удалена',
                    priority='high',
                    action_url='/schedule',
                    content_object=lesson
                )
            else:
                # Уведомление об удалении одного занятия
                NotificationService.create_notification_with_telegram(
                    recipient=lesson.client.user,
                    notification_type='lesson_cancelled',
                    title='🗑️ Занятие удалено',
                    message=f'Занятие "{lesson.title}" удалено',
                    priority='high',
                    action_url='/schedule',
                    content_object=lesson
                )
    
    @staticmethod
    def send_lesson_reminder(lesson, time_before=None):
        """
        Отправка напоминания о занятии.
        
        Args:
            lesson: Объект занятия
            time_before: Время до занятия (например, "24 часа", "1 час", "15 минут")
        """
        from django.utils import timezone
        import pytz
        
        # Вычисляем время до занятия для сообщения
        now = timezone.now()
        if timezone.is_aware(lesson.start_time):
            time_until = lesson.start_time - now
        else:
            utc_time = timezone.make_aware(lesson.start_time, pytz.UTC)
            time_until = utc_time - now
        
        # Форматируем время до занятия
        if time_before:
            time_text = f"через {time_before}"
        else:
            # Автоматически определяем время до занятия
            total_seconds = int(time_until.total_seconds())
            hours = total_seconds // 3600
            minutes = (total_seconds % 3600) // 60
            
            if hours >= 24:
                days = hours // 24
                time_text = f"через {days} {NotificationService._pluralize_days(days)}"
            elif hours > 0:
                time_text = f"через {hours} {NotificationService._pluralize_hours(hours)}"
            elif minutes > 0:
                time_text = f"через {minutes} {NotificationService._pluralize_minutes(minutes)}"
            else:
                time_text = "скоро"
        
        # Отправляем ментору
        from apps.users.utils import get_user_timezone
        mentor_timezone = get_user_timezone(lesson.mentor.timezone or 'UTC')
        if timezone.is_aware(lesson.start_time):
            mentor_local_time = lesson.start_time.astimezone(mentor_timezone)
        else:
            utc_time = timezone.make_aware(lesson.start_time, pytz.UTC)
            mentor_local_time = utc_time.astimezone(mentor_timezone)
        
        mentor_start_time = mentor_local_time.strftime('%d.%m.%Y в %H:%M')
        NotificationService.create_notification_with_telegram(
            recipient=lesson.mentor,
            notification_type='lesson_reminder',
            title='⏰ Напоминание о занятии',
            message=f'Занятие "{lesson.title}" начнется {time_text} ({mentor_start_time})',
            priority='high',
            action_url=f'/schedule?lesson={lesson.id}',
            content_object=lesson
        )
        
        # Отправляем клиенту
        if lesson.client and lesson.client.user:
            from apps.users.utils import get_user_timezone
            client_timezone = get_user_timezone(lesson.client.user.timezone or 'UTC')
            if timezone.is_aware(lesson.start_time):
                client_local_time = lesson.start_time.astimezone(client_timezone)
            else:
                utc_time = timezone.make_aware(lesson.start_time, pytz.UTC)
                client_local_time = utc_time.astimezone(client_timezone)
            
            client_start_time = client_local_time.strftime('%d.%m.%Y в %H:%M')
            child_user = lesson.client.user
            child_id = child_user.id
            
            NotificationService.create_notification_with_telegram(
                recipient=child_user,
                notification_type='lesson_reminder',
                title='⏰ Напоминание о занятии',
                message=f'Занятие "{lesson.title}" начнется {time_text} ({client_start_time})',
                priority='high',
                action_url=f'/schedule?lesson={lesson.id}',
                content_object=lesson
            )
            
            # Отправляем уведомление родителям ребенка
            try:
                child_client = lesson.client
                # Оптимизация: используем list() для кеширования запроса
                parents = list(child_client.parents.select_related('user').all())
                
                for parent in parents:
                    if parent.user:
                        NotificationService.create_notification_with_telegram(
                            recipient=parent.user,
                            notification_type='lesson_reminder',
                            title='⏰ Напоминание о занятии для вашего ребенка',
                            message=f'{child_user.get_full_name() or child_user.email}: Занятие "{lesson.title}" начнется {time_text} ({client_start_time})',
                            priority='high',
                            action_url=f'/schedule?lesson={lesson.id}',
                            content_object=lesson,
                            child_id=child_id,
                            data={'child_id': child_id}
                        )
            except Exception as e:
                logger.warning(f'Error sending reminder notification to parents for lesson {lesson.id}: {e}')
    
    @staticmethod
    def _pluralize_days(count):
        """Склонение слова 'день'."""
        if count % 10 == 1 and count % 100 != 11:
            return 'день'
        elif 2 <= count % 10 <= 4 and (count % 100 < 10 or count % 100 >= 20):
            return 'дня'
        else:
            return 'дней'
    
    @staticmethod
    def _pluralize_hours(count):
        """Склонение слова 'час'."""
        if count % 10 == 1 and count % 100 != 11:
            return 'час'
        elif 2 <= count % 10 <= 4 and (count % 100 < 10 or count % 100 >= 20):
            return 'часа'
        else:
            return 'часов'
    
    @staticmethod
    def _pluralize_minutes(count):
        """Склонение слова 'минута'."""
        if count % 10 == 1 and count % 100 != 11:
            return 'минуту'
        elif 2 <= count % 10 <= 4 and (count % 100 < 10 or count % 100 >= 20):
            return 'минуты'
        else:
            return 'минут'
    
    @staticmethod
    def send_homework_notification(homework, notification_type='homework_assigned', student=None, submission=None):
        """
        Отправка уведомления о домашнем задании.
        
        Args:
            homework: Объект домашнего задания
            notification_type: Тип уведомления
            student: Студент (для homework_submitted и homework_reviewed)
            submission: Объект решения (для homework_reviewed)
        """
        if notification_type == 'homework_assigned':
            # Уведомление всем назначенным ученикам о новом ДЗ
            recipients = homework.assigned_to.all()
            title = '📝 Новое домашнее задание'
            lesson_title = homework.lesson.title if homework.lesson else homework.title
            message = f'Вам назначено домашнее задание по занятию "{lesson_title}"'
            
            # Отправляем уведомление каждому назначенному студенту
            for recipient in recipients:
                child_id = recipient.id
                
                NotificationService.create_notification_with_telegram(
                    recipient=recipient,
                    notification_type=notification_type,
                    title=title,
                    message=message,
                    priority='normal',
                    action_url=f'/homework/{homework.id}',
                    content_object=homework
                )
                
                # Отправляем уведомление родителям ребенка
                try:
                    from apps.users.models import Client, Parent
                    child_client = Client.objects.get(user=recipient)
                    parents = child_client.parents.all()
                    
                    for parent in parents:
                        if parent.user:
                            NotificationService.create_notification_with_telegram(
                                recipient=parent.user,
                                notification_type=notification_type,
                                title='📝 Новое домашнее задание для вашего ребенка',
                                message=f'{recipient.get_full_name() or recipient.email}: {message}',
                                priority='normal',
                                action_url=f'/homework/{homework.id}',
                                content_object=homework,
                                child_id=child_id,
                                data={'child_id': child_id}
                            )
                except Exception as e:
                    logger.warning(f'Error sending notification to parents for homework {homework.id}: {e}')
            return
        
        elif notification_type == 'homework_submitted':
            # Уведомление ментору о сданном ДЗ
            if not homework.lesson:
                return
            recipient = homework.lesson.mentor
            student_name = student.get_full_name() if student else 'Ученик'
            title = '📤 Домашнее задание сдано'
            lesson_title = homework.lesson.title if homework.lesson else homework.title
            message = f'{student_name} сдал домашнее задание по занятию "{lesson_title}"'
        
        elif notification_type == 'homework_reviewed':
            # Уведомление ученику о проверенном ДЗ
            if not student:
                return
            recipient = student
            child_id = student.id
            title = '✅ Домашнее задание проверено'
            lesson_title = homework.lesson.title if homework.lesson else homework.title
            message = f'Ваше домашнее задание по занятию "{lesson_title}" проверено'
            
            if submission:
                if hasattr(submission, 'score') and submission.score is not None:
                    max_score = getattr(homework, 'max_score', None)
                    if max_score:
                        message += f'. Оценка: {submission.score}/{max_score}'
                    else:
                        message += f'. Оценка: {submission.score}'
                
                feedback = getattr(submission, 'feedback', None)
                if feedback:
                    import html
                    escaped_feedback = html.escape(feedback)
                    message += f'\n\n💬 <b>Комментарий:</b>\n{escaped_feedback}'
        
        else:
            return
        
        if recipient:
            NotificationService.create_notification_with_telegram(
                recipient=recipient,
                notification_type=notification_type,
                title=title,
                message=message,
                priority='normal',
                action_url=f'/homework/{homework.id}',
                content_object=homework
            )
            
            # Отправляем уведомление родителям ребенка (только для homework_reviewed и homework_submitted)
            if notification_type in ['homework_reviewed', 'homework_submitted'] and recipient.role == 'client':
                try:
                    from apps.users.models import Client, Parent
                    child_client = Client.objects.get(user=recipient)
                    parents = child_client.parents.all()
                    
                    for parent in parents:
                        if parent.user:
                            NotificationService.create_notification_with_telegram(
                                recipient=parent.user,
                                notification_type=notification_type,
                                title=f'{title} для вашего ребенка',
                                message=f'{recipient.get_full_name() or recipient.email}: {message}',
                                priority='normal',
                                action_url=f'/homework/{homework.id}',
                                content_object=homework,
                                child_id=child_id,
                                data={'child_id': child_id}
                            )
                except Exception as e:
                    logger.warning(f'Error sending notification to parents for homework {homework.id}: {e}')
    
    @staticmethod
    def send_attendance_confirmation_request(lesson):
        """
        Отправка запроса о подтверждении присутствия студенту.
        
        Args:
            lesson: Объект занятия
        """
        from django.utils import timezone
        import pytz
        
        if not lesson.client or not lesson.client.user:
            return
        
        student = lesson.client.user
        
        # Используем часовой пояс пользователя
        from apps.users.utils import get_user_timezone
        user_timezone = get_user_timezone(student.timezone or 'UTC')
        if timezone.is_aware(lesson.start_time):
            local_time = lesson.start_time.astimezone(user_timezone)
        else:
            utc_time = timezone.make_aware(lesson.start_time, pytz.UTC)
            local_time = utc_time.astimezone(user_timezone)
        
        start_time = local_time.strftime('%d.%m.%Y в %H:%M')
        
        # Создаем in-app уведомление и отправляем email
        from .models import Notification
        from .tasks import send_notification_task
        
        # Создаем in-app уведомление
        notification = Notification.create_notification(
            recipient=student,
            notification_type='lesson_reminder',  # Используем существующий тип
            title='❓ Подтверждение присутствия',
            message=f'Будете ли вы присутствовать на занятии "{lesson.title}" {start_time}?',
            channel='in_app',
            priority='high',
            action_url=f'/schedule?lesson={lesson.id}',
            content_object=lesson,
            data={
                'lesson_id': lesson.id,
                'requires_attendance_confirmation': True,
                'attendance_yes_url': f'/api/schedule/lessons/{lesson.id}/confirm-attendance/?response=yes',
                'attendance_no_url': f'/api/schedule/lessons/{lesson.id}/confirm-attendance/?response=no',
            }
        )
        
        # Отправляем email уведомление, если включено
        try:
            preferences = student.notification_preferences
            email_enabled = preferences.is_type_enabled('lesson_reminder', 'email')
        except:
            email_enabled = bool(student.email)
        
        if email_enabled and student.email:
            email_notification = Notification.create_notification(
                recipient=student,
                notification_type='lesson_reminder',
                title='❓ Подтверждение присутствия',
                message=f'Будете ли вы присутствовать на занятии "{lesson.title}" {start_time}?',
                channel='email',
                priority='high',
                action_url=f'/schedule?lesson={lesson.id}',
                content_object=lesson,
            )
            send_notification_task.delay(email_notification.id)
        
        # Отправляем также в Telegram с кнопками
        if student.telegram_id:
            try:
                preferences = student.notification_preferences
                telegram_enabled = preferences.is_type_enabled('lesson_reminder', 'telegram')
            except:
                telegram_enabled = True
            
            if telegram_enabled:
                from telegram import InlineKeyboardButton, InlineKeyboardMarkup
                from .telegram_bot import send_telegram_message_with_buttons
                import asyncio
                
                keyboard = [
                    [
                        InlineKeyboardButton("✅ Да, буду", callback_data=f"attendance_yes_{lesson.id}"),
                        InlineKeyboardButton("❌ Нет, не смогу", callback_data=f"attendance_no_{lesson.id}")
                    ]
                ]
                reply_markup = InlineKeyboardMarkup(keyboard)
                
                message_text = (
                    f"❓ <b>Подтверждение присутствия</b>\n\n"
                    f"Будете ли вы присутствовать на занятии:\n"
                    f"<b>{lesson.title}</b>\n"
                    f"📅 {start_time}"
                )
                
                # Отправляем сообщение с кнопками напрямую
                try:
                    # Запускаем асинхронную отправку
                    loop = asyncio.new_event_loop()
                    asyncio.set_event_loop(loop)
                    success = loop.run_until_complete(
                        send_telegram_message_with_buttons(
                            student.telegram_id,
                            message_text,
                            reply_markup
                        )
                    )
                    loop.close()
                except Exception as e:
                    logger.error(f'Error sending Telegram message with buttons: {e}')
                    success = False
    
    @staticmethod
    def send_attendance_response_to_mentor(lesson, response):
        """
        Отправка уведомления ментору о ответе студента на запрос о присутствии.
        
        Args:
            lesson: Объект занятия
            response: True если будет присутствовать, False если нет
        """
        if not lesson.mentor:
            return
        
        student_name = lesson.client.user.get_full_name() if lesson.client and lesson.client.user else 'Студент'
        response_text = "будет присутствовать" if response else "не сможет присутствовать"
        
        NotificationService.create_notification_with_telegram(
            recipient=lesson.mentor,
            notification_type='lesson_reminder',
            title='📢 Ответ о присутствии',
            message=f'{student_name} {response_text} на занятии "{lesson.title}"',
            priority='normal',
            action_url=f'/schedule?lesson={lesson.id}',
            content_object=lesson
        )
    
    @staticmethod
    def send_message_notification(message):
        """
        Отправка уведомлений о новом сообщении всем участникам чата, кроме отправителя.
        
        Args:
            message: Экземпляр Message
        """
        from .models import Notification
        
        chat = message.chat
        sender = message.sender
        
        # Получаем всех участников чата, кроме отправителя
        participants = chat.participants.exclude(user=sender).select_related('user')
        
        # Формируем имя отправителя
        sender_name = sender.get_full_name() if sender else 'Система'
        
        # Обрезаем сообщение для уведомления
        content_preview = ''
        if message.content:
            content_preview = message.content[:100]
            if len(message.content) > 100:
                content_preview += '...'
        
        # Определяем заголовок в зависимости от типа чата
        if chat.chat_type == 'direct':
            title = f'💬 Новое сообщение от {sender_name}'
        else:
            title = f'💬 {sender_name} в чате "{chat.name or "Групповой чат"}"'
        
        # Создаем уведомления для каждого участника
        for participant in participants:
            # Пропускаем если уведомления отключены
            if participant.is_muted:
                continue
            
            NotificationService.create_notification_with_telegram(
                recipient=participant.user,
                notification_type='message_received',
                title=title,
                message=content_preview or 'Новое сообщение',
                priority='normal',
                action_url=f'/chat?chat={chat.uuid}',
                content_object=message
            )


def create_notification_preferences(user):
    """
    Создание настроек уведомлений для пользователя.
    
    Args:
        user: Пользователь
    """
    from .models import NotificationPreference
    
    try:
        NotificationPreference.objects.get_or_create(
            user=user,
            defaults={
                'enabled': True,
                'email_enabled': True,
                'telegram_enabled': bool(user.telegram_id),
                'in_app_enabled': True,
            }
        )
    except Exception as e:
        logger.error(f"Error creating notification preferences: {e}")


class WebSocketNotificationService:
    """Сервис для отправки уведомлений через WebSocket."""
    
    @staticmethod
    def send_notification_via_websocket(notification):
        """
        Отправка уведомления через WebSocket в реальном времени.
        
        Args:
            notification: Объект Notification
        """
        try:
            channel_layer = get_channel_layer()
            if not channel_layer:
                logger.warning("Channel layer not available, skipping WebSocket notification")
                return
            
            from .serializers import NotificationSerializer
            from .models import Notification
            
            # Сериализуем уведомление
            serializer = NotificationSerializer(notification)
            notification_data = serializer.data
            
            # Группа пользователя для уведомлений
            user_group_name = f'notifications_user_{notification.recipient.id}'
            
            # Получаем количество непрочитанных уведомлений
            unread_count = Notification.objects.filter(
                recipient=notification.recipient,
                channel='in_app',
                is_read=False
            ).count()
            
            # Отправляем через channel_layer
            async_to_sync(channel_layer.group_send)(
                user_group_name,
                {
                    'type': 'notification_created',
                    'notification': notification_data,
                    'unread_count': unread_count
                }
            )
            
            logger.info(f"WebSocket notification sent to user {notification.recipient.id} (unread: {unread_count})")
            
        except Exception as e:
            logger.error(f"Error sending WebSocket notification: {e}", exc_info=True)

    @staticmethod
    def send_nav_badges_updated(user_id):
        """
        Уведомить пользователя об изменении бейджей нижнего меню (чат, расписание, ДЗ и т.д.).
        Клиент по событию nav_badges_updated перезапросит GET /api/nav-badges/.
        """
        try:
            channel_layer = get_channel_layer()
            if not channel_layer:
                return
            user_group_name = f'notifications_user_{user_id}'
            async_to_sync(channel_layer.group_send)(
                user_group_name,
                {'type': 'nav_badges_updated'},
            )
        except Exception as e:
            logger.debug("send_nav_badges_updated: %s", e)
