"""Реализация провайдера репутации IP от AbuseIPDB."""

from __future__ import annotations

from contextlib import AbstractAsyncContextManager, asynccontextmanager
import logging
from typing import Any, AsyncIterator

import httpx

from ..iocs import IOCType
from .base import BaseProvider, FeatureValue

TOKEN_NAME = "abuseipdb"

logger = logging.getLogger(__name__)


class AbuseIPDBProvider(BaseProvider):
    """Запрашивает репутацию IP-адресов через API AbuseIPDB."""

    API_BASE = "https://api.abuseipdb.com/api/v2"
    CHECK_ENDPOINT = "check"
    DEFAULT_MAX_AGE_DAYS = 1

    def __init__(self, *, max_age_days: int = DEFAULT_MAX_AGE_DAYS) -> None:
        """Настроить провайдера с параметром глубины истории."""
        super().__init__("abuseipdb", requires_token=True, token_name=TOKEN_NAME)

        if not 1 <= max_age_days <= 365:
            raise ValueError("max_age_days должен находиться в пределах от 1 до 365")
        self.max_age_days = max_age_days

    def get_context(
        self, token: str | None = None
    ) -> AbstractAsyncContextManager[httpx.AsyncClient]:
        """Создать HTTP-клиент для запросов к API AbuseIPDB с переданным токеном."""
        if not token:
            raise ValueError("Для AbuseIPDB требуется API-токен")

        headers = {"Key": token, "Accept": "application/json"}
        logger.debug("Создаём клиент AbuseIPDB с переданным токеном")

        @asynccontextmanager
        async def _client() -> AsyncIterator[httpx.AsyncClient]:
            logger.debug(
                "Opening httpx client for AbuseIPDB at %s with timeout %.2fs",
                self.API_BASE,
                self.http_timeout,
            )
            logger.debug(
                "HTTP прокси для AbuseIPDB: %s",
                self.http_proxy or "не используется",
            )
            client_kwargs = self.build_http_client_kwargs(
                base_url=self.API_BASE,
                headers=headers,
            )
            async with httpx.AsyncClient(**client_kwargs) as client:
                yield client
            logger.debug("HTTP-клиент для AbuseIPDB закрыт")

        return _client()

    async def fetch(self, indicator: IOCType, context: Any) -> dict[str, Any] | bool:
        """Получить данные репутации для IP-адреса и нормализовать ответ API."""
        if indicator.category != "ip":
            logger.info(
                "AbuseIPDB не поддерживает индикатор %s (%s)",
                indicator.value,
                indicator.category,
            )
            return False

        params: dict[str, Any] = {
            "ipAddress": indicator.value,
            "maxAgeInDays": str(self.max_age_days),
        }

        logger.info("Запрашиваем AbuseIPDB для IP %s", indicator.value)

        try:
            response = await context.get(self.CHECK_ENDPOINT, params=params)
            response.raise_for_status()
            payload = response.json()
            data = payload["data"]
        except Exception as exc:
            logger.exception(
                "Не удалось получить данные AbuseIPDB для индикатора %s: %s",
                indicator.value,
                exc,
            )
            return False

        return data

    def build_features(
        self,
        payload: Any,
        *,
        indicator: IOCType | None = None,
    ) -> dict[str, FeatureValue]:
        """Построить фичи на основе ответа AbuseIPDB (заглушка)."""

        indicator_value = getattr(indicator, "value", indicator)
        logger.debug(
            "Фичи для AbuseIPDB пока не реализованы (индикатор=%s)",
            indicator_value,
        )
        return payload
