"""
API views для видеоконференций.
"""
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.shortcuts import get_object_or_404
from django.utils import timezone
from .models import VideoRoom, VideoParticipant, VideoCallLog, ScreenRecording
from .serializers import (
    VideoRoomSerializer,
    VideoRoomCreateSerializer,
    VideoRoomStartSerializer,
    VideoRoomEndSerializer,
    VideoParticipantSerializer,
    VideoCallLogSerializer,
    ScreenRecordingSerializer,
    ScreenRecordingCreateSerializer
)
from .permissions import IsVideoRoomParticipant
from .services import get_sfu_client, SFUClientError
import logging

logger = logging.getLogger(__name__)


class VideoRoomViewSet(viewsets.ModelViewSet):
    """
    ViewSet для управления видеокомнатами.
    
    list: Список видеокомнат пользователя
    create: Создать видеокомнату
    retrieve: Получить информацию о комнате
    update: Обновить комнату
    destroy: Удалить комнату
    start: Начать видеозвонок
    end: Завершить видеозвонок
    join: Присоединиться к комнате
    """
    
    permission_classes = [IsAuthenticated]
    lookup_field = 'room_id'
    
    def get_queryset(self):
        """Получение комнат пользователя."""
        user = self.request.user
        
        if user.role == 'mentor':
            queryset = VideoRoom.objects.filter(mentor=user).select_related(
                'lesson', 'mentor', 'client', 'client__user'
            ).prefetch_related('participants__user')
        else:
            queryset = VideoRoom.objects.filter(
                participants__user=user
            ).select_related(
                'lesson', 'mentor', 'client', 'client__user'
            ).prefetch_related('participants__user').distinct()
        
        # Оптимизация: для списка используем only() для ограничения полей
        if self.action == 'list':
            queryset = queryset.only(
                'id', 'room_id', 'lesson_id', 'mentor_id', 'client_id',
                'status', 'started_at', 'ended_at', 'duration', 'is_recording',
                'recording_url', 'quality_rating', 'quality_issues', 'created_at'
            )
        
        return queryset.order_by('-created_at')
    
    def get_serializer_class(self):
        """Выбор сериализатора."""
        if self.action == 'create':
            return VideoRoomCreateSerializer
        elif self.action == 'start':
            return VideoRoomStartSerializer
        elif self.action == 'end':
            return VideoRoomEndSerializer
        return VideoRoomSerializer
    
    def create(self, request, *args, **kwargs):
        """Создание видеокомнаты."""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        video_room = serializer.save()
        
        # Создаем комнату в sfu-server
        sfu_client = get_sfu_client()
        try:
            sfu_client.create_room(str(video_room.room_id))
            logger.info(f"Video room {video_room.room_id} created in SFU server")
        except SFUClientError as e:
            logger.error(f"Failed to create room in SFU server: {e}")
            # Не прерываем создание комнаты в Django, но логируем ошибку
            # Комната будет создана в Django, но может не работать в SFU
        
        # Возвращаем полную информацию о комнате
        response_serializer = VideoRoomSerializer(video_room)
        return Response(
            response_serializer.data,
            status=status.HTTP_201_CREATED
        )
    
    def destroy(self, request, *args, **kwargs):
        """Удаление видеокомнаты."""
        room = self.get_object()
        room_id = str(room.room_id)
        
        # Удаляем комнату из sfu-server
        sfu_client = get_sfu_client()
        try:
            sfu_client.delete_room(room_id)
            logger.info(f"Video room {room_id} deleted from SFU server")
        except SFUClientError as e:
            logger.error(f"Failed to delete room from SFU server: {e}")
            # Продолжаем удаление из Django даже если SFU недоступен
        
        # Удаляем комнату из Django
        return super().destroy(request, *args, **kwargs)
    
    @action(detail=True, methods=['post'])
    def start(self, request, room_id=None):
        """
        Начать видеозвонок.
        
        POST /api/video/rooms/{room_id}/start/
        """
        room = self.get_object()
        
        # Проверяем права (оптимизация: проверяем client.user если есть)
        client_user = room.client.user if hasattr(room.client, 'user') else room.client
        if request.user not in [room.mentor, client_user]:
            return Response(
                {'error': 'У вас нет доступа к этой комнате'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        serializer = self.get_serializer(room, data={})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        
        response_serializer = VideoRoomSerializer(room)
        return Response(response_serializer.data)
    
    @action(detail=True, methods=['post'])
    def end(self, request, room_id=None):
        """
        Завершить видеозвонок.
        
        POST /api/video/rooms/{room_id}/end/
        Body: {
            "quality_rating": 5,  // опционально
            "quality_issues": ""  // опционально
        }
        """
        room = self.get_object()
        
        # Проверяем права (может завершить только ментор)
        if request.user != room.mentor:
            return Response(
                {'error': 'Только ментор может завершить звонок'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        serializer = self.get_serializer(room, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        
        response_serializer = VideoRoomSerializer(room)
        return Response(response_serializer.data)
    
    @action(detail=True, methods=['get'])
    def join(self, request, room_id=None):
        """
        Получить информацию для присоединения к комнате.
        
        GET /api/video/rooms/{room_id}/join/
        
        Возвращает:
        - room_id: UUID комнаты
        - ws_url: WebSocket URL для подключения
        - ice_servers: STUN/TURN серверы
        - participant_info: информация об участнике
        """
        room = self.get_object()
        
        # Проверяем права (оптимизация: проверяем client.user если есть)
        client_user = room.client.user if hasattr(room.client, 'user') else room.client
        if request.user not in [room.mentor, client_user]:
            return Response(
                {'error': 'У вас нет доступа к этой комнате'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        # Получаем или создаем участника
        participant, created = VideoParticipant.objects.get_or_create(
            room=room,
            user=request.user,
            defaults={'is_connected': False}
        )
        
        # Убеждаемся, что комната существует в sfu-server
        sfu_client = get_sfu_client()
        try:
            # Проверяем, существует ли комната
            sfu_client.get_room(str(room.room_id))
        except SFUClientError:
            # Комната не существует, создаем её
            try:
                sfu_client.create_room(str(room.room_id))
                logger.info(f"Video room {room.room_id} created in SFU server during join")
            except SFUClientError as e:
                logger.error(f"Failed to create room in SFU server during join: {e}")
                return Response(
                    {'error': 'Не удалось создать комнату в SFU сервере'},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        
        # WebSocket URL для sfu-server
        from django.conf import settings
        sfu_ws_url = getattr(settings, 'SFU_WS_URL', 'ws://sfu-server:7001')
        # Заменяем внутренний адрес на внешний для клиента
        if 'sfu-server' in sfu_ws_url:
            # В production нужно использовать правильный внешний адрес
            sfu_ws_url = sfu_ws_url.replace('sfu-server', 'localhost')
        
        ws_url = f"{sfu_ws_url}/ws/{room.room_id}"
        
        # ICE серверы (STUN/TURN)
        ice_servers = [
            {
                'urls': 'stun:stun.l.google.com:19302'
            },
            {
                'urls': 'stun:stun1.l.google.com:19302'
            }
        ]
        
        return Response({
            'room_id': str(room.room_id),
            'ws_url': ws_url,
            'ice_servers': ice_servers,
            'participant_info': VideoParticipantSerializer(participant).data,
            'room_info': VideoRoomSerializer(room).data
        })
    
    @action(detail=False, methods=['get'])
    def active(self, request):
        """
        Получить список активных комнат пользователя.
        
        GET /api/video/rooms/active/
        """
        queryset = self.get_queryset().filter(status='active')
        serializer = VideoRoomSerializer(queryset, many=True)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def history(self, request):
        """
        Получить историю видеозвонков.
        
        GET /api/video/rooms/history/
        """
        queryset = self.get_queryset().filter(status='ended').order_by('-ended_at')
        
        # Пагинация
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = VideoRoomSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        
        serializer = VideoRoomSerializer(queryset, many=True)
        return Response(serializer.data)


class VideoParticipantViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet для просмотра участников видео.
    
    list: Список участников
    retrieve: Информация об участнике
    """
    
    serializer_class = VideoParticipantSerializer
    permission_classes = [IsAuthenticated, IsVideoRoomParticipant]
    
    def get_queryset(self):
        """Получение участников."""
        user = self.request.user
        
        # Оптимизация: получаем только ID комнат для фильтрации
        if user.role == 'mentor':
            room_ids = VideoRoom.objects.filter(mentor=user).values_list('id', flat=True)
        else:
            room_ids = VideoRoom.objects.filter(client=user).values_list('id', flat=True)
        
        queryset = VideoParticipant.objects.filter(
            room_id__in=room_ids
        ).select_related('user', 'room', 'room__mentor', 'room__client')
        
        # Оптимизация: для списка используем only() для ограничения полей
        if self.action == 'list':
            queryset = queryset.only(
                'id', 'room_id', 'user_id', 'is_connected', 'is_audio_enabled',
                'is_video_enabled', 'is_screen_sharing', 'joined_at', 'left_at',
                'reconnection_count', 'created_at', 'updated_at'
            )
        
        return queryset


class VideoCallLogViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet для просмотра логов видеозвонков.
    
    list: Список логов
    retrieve: Детали лога
    """
    
    serializer_class = VideoCallLogSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """Получение логов."""
        user = self.request.user
        
        # Оптимизация: получаем только ID комнат для фильтрации
        if user.role == 'mentor':
            room_ids = VideoRoom.objects.filter(mentor=user).values_list('id', flat=True)
        else:
            room_ids = VideoRoom.objects.filter(client=user).values_list('id', flat=True)
        
        queryset = VideoCallLog.objects.filter(
            room_id__in=room_ids
        ).select_related('room', 'room__lesson', 'room__mentor', 'room__client', 'room__client__user')
        
        # Оптимизация: для списка используем only() для ограничения полей
        if self.action == 'list':
            queryset = queryset.only(
                'id', 'room_id', 'call_duration', 'quality_rating', 'quality_issues',
                'participants_count', 'created_at', 'updated_at'
            )
        
        return queryset.order_by('-created_at')


class ScreenRecordingViewSet(viewsets.ModelViewSet):
    """
    ViewSet для управления записями видео.
    
    list: Список записей
    create: Начать запись
    retrieve: Получить запись
    update: Обновить запись
    destroy: Удалить запись
    """
    
    serializer_class = ScreenRecordingSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """Получение записей."""
        user = self.request.user
        
        # Оптимизация: получаем только ID комнат для фильтрации
        if user.role == 'mentor':
            room_ids = VideoRoom.objects.filter(mentor=user).values_list('id', flat=True)
        else:
            room_ids = VideoRoom.objects.filter(client=user).values_list('id', flat=True)
        
        queryset = ScreenRecording.objects.filter(
            room_id__in=room_ids
        ).select_related('room', 'room__lesson', 'room__mentor', 'room__client')
        
        # Оптимизация: для списка используем only() для ограничения полей
        if self.action == 'list':
            queryset = queryset.only(
                'id', 'room_id', 'file_path', 'file_size', 'duration', 'status',
                'started_at', 'ended_at', 'created_at', 'updated_at'
            )
        
        return queryset.order_by('-created_at')
    
    def get_serializer_class(self):
        """Выбор сериализатора."""
        if self.action == 'create':
            return ScreenRecordingCreateSerializer
        return ScreenRecordingSerializer
    
    def create(self, request, *args, **kwargs):
        """Начать запись."""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        recording = serializer.save()
        
        # Возвращаем полную информацию
        response_serializer = ScreenRecordingSerializer(recording)
        return Response(
            response_serializer.data,
            status=status.HTTP_201_CREATED
        )
    
    @action(detail=False, methods=['get'])
    def available(self, request):
        """
        Получить доступные записи (готовые и не истекшие).
        
        GET /api/video/recordings/available/
        """
        queryset = self.get_queryset().filter(
            status='ready'
        ).exclude(
            expires_at__lt=timezone.now()
        )
        
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
