from __future__ import annotations

import logging
from typing import Any

from src.cache import FileCache
from src.config import FILE_CACHE_DIR, FILE_CACHE_TTL_SECONDS

logger = logging.getLogger(__name__)

_file_cache = FileCache(FILE_CACHE_DIR, FILE_CACHE_TTL_SECONDS)


def cache_key_period(slug: str, start: str, end: str) -> str:
    return f"period_{slug}_{start}_{end}"


def cache_key_month(slug: str, year: int, month: int) -> str:
    return f"month_{slug}_{year}_{month:02d}"


def cache_key_town(slug: str) -> str:
    return f"town_{slug}"


def get_cached(key: str) -> dict[str, Any] | None:
    return _file_cache.get(key)


def store_cached(key: str, data: dict[str, Any]) -> None:
    _file_cache.set(key, data)


async def prefetch_period(
    commune_service: Any,
    weather_service: Any,
    normals_service: Any,
    slug: str,
    start: str,
    end: str,
) -> dict[str, Any] | None:
    key = cache_key_period(slug, start, end)
    cached = get_cached(key)
    if cached is not None:
        return cached

    try:
        commune = await commune_service.resolve_slug(slug)
        if commune is None:
            return None

        lat = commune.get("latitude")
        lon = commune.get("longitude")
        if lat is None or lon is None:
            return None

        weather = await weather_service.get_weather_for_prefetch(lat, lon, start, end)

        normals = None
        try:
            normals = await normals_service.get_normals(lat, lon, start, end)
        except Exception:
            normals = None

        bundle = {
            "commune": commune,
            "weather": weather,
            "normals": normals,
        }
        store_cached(key, bundle)
        return bundle
    except Exception:
        logger.debug("Prefetch failed for %s %s/%s", slug, start, end)
        return None


async def prefetch_month(
    commune_service: Any,
    weather_service: Any,
    normals_service: Any,
    slug: str,
    start: str,
    end: str,
    year: int,
    month: int,
) -> dict[str, Any] | None:
    key = cache_key_month(slug, year, month)
    cached = get_cached(key)
    if cached is not None:
        return cached

    try:
        commune = await commune_service.resolve_slug(slug)
        if commune is None:
            return None

        lat = commune.get("latitude")
        lon = commune.get("longitude")
        if lat is None or lon is None:
            return None

        weather = await weather_service.get_weather_for_prefetch(lat, lon, start, end)

        normals = None
        try:
            normals = await normals_service.get_normals(lat, lon, start, end)
        except Exception:
            normals = None

        bundle = {
            "commune": commune,
            "weather": weather,
            "normals": normals,
        }
        store_cached(key, bundle)
        return bundle
    except Exception:
        logger.debug("Prefetch failed for %s %d/%02d", slug, year, month)
        return None


async def prefetch_town(
    commune_service: Any,
    normals_service: Any,
    slug: str,
) -> dict[str, Any] | None:
    key = cache_key_town(slug)
    cached = get_cached(key)
    if cached is not None:
        return cached

    try:
        commune = await commune_service.resolve_slug(slug)
        if commune is None:
            return None

        lat = commune.get("latitude")
        lon = commune.get("longitude")
        if lat is None or lon is None:
            return None

        annual = None
        try:
            annual = await normals_service.get_annual_normals(lat, lon)
        except Exception:
            annual = None

        bundle = {
            "commune": commune,
            "annual_climate": annual,
        }
        store_cached(key, bundle)
        return bundle
    except Exception:
        logger.debug("Prefetch failed for town %s", slug)
        return None
