"""CO2-Intensität des Stromnetzes — Echtzeit-Daten.

Nutzt:
- Carbon Intensity UK API (kostenlos, kein Key)
- Electricity Maps API (optional, mit Key global verfügbar)
"""

import httpx
from mcp.server.fastmcp import FastMCP
from src.config import (
    CARBON_INTENSITY_BASE,
    ELECTRICITY_MAPS_BASE,
    ELECTRICITY_MAPS_TOKEN,
)


def register_co2_tools(mcp: FastMCP) -> None:
    """Registriert CO2-Intensitäts-Tools."""

    @mcp.tool()
    async def get_uk_carbon_intensity(region: str = "") -> dict:
        """Aktuelle CO2-Intensität des britischen Stromnetzes (gCO2/kWh).

        Args:
            region: Optional — UK-Region (z.B. 'South West England', 'Scotland').
                    Leer lassen für nationale Übersicht.

        Returns:
            CO2-Intensität (gCO2/kWh), Index (low/moderate/high/very high),
            Strommix-Aufschlüsselung nach Quelle.
        """
        async with httpx.AsyncClient(timeout=15) as client:
            if region:
                # Alle Regionen abrufen und filtern
                resp = await client.get(f"{CARBON_INTENSITY_BASE}/regional")
                resp.raise_for_status()
                data = resp.json()
                regions = data.get("data", [{}])[0].get("regions", [])
                for r in regions:
                    if region.lower() in r.get("shortname", "").lower() or \
                       region.lower() in r.get("dnoregion", "").lower():
                        return {
                            "region": r.get("dnoregion", r.get("shortname")),
                            "intensity_gco2_kwh": r.get("intensity", {}).get("forecast"),
                            "index": r.get("intensity", {}).get("index"),
                            "generation_mix": r.get("generationmix", []),
                        }
                return {"error": f"Region '{region}' nicht gefunden. Verfügbare: South West England, South East England, London, East England, East Midlands, Yorkshire, North West England, North East England, Scotland, Wales, South England, Midlands"}
            else:
                # National
                resp = await client.get(f"{CARBON_INTENSITY_BASE}/intensity")
                resp.raise_for_status()
                data = resp.json()
                intensity = data.get("data", [{}])[0].get("intensity", {})
                return {
                    "region": "United Kingdom (national)",
                    "intensity_gco2_kwh": intensity.get("actual") or intensity.get("forecast"),
                    "forecast_gco2_kwh": intensity.get("forecast"),
                    "index": intensity.get("index"),
                    "source": "Carbon Intensity UK API",
                }

    @mcp.tool()
    async def get_carbon_intensity_forecast(hours_ahead: int = 24) -> list:
        """CO2-Intensitäts-Prognose für das UK-Stromnetz (bis 48h voraus).

        Args:
            hours_ahead: Stunden in die Zukunft (max. 48). Standard: 24.

        Returns:
            Liste mit stündlichen CO2-Prognosen — ideal um energieintensive
            Tasks in grüne Zeitfenster zu planen.
        """
        hours_ahead = min(hours_ahead, 48)
        async with httpx.AsyncClient(timeout=15) as client:
            resp = await client.get(f"{CARBON_INTENSITY_BASE}/intensity/pt24h/fw48h")
            resp.raise_for_status()
            data = resp.json()
            slots = data.get("data", [])[:hours_ahead * 2]  # 30-min Intervalle
            return [
                {
                    "von": slot.get("from"),
                    "bis": slot.get("to"),
                    "forecast_gco2_kwh": slot.get("intensity", {}).get("forecast"),
                    "index": slot.get("intensity", {}).get("index"),
                }
                for slot in slots
            ]

    @mcp.tool()
    async def find_greenest_time_window(duration_hours: int = 2) -> dict:
        """Findet das grünste Zeitfenster für energieintensive AI-Tasks (UK).

        Ideal für: GPU-Training, Batch-Verarbeitung, große Inferenz-Jobs.

        Args:
            duration_hours: Dauer des geplanten Tasks in Stunden. Standard: 2.

        Returns:
            Bestes Zeitfenster mit niedrigster CO2-Intensität in den
            nächsten 48 Stunden inkl. Vergleich zu aktuellem Wert.
        """
        async with httpx.AsyncClient(timeout=15) as client:
            resp = await client.get(f"{CARBON_INTENSITY_BASE}/intensity/pt24h/fw48h")
            resp.raise_for_status()
            data = resp.json()
            slots = data.get("data", [])

        # Gleitendes Fenster über `duration_hours * 2` Slots (30-min Intervalle)
        window_size = duration_hours * 2
        best_start = 0
        best_avg = float("inf")

        for i in range(len(slots) - window_size + 1):
            window = slots[i:i + window_size]
            values = [s.get("intensity", {}).get("forecast", 999) for s in window]
            avg = sum(values) / len(values)
            if avg < best_avg:
                best_avg = avg
                best_start = i

        best_window = slots[best_start:best_start + window_size]
        current_intensity = slots[0].get("intensity", {}).get("forecast", 0) if slots else 0

        return {
            "bestes_fenster_start": best_window[0].get("from") if best_window else None,
            "bestes_fenster_ende": best_window[-1].get("to") if best_window else None,
            "durchschnitt_gco2_kwh": round(best_avg, 1),
            "aktuell_gco2_kwh": current_intensity,
            "einsparung_prozent": round((1 - best_avg / current_intensity) * 100, 1) if current_intensity else 0,
            "empfehlung": "Jetzt ausführen" if best_start == 0 else f"Warten bis {best_window[0].get('from')}",
        }

    @mcp.tool()
    async def get_global_carbon_intensity(zone: str) -> dict:
        """CO2-Intensität für eine globale Zone (benötigt ELECTRICITY_MAPS_TOKEN).

        Args:
            zone: Zone-Code, z.B. 'DE' (Deutschland), 'FR' (Frankreich),
                  'US-CAL-CISO' (Kalifornien), 'IN-NO' (Nordindien).

        Returns:
            CO2-Intensität (gCO2/kWh) und Strommix für die Zone.
            Benötigt ELECTRICITY_MAPS_TOKEN in .env.
        """
        if not ELECTRICITY_MAPS_TOKEN:
            return {
                "error": "ELECTRICITY_MAPS_TOKEN nicht gesetzt.",
                "hinweis": "Kostenlosen Token unter https://api-portal.electricitymaps.com registrieren.",
                "alternative": "Für UK-Daten: get_uk_carbon_intensity() ohne Key verfügbar.",
            }

        async with httpx.AsyncClient(
            timeout=15,
            headers={"auth-token": ELECTRICITY_MAPS_TOKEN},
        ) as client:
            resp = await client.get(
                f"{ELECTRICITY_MAPS_BASE}/carbon-intensity/latest",
                params={"zone": zone},
            )
            resp.raise_for_status()
            data = resp.json()
            return {
                "zone": zone,
                "intensity_gco2_kwh": data.get("carbonIntensity"),
                "is_estimated": data.get("isEstimated"),
                "datetime": data.get("datetime"),
                "source": "Electricity Maps",
            }
