from __future__ import annotations

import asyncio
import time
from typing import Any

from app.cache import cache_get, cache_set, redis_available
from app.config import (
    BRIGHTSKY_BASE_URL,
    CACHE_TTL_HEALTH_SOURCES,
    DATABASE_URL,
    DWD_RADAR_BASE_URL,
    DWD_WMS_URL,
    DWD_WARNINGS_URL,
    OPEN_METEO_BASE_URL,
)
from app.database import pool_available
from app.http_client import get_client


async def _probe(name: str, url: str, timeout: float = 5.0) -> dict[str, Any]:
    started = time.perf_counter()
    try:
        client = get_client()
        response = await client.get(url, timeout=timeout)
        elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
        ok = response.status_code < 500
        return {
            "name": name,
            "url": url,
            "status": "ok" if ok else "degraded",
            "http_status": response.status_code,
            "latency_ms": elapsed_ms,
        }
    except Exception as exc:
        elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
        return {
            "name": name,
            "url": url,
            "status": "error",
            "error": str(exc),
            "latency_ms": elapsed_ms,
        }


async def check_sources() -> list[dict[str, Any]]:
    cache_key = "health:sources"
    cached = await cache_get(cache_key)
    if cached:
        return cached

    probes = await asyncio.gather(
        _probe("open_meteo", f"{OPEN_METEO_BASE_URL}/forecast?latitude=52.5&longitude=13.4&current=temperature_2m"),
        _probe("brightsky", f"{BRIGHTSKY_BASE_URL}/current_weather?lat=52.5&lon=13.4"),
        _probe("dwd_radar", f"{DWD_RADAR_BASE_URL}/rv/", timeout=4.0),
        _probe("dwd_wms", f"{DWD_WMS_URL}?service=WMS&request=GetCapabilities", timeout=6.0),
        _probe("dwd_warnings", DWD_WARNINGS_URL, timeout=4.0),
    )
    results = list(probes)
    results.append(
        {
            "name": "postgres",
            "url": DATABASE_URL.split("@")[-1],
            "status": "ok" if pool_available() else "disabled",
        }
    )
    results.append(
        {
            "name": "redis",
            "url": "redis",
            "status": "ok" if redis_available() else "disabled",
        }
    )
    await cache_set(cache_key, results, CACHE_TTL_HEALTH_SOURCES)
    return results
