from __future__ import annotations

import os
from pathlib import Path
from typing import Any

from .api_geo import ApiGeoClient
from .cache import read_json, write_json, envelope


def load_scope_config(base_dir: Path) -> dict[str, Any]:
    explicit = os.getenv("AULA_SCOPE_FILE")
    path = Path(explicit) if explicit else base_dir / "data" / "aula_scope.example.json"
    if not path.is_absolute():
        path = base_dir / path
    return read_json(path, default={
        "label": "Territoire AULA",
        "mode": "communes",
        "epci_codes": [],
        "commune_codes": [],
        "commune_codes_extra": [],
    })


def cache_path(base_dir: Path) -> Path:
    return base_dir / os.getenv("AULA_CACHE_DIR", "data/cache") / "aula_scope.json"


def current_scope(base_dir: Path) -> dict[str, Any]:
    cached = read_json(cache_path(base_dir))
    if cached:
        return cached
    config = load_scope_config(base_dir)
    return envelope("aula_scope_config", {"config": config, "communes": [], "epcis": []}, status="not_refreshed")


def refresh_scope(base_dir: Path) -> dict[str, Any]:
    config = load_scope_config(base_dir)
    client = ApiGeoClient()
    epcis: list[dict[str, Any]] = []
    communes_by_code: dict[str, dict[str, Any]] = {}

    for item in config.get("epci_codes", []) or []:
        code = item.get("code") if isinstance(item, dict) else str(item)
        if not code:
            continue
        epci_meta = client.epci(code)
        epci_meta["source_config"] = item if isinstance(item, dict) else {"code": code}
        epcis.append(epci_meta)
        for commune in client.epci_communes(code):
            commune["epci_code"] = code
            commune["epci_nom"] = epci_meta.get("nom")
            communes_by_code[commune["code"]] = commune

    for code in (config.get("commune_codes", []) or []) + (config.get("commune_codes_extra", []) or []):
        if not code:
            continue
        commune = client.commune(str(code))
        communes_by_code[commune["code"]] = commune

    payload = {
        "config": config,
        "epcis": sorted(epcis, key=lambda x: x.get("nom", "")),
        "communes": sorted(communes_by_code.values(), key=lambda x: x.get("nom", "")),
        "commune_codes": sorted(communes_by_code.keys()),
        "epci_codes": [e.get("code") for e in epcis if e.get("code")],
        "warning": config.get("warning"),
    }
    result = envelope("api_geo", payload, metadata={"base_url": client.base_url})
    write_json(cache_path(base_dir), result)
    return result
