from __future__ import annotations

from collections import Counter
from typing import Any, Iterable

from .cache import get_or_fetch
from .config import CACHE_TTL_DAYS
from .http_client import get_json

import os

BASE_URL = os.environ.get("GEORISQUES_API_BASE_URL", "https://www.georisques.gouv.fr/api/v1")
TTL_SECONDS = CACHE_TTL_DAYS * 24 * 3600


def chunked(values: list[str], size: int = 10) -> Iterable[list[str]]:
    for idx in range(0, len(values), size):
        yield values[idx : idx + size]


def _payload_items(payload: Any) -> list[Any]:
    if isinstance(payload, list):
        return payload
    if isinstance(payload, dict):
        for key in ("data", "results", "items", "content"):
            value = payload.get(key)
            if isinstance(value, list):
                return value
    return []


def fetch_endpoint(endpoint: str, codes_insee: list[str], *, force: bool = False) -> list[dict[str, Any]]:
    responses: list[dict[str, Any]] = []
    for group in chunked(codes_insee, 10):
        codes = ",".join(group)
        cache_name = f"georisques_{endpoint.replace('/', '_')}_{codes}"
        url = f"{BASE_URL}/{endpoint.lstrip('/')}"
        item = get_or_fetch(
            cache_name,
            TTL_SECONDS,
            lambda url=url, codes=codes: get_json(url, params={"code_insee": codes, "page_size": 100}),
            force=force,
            source=url,
        )
        responses.append({"codes": group, "payload": item["payload"], "cache_status": item.get("cache_status")})
    return responses


def risks_for_communes(codes_insee: list[str], *, force: bool = False) -> dict[str, Any]:
    responses = fetch_endpoint("gaspar/risques", codes_insee, force=force)
    counter: Counter[str] = Counter()
    total_items = 0
    for response in responses:
        items = _payload_items(response.get("payload"))
        total_items += len(items)
        for item in items:
            if isinstance(item, dict):
                label = item.get("libelle_risque") or item.get("libelle") or item.get("risque") or item.get("type_risque") or "Risque non qualifié"
                counter[str(label)] += 1
    return {
        "endpoint": "gaspar/risques",
        "communes_requested": len(codes_insee),
        "items": total_items,
        "by_label": counter.most_common(),
        "raw_batches": responses,
    }


def pprn_for_commune(code_insee: str, *, force: bool = False) -> dict[str, Any]:
    url = f"{BASE_URL}/gaspar/pprn"
    item = get_or_fetch(
        f"georisques_pprn_{code_insee}",
        TTL_SECONDS,
        lambda: get_json(url, params={"codeInsee": code_insee, "page_size": 100}),
        force=force,
        source=url,
    )
    return item["payload"]
