"""The "Zużycie usług" panel's document (AV-052): per server-side service --
today's use against its limit (or our budget), the level and what it gives
up, today's use by feature, the share the caches answered, the hours of the
past week, the latest errors and refusals. Numbers only."""

from __future__ import annotations

from collections import defaultdict
from datetime import datetime, timezone

from mountain_twin import budgets
from mountain_twin.external_services import DEFAULT_DEGRADATION, SERVICES, thresholds


def usage_summary_document(store, days: int = 7) -> dict:
    if store is None:
        return {"configured": False, "services": []}
    today = datetime.fromtimestamp(store.clock(), timezone.utc).strftime("%Y-%m-%d")
    rows = store.hourly(days)
    by_service: dict[str, list[dict]] = defaultdict(list)
    for row in rows:
        by_service[row["service"]].append(row)
    errors = store.recent_errors(50)
    services = []
    for key, config in SERVICES.items():
        if config["side"] != "server":
            continue
        own = by_service.get(key, [])
        network = [row for row in own if not row["cache_hit"]]
        today_rows = [row for row in own if row["hour"].startswith(today)]
        used = sum(
            row["weight"] for row in today_rows if not row["cache_hit"] and row["outcome"] == "OK"
        )
        from_cache = sum(row["requests"] for row in today_rows if row["cache_hit"])
        asked = sum(row["requests"] for row in today_rows if not row["cache_hit"])
        features: dict[str, float] = defaultdict(float)
        for row in today_rows:
            if not row["cache_hit"]:
                features[row["feature"]] += row["weight"]
        hourly: dict[str, float] = defaultdict(float)
        for row in network:
            hourly[row["hour"]] += row["weight"]
        level = budgets.level(key)
        services.append(
            {
                "service": key,
                "name": config["name"],
                "daily_budget": config.get("daily_budget"),
                "limits": config.get("limits", {}),
                "counting": config.get("counting"),
                "today_weight": round(used, 1),
                "share": round(used / config["daily_budget"], 4)
                if config.get("daily_budget")
                else None,
                "level": level,
                "policy": DEFAULT_DEGRADATION.get(level, "everything as usual"),
                "thresholds": thresholds(key),
                "fallback": config.get("fallback"),
                "features_today": {
                    name: round(value, 1) for name, value in sorted(features.items())
                },
                "cache_share_today": round(from_cache / (from_cache + asked), 3)
                if from_cache + asked
                else None,
                "requests_today": asked,
                "cache_hits_today": from_cache,
                "hourly": [
                    {"hour": hour, "weight": round(value, 1)}
                    for hour, value in sorted(hourly.items())
                ],
                "recent_errors": [error for error in errors if error["service"] == key][:10],
            }
        )
    return {
        "configured": True,
        "instance": store.instance,
        "day": today,
        "renews_at": budgets.renews_at(),
        "services": services,
    }
