"""
Python клиент для взаимодействия с sfu-server (ion-sfu).
"""
import logging
import requests
from typing import Optional, Dict, List, Any
from django.conf import settings

logger = logging.getLogger(__name__)


class SFUClientError(Exception):
    """Ошибка при работе с SFU сервером."""
    pass


class SFUClient:
    """
    Клиент для взаимодействия с sfu-server через HTTP API.
    
    Используется для управления видеокомнатами на стороне Django.
    """
    
    def __init__(self, base_url: Optional[str] = None):
        """
        Инициализация клиента.
        
        Args:
            base_url: Базовый URL sfu-server (по умолчанию из настроек)
        """
        self.base_url = base_url or getattr(
            settings,
            'SFU_SERVER_URL',
            'http://sfu-server:7001'
        )
        self.timeout = getattr(settings, 'SFU_CLIENT_TIMEOUT', 10)
        
    def _request(
        self,
        method: str,
        endpoint: str,
        data: Optional[Dict] = None,
        params: Optional[Dict] = None
    ) -> Dict[str, Any]:
        """
        Выполнение HTTP запроса к sfu-server.
        
        Args:
            method: HTTP метод (GET, POST, DELETE)
            endpoint: Endpoint API
            data: Данные для отправки
            params: Query параметры
            
        Returns:
            Ответ от сервера в виде словаря
            
        Raises:
            SFUClientError: При ошибке запроса
        """
        url = f"{self.base_url}{endpoint}"
        
        try:
            response = requests.request(
                method=method,
                url=url,
                json=data,
                params=params,
                timeout=self.timeout,
                headers={'Content-Type': 'application/json'}
            )
            
            # Проверка статуса ответа
            if not response.ok:
                error_msg = f"SFU server error: {response.status_code}"
                try:
                    error_data = response.json()
                    error_msg = error_data.get('error', error_msg)
                except:
                    error_msg = f"{error_msg} - {response.text}"
                
                logger.error(f"SFU request failed: {method} {url} - {error_msg}")
                raise SFUClientError(error_msg)
            
            # Парсинг ответа
            try:
                return response.json()
            except ValueError:
                return {'status': 'ok'}
                
        except requests.exceptions.RequestException as e:
            error_msg = f"Failed to connect to SFU server: {str(e)}"
            logger.error(f"SFU connection error: {error_msg}")
            raise SFUClientError(error_msg)
    
    def create_room(self, room_id: str) -> Dict[str, Any]:
        """
        Создать видеокомнату в sfu-server.
        
        Args:
            room_id: Уникальный ID комнаты (обычно UUID из VideoRoom)
            
        Returns:
            Информация о созданной комнате
            
        Example:
            >>> client = SFUClient()
            >>> result = client.create_room('123e4567-e89b-12d3-a456-426614174000')
            >>> print(result)
            {'room_id': '123e4567-e89b-12d3-a456-426614174000', 'status': 'created'}
        """
        try:
            response = self._request('POST', f'/api/rooms/{room_id}/create')
            logger.info(f"Room {room_id} created in SFU server")
            return response
        except SFUClientError:
            raise
        except Exception as e:
            logger.error(f"Unexpected error creating room {room_id}: {e}")
            raise SFUClientError(f"Failed to create room: {str(e)}")
    
    def get_room(self, room_id: str) -> Dict[str, Any]:
        """
        Получить информацию о видеокомнате.
        
        Args:
            room_id: ID комнаты
            
        Returns:
            Информация о комнате (room_id, peers_count, status)
            
        Example:
            >>> client = SFUClient()
            >>> room = client.get_room('123e4567-e89b-12d3-a456-426614174000')
            >>> print(room)
            {'room_id': '...', 'peers_count': 2, 'status': 'active'}
        """
        try:
            response = self._request('GET', f'/api/rooms/{room_id}')
            return response
        except SFUClientError:
            raise
        except Exception as e:
            logger.error(f"Unexpected error getting room {room_id}: {e}")
            raise SFUClientError(f"Failed to get room: {str(e)}")
    
    def delete_room(self, room_id: str) -> Dict[str, Any]:
        """
        Удалить видеокомнату из sfu-server.
        
        Args:
            room_id: ID комнаты
            
        Returns:
            Подтверждение удаления
            
        Example:
            >>> client = SFUClient()
            >>> result = client.delete_room('123e4567-e89b-12d3-a456-426614174000')
            >>> print(result)
            {'room_id': '...', 'status': 'deleted'}
        """
        try:
            response = self._request('DELETE', f'/api/rooms/{room_id}')
            logger.info(f"Room {room_id} deleted from SFU server")
            return response
        except SFUClientError:
            raise
        except Exception as e:
            logger.error(f"Unexpected error deleting room {room_id}: {e}")
            raise SFUClientError(f"Failed to delete room: {str(e)}")
    
    def list_rooms(self) -> List[Dict[str, Any]]:
        """
        Получить список всех активных комнат.
        
        Returns:
            Список комнат с информацией о каждой
            
        Example:
            >>> client = SFUClient()
            >>> rooms = client.list_rooms()
            >>> print(rooms)
            [{'room_id': '...', 'peers_count': 2, 'status': 'active'}, ...]
        """
        try:
            response = self._request('GET', '/api/rooms')
            return response.get('rooms', [])
        except SFUClientError:
            raise
        except Exception as e:
            logger.error(f"Unexpected error listing rooms: {e}")
            raise SFUClientError(f"Failed to list rooms: {str(e)}")
    
    def health_check(self) -> bool:
        """
        Проверить доступность sfu-server.
        
        Returns:
            True если сервер доступен, False иначе
        """
        try:
            response = self._request('GET', '/health')
            return response.get('status') == 'ok'
        except Exception as e:
            logger.warning(f"SFU health check failed: {e}")
            return False


# Singleton экземпляр клиента
_sfu_client: Optional[SFUClient] = None


def get_sfu_client() -> SFUClient:
    """
    Получить singleton экземпляр SFU клиента.
    
    Returns:
        Экземпляр SFUClient
    """
    global _sfu_client
    if _sfu_client is None:
        _sfu_client = SFUClient()
    return _sfu_client

