"""Proxy rotation domain — sync and async mixins."""

from __future__ import annotations

from typing import Any

from ...exceptions import api_error_handler, async_api_error_handler
from ..._api.generated.proxies.proxies__api__proxies.models import (
    Proxy,
    PaginatedProxyRotationList,
    ProxyRotation,
    ProxyRotationRequest,
    PatchedProxyRotationRequest,
)
from ._utils import normalize_countries, normalize_providers


class _RotationsMixin:
    """Sync rotation methods."""

    _api: Any

    @api_error_handler
    def list_rotations(
        self,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedProxyRotationList:
        """List rotation configurations."""
        return self._api.rotations_list(page=page, page_size=page_size, search=search, ordering=ordering)

    @api_error_handler
    def get_rotation(self, rotation_id: str) -> ProxyRotation:
        """Get rotation details."""
        return self._api.rotations_retrieve(rotation_id)

    @api_error_handler
    def create_rotation(
        self,
        *,
        name: str,
        parser_ids: dict[str, Any] | None = None,
        rotation_interval_minutes: int | None = None,
        max_requests_per_proxy: int | None = None,
        max_errors_per_proxy: int | None = None,
        allowed_countries: list[str] | dict[str, Any] | None = None,
        allowed_providers: list[str] | dict[str, Any] | None = None,
        min_success_rate: float | None = None,
        max_response_time_ms: int | None = None,
        is_active: bool | None = None,
    ) -> ProxyRotation:
        """Create a rotation configuration."""
        request = ProxyRotationRequest(
            name=name,
            parser_ids=parser_ids,
            rotation_interval_minutes=rotation_interval_minutes,
            max_requests_per_proxy=max_requests_per_proxy,
            max_errors_per_proxy=max_errors_per_proxy,
            allowed_countries=normalize_countries(allowed_countries),
            allowed_providers=normalize_providers(allowed_providers),
            min_success_rate=min_success_rate,
            max_response_time_ms=max_response_time_ms,
            is_active=is_active,
        )
        return self._api.rotations_create(request)

    @api_error_handler
    def update_rotation(
        self,
        rotation_id: str,
        *,
        name: str | None = None,
        parser_ids: dict[str, Any] | None = None,
        rotation_interval_minutes: int | None = None,
        max_requests_per_proxy: int | None = None,
        max_errors_per_proxy: int | None = None,
        allowed_countries: list[str] | dict[str, Any] | None = None,
        allowed_providers: list[str] | dict[str, Any] | None = None,
        min_success_rate: float | None = None,
        max_response_time_ms: int | None = None,
        is_active: bool | None = None,
    ) -> ProxyRotation:
        """Update a rotation configuration (partial update)."""
        request = PatchedProxyRotationRequest(
            name=name,
            parser_ids=parser_ids,
            rotation_interval_minutes=rotation_interval_minutes,
            max_requests_per_proxy=max_requests_per_proxy,
            max_errors_per_proxy=max_errors_per_proxy,
            allowed_countries=normalize_countries(allowed_countries),
            allowed_providers=normalize_providers(allowed_providers),
            min_success_rate=min_success_rate,
            max_response_time_ms=max_response_time_ms,
            is_active=is_active,
        )
        return self._api.rotations_partial_update(rotation_id, request)

    @api_error_handler
    def delete_rotation(self, rotation_id: str) -> bool:
        """Delete a rotation configuration."""
        self._api.rotations_destroy(rotation_id)
        return True

    @api_error_handler
    def get_available_proxies_for_rotation(self, rotation_id: str) -> list[Proxy]:
        """Get proxies matching rotation criteria."""
        return self._api.rotations_available_proxies_retrieve(rotation_id)


class _AsyncRotationsMixin:
    """Async rotation methods."""

    _api: Any

    @async_api_error_handler
    async def list_rotations(
        self,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedProxyRotationList:
        """List rotation configurations."""
        return await self._api.rotations_list(page=page, page_size=page_size, search=search, ordering=ordering)

    @async_api_error_handler
    async def get_rotation(self, rotation_id: str) -> ProxyRotation:
        """Get rotation details."""
        return await self._api.rotations_retrieve(rotation_id)

    @async_api_error_handler
    async def create_rotation(
        self,
        *,
        name: str,
        parser_ids: dict[str, Any] | None = None,
        rotation_interval_minutes: int | None = None,
        max_requests_per_proxy: int | None = None,
        max_errors_per_proxy: int | None = None,
        allowed_countries: list[str] | dict[str, Any] | None = None,
        allowed_providers: list[str] | dict[str, Any] | None = None,
        min_success_rate: float | None = None,
        max_response_time_ms: int | None = None,
        is_active: bool | None = None,
    ) -> ProxyRotation:
        """Create a rotation configuration."""
        request = ProxyRotationRequest(
            name=name,
            parser_ids=parser_ids,
            rotation_interval_minutes=rotation_interval_minutes,
            max_requests_per_proxy=max_requests_per_proxy,
            max_errors_per_proxy=max_errors_per_proxy,
            allowed_countries=normalize_countries(allowed_countries),
            allowed_providers=normalize_providers(allowed_providers),
            min_success_rate=min_success_rate,
            max_response_time_ms=max_response_time_ms,
            is_active=is_active,
        )
        return await self._api.rotations_create(request)

    @async_api_error_handler
    async def update_rotation(
        self,
        rotation_id: str,
        *,
        name: str | None = None,
        parser_ids: dict[str, Any] | None = None,
        rotation_interval_minutes: int | None = None,
        max_requests_per_proxy: int | None = None,
        max_errors_per_proxy: int | None = None,
        allowed_countries: list[str] | dict[str, Any] | None = None,
        allowed_providers: list[str] | dict[str, Any] | None = None,
        min_success_rate: float | None = None,
        max_response_time_ms: int | None = None,
        is_active: bool | None = None,
    ) -> ProxyRotation:
        """Update a rotation configuration (partial update)."""
        request = PatchedProxyRotationRequest(
            name=name,
            parser_ids=parser_ids,
            rotation_interval_minutes=rotation_interval_minutes,
            max_requests_per_proxy=max_requests_per_proxy,
            max_errors_per_proxy=max_errors_per_proxy,
            allowed_countries=normalize_countries(allowed_countries),
            allowed_providers=normalize_providers(allowed_providers),
            min_success_rate=min_success_rate,
            max_response_time_ms=max_response_time_ms,
            is_active=is_active,
        )
        return await self._api.rotations_partial_update(rotation_id, request)

    @async_api_error_handler
    async def delete_rotation(self, rotation_id: str) -> bool:
        """Delete a rotation configuration."""
        await self._api.rotations_destroy(rotation_id)
        return True

    @async_api_error_handler
    async def get_available_proxies_for_rotation(self, rotation_id: str) -> list[Proxy]:
        """Get proxies matching rotation criteria."""
        return await self._api.rotations_available_proxies_retrieve(rotation_id)
