"""
Сервисы для системы чата.
Централизованная логика создания и управления чатами.
"""
from django.db import transaction
from django.db.models import Q
from .models import Chat, ChatParticipant


class ChatService:
    """
    Сервис для работы с чатами.
    Обеспечивает атомарность операций и предотвращает создание дубликатов.
    """
    
    @staticmethod
    def get_or_create_direct_chat(user1, user2, created_by=None):
        """
        Получить или создать личный чат между двумя пользователями.
        
        Использует блокировку для предотвращения race condition
        при одновременных запросах на создание чата.
        
        Args:
            user1: Первый пользователь (User)
            user2: Второй пользователь (User)
            created_by: Кто создает чат (по умолчанию user1)
        
        Returns:
            tuple: (chat, created) - объект чата и флаг создания
        """
        if user1.id == user2.id:
            raise ValueError("Нельзя создать чат с самим собой")
        
        # Нормализуем порядок пользователей для консистентного поиска
        users = sorted([user1, user2], key=lambda u: u.id)
        
        with transaction.atomic():
            # Ищем существующий чат между пользователями
            # Используем select_for_update для блокировки найденных записей
            existing_chat = Chat.objects.select_for_update().filter(
                chat_type='direct',
                participants__user=users[0]
            ).filter(
                participants__user=users[1]
            ).distinct().first()
            
            if existing_chat:
                return existing_chat, False
            
            # Чата нет - создаем новый
            creator = created_by or users[0]
            chat = Chat.objects.create(
                chat_type='direct',
                created_by=creator
            )
            
            # Определяем роли участников
            # Создатель становится админом
            ChatParticipant.objects.create(
                chat=chat,
                user=users[0],
                role='admin' if users[0] == creator else 'member'
            )
            
            ChatParticipant.objects.create(
                chat=chat,
                user=users[1],
                role='admin' if users[1] == creator else 'member'
            )
            
            return chat, True
    
    @staticmethod
    def get_direct_chat(user1, user2):
        """
        Получить существующий личный чат между двумя пользователями.
        
        Args:
            user1: Первый пользователь
            user2: Второй пользователь
        
        Returns:
            Chat или None
        """
        return Chat.objects.filter(
            chat_type='direct',
            participants__user=user1
        ).filter(
            participants__user=user2
        ).distinct().first()
    
    @staticmethod
    def ensure_participant(chat, user, role='member'):
        """
        Убедиться что пользователь является участником чата.
        Если нет - добавить его.
        
        Args:
            chat: Чат
            user: Пользователь
            role: Роль (по умолчанию 'member')
        
        Returns:
            tuple: (participant, created)
        """
        return ChatParticipant.objects.get_or_create(
            chat=chat,
            user=user,
            defaults={'role': role}
        )
