"""API для работы с профилями."""

from typing import Optional, TYPE_CHECKING

from .models import Profile
from .exceptions import NotFoundError, APIError

if TYPE_CHECKING:
    from .client import AmnezioClient


class ProfilesAPI:
    """API для работы с профилями."""
    
    def __init__(self, client: "AmnezioClient"):
        self.client = client
    
    async def list(self) -> list[Profile]:
        """
        Получить список профилей.
        
        Returns:
            Список профилей
        """
        response = await self.client.request("GET", "/api/profiles")
        
        if response.status_code != 200:
            raise APIError(response.status_code, response.text)
        
        return [Profile(**item) for item in response.json()]
    
    async def create(
        self,
        name: str,
        subdomain: Optional[str] = None,
        listen_port: int = 51820,
        dns: str = "1.1.1.1",
        mtu: int = 1420,
        persistent_keepalive: int = 25,
        junk_packet_count: int = 4,
        junk_packet_min_size: int = 40,
        junk_packet_max_size: int = 70,
        init_packet_junk_size: int = 0,
        response_packet_junk_size: int = 0,
        underload_packet_junk_size: int = 0,
        transport_packet_junk_size: int = 0,
        init_packet_magic_header: int = 0,
        response_packet_magic_header: int = 0,
        underload_packet_magic_header: int = 0,
        transport_packet_magic_header: int = 0,
    ) -> Profile:
        """
        Создать профиль.
        
        Args:
            name: Название профиля
            subdomain: Поддомен (опционально)
            listen_port: Порт прослушивания
            dns: DNS сервер
            mtu: MTU
            persistent_keepalive: Keepalive интервал
            junk_packet_count: Количество junk пакетов
            junk_packet_min_size: Минимальный размер junk пакета
            junk_packet_max_size: Максимальный размер junk пакета
            init_packet_junk_size: Размер junk для init пакета
            response_packet_junk_size: Размер junk для response пакета
            underload_packet_junk_size: Размер junk для underload пакета
            transport_packet_junk_size: Размер junk для transport пакета
            init_packet_magic_header: Magic header для init пакета
            response_packet_magic_header: Magic header для response пакета
            underload_packet_magic_header: Magic header для underload пакета
            transport_packet_magic_header: Magic header для transport пакета
        
        Returns:
            Созданный профиль
        """
        data = {
            "name": name,
            "listen_port": listen_port,
            "dns": dns,
            "mtu": mtu,
            "persistent_keepalive": persistent_keepalive,
            "junk_packet_count": junk_packet_count,
            "junk_packet_min_size": junk_packet_min_size,
            "junk_packet_max_size": junk_packet_max_size,
            "init_packet_junk_size": init_packet_junk_size,
            "response_packet_junk_size": response_packet_junk_size,
            "underload_packet_junk_size": underload_packet_junk_size,
            "transport_packet_junk_size": transport_packet_junk_size,
            "init_packet_magic_header": init_packet_magic_header,
            "response_packet_magic_header": response_packet_magic_header,
            "underload_packet_magic_header": underload_packet_magic_header,
            "transport_packet_magic_header": transport_packet_magic_header,
        }
        
        if subdomain:
            data["subdomain"] = subdomain
        
        response = await self.client.request("POST", "/api/profiles", json=data)
        
        if response.status_code != 200:
            raise APIError(response.status_code, response.text)
        
        return Profile(**response.json())
    
    async def get(self, profile_id: int) -> Profile:
        """
        Получить профиль по ID.
        
        Args:
            profile_id: ID профиля
        
        Returns:
            Профиль
        """
        response = await self.client.request("GET", f"/api/profiles/{profile_id}")
        
        if response.status_code == 404:
            raise NotFoundError(f"Профиль {profile_id} не найден")
        
        if response.status_code != 200:
            raise APIError(response.status_code, response.text)
        
        return Profile(**response.json())
    
    async def update(
        self,
        profile_id: int,
        **kwargs
    ) -> Profile:
        """
        Обновить профиль.
        
        Args:
            profile_id: ID профиля
            **kwargs: Поля для обновления
        
        Returns:
            Обновленный профиль
        """
        # Убираем None значения
        data = {k: v for k, v in kwargs.items() if v is not None}
        
        response = await self.client.request("PUT", f"/api/profiles/{profile_id}", json=data)
        
        if response.status_code == 404:
            raise NotFoundError(f"Профиль {profile_id} не найден")
        
        if response.status_code != 200:
            raise APIError(response.status_code, response.text)
        
        return Profile(**response.json())
    
    async def delete(self, profile_id: int) -> dict:
        """
        Удалить профиль.
        
        Args:
            profile_id: ID профиля
        
        Returns:
            Статус операции
        """
        response = await self.client.request("DELETE", f"/api/profiles/{profile_id}")
        
        if response.status_code == 404:
            raise NotFoundError(f"Профиль {profile_id} не найден")
        
        if response.status_code != 200:
            raise APIError(response.status_code, response.text)
        
        return response.json()
