from __future__ import annotations

from typing import Any

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("INSEE_MELODI_BASE_URL", "https://api.insee.fr/melodi")
TTL_SECONDS = CACHE_TTL_DAYS * 24 * 3600


def catalog(*, force: bool = False) -> list[dict[str, Any]]:
    item = get_or_fetch(
        "insee_melodi_catalog_all",
        TTL_SECONDS,
        lambda: get_json(f"{BASE_URL}/catalog/all"),
        force=force,
        source=f"{BASE_URL}/catalog/all",
    )
    payload = item["payload"]
    return payload if isinstance(payload, list) else []


def metadata(ds_name: str, *, force: bool = False) -> dict[str, Any]:
    item = get_or_fetch(
        f"insee_melodi_metadata_{ds_name}",
        TTL_SECONDS,
        lambda: get_json(f"{BASE_URL}/metadata/{ds_name}"),
        force=force,
        source=f"{BASE_URL}/metadata/{ds_name}",
    )
    return item["payload"]


def data(ds_name: str, params: dict[str, Any] | None = None, *, force: bool = False, cache_name: str | None = None) -> Any:
    params = params or {}
    key = cache_name or f"insee_melodi_data_{ds_name}_" + "_".join(f"{k}-{v}" for k, v in sorted(params.items()))[:120]
    item = get_or_fetch(
        key,
        TTL_SECONDS,
        lambda: get_json(f"{BASE_URL}/data/{ds_name}", params=params),
        force=force,
        source=f"{BASE_URL}/data/{ds_name}",
    )
    return item["payload"]


def population_reference_for_epci(epci_code: str, *, force: bool = False) -> Any:
    # Requête volontairement simple et explicite : les filtres exacts pourront être ajustés depuis l'explorateur Melodi.
    # D'après les exemples Melodi, les géographies peuvent être appelées avec GEO=EPCI-<code>.
    return data(
        "DS_POPULATIONS_REFERENCE",
        params={"GEO": f"EPCI-{epci_code}", "POPREF_MEASURE": "PMUN"},
        force=force,
        cache_name=f"insee_population_reference_epci_{epci_code}",
    )


def rp_population_principale_for_epci(epci_code: str, *, force: bool = False) -> Any:
    return data(
        "DS_RP_POPULATION_PRINC",
        params={"GEO": f"EPCI-{epci_code}", "SEX": "_T", "AGE": "_T", "maxResult": 10000},
        force=force,
        cache_name=f"insee_rp_population_princ_epci_{epci_code}",
    )
