"""Провайдер рейтинга доменов OpenPageRank."""

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 = "openpagerank"

logger = logging.getLogger(__name__)


class OpenPageRankProvider(BaseProvider):
    """Получает показатели PageRank для доменов через OpenPageRank API."""

    API_URL = "https://openpagerank.com/api/v1.0/getPageRank"

    def __init__(self) -> None:
        """Создать провайдера OpenPageRank с обязательным токеном."""
        super().__init__("openpagerank", requires_token=True, token_name=TOKEN_NAME)

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

        headers = {"API-OPR": token, "Accept": "application/json"}

        logger.debug(
            "Создаём HTTP-клиент OpenPageRank: прокси=%s, таймаут=%.2f",
            self.http_proxy or "не используется",
            self.http_timeout,
        )

        @asynccontextmanager
        async def _client() -> AsyncIterator[httpx.AsyncClient]:
            client_kwargs = self.build_http_client_kwargs(
                base_url=self.API_URL,
                headers=headers,
            )
            async with httpx.AsyncClient(**client_kwargs) as client:
                yield client

        return _client()

    async def fetch(self, indicator: IOCType, context: Any) -> dict[str, Any] | bool:
        """Запросить рейтинг PageRank и вернуть ответ API как есть."""

        if indicator.category != "domain":
            logger.info(
                "OpenPageRank не поддерживает индикатор %s (%s)",
                indicator.value,
                indicator.category,
            )
            return False

        domain = indicator.value
        logger.info("Запрашиваем OpenPageRank для домена %s", domain)

        try:
            response = await context.get("", params={"domains[]": domain})
            response.raise_for_status()
            return response.json()
        except Exception as exc:
            logger.exception(
                "Не удалось получить данные OpenPageRank для %s: %s",
                domain,
                exc,
            )
            return False

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

        entry = payload.get("response", [{}])
        entry = entry[0]
        page_rank_dec = entry.get("page_rank_decimal")
        opr_rank = entry.get("rank")

        features = {
            "opr_pr_dec": page_rank_dec or None,
            "opr_rank": int(opr_rank) if opr_rank else None,
        }

        logger.debug("Построены фичи OpenPageRank для %s: %s", indicator, features)
        return features
