"""Service de collecte des données de la station météo locale WeeWX."""
import logging
import re
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta, timezone

import httpx

from app.config import STATION_URL

logger = logging.getLogger(__name__)


def _safe_float(text: str | None) -> float | None:
    if text is None:
        return None
    try:
        cleaned = text.strip().replace(",", ".")
        # Retirer unités courantes
        for unit in [" °C", " %", " hPa", " km/h", " W/m²", "°C", "%", "hPa"]:
            cleaned = cleaned.replace(unit, "")
        return float(cleaned.strip())
    except (ValueError, AttributeError):
        return None


def _direction_to_abbr(deg: float | None) -> str | None:
    if deg is None:
        return None
    dirs = ["N", "NE", "E", "SE", "S", "SO", "O", "NO"]
    return dirs[round(deg / 45) % 8]


def fetch_current(base_url: str = STATION_URL) -> dict | None:
    """Scrape les données actuelles depuis le RSS de la station WeeWX.

    Retourne un dict avec les clés : temp_ext, humidite, pression,
    pluie_mm, vent_kmh, vent_dir, uv, solaire — ou None si indisponible.
    """
    try:
        url = base_url.rstrip("/") + "/rss.xml"
        r = httpx.get(url, timeout=10)
        r.raise_for_status()
        root = ET.fromstring(r.text)

        channel = root.find("channel")
        if channel is None:
            return None

        item = channel.find("item")
        if item is None:
            return None

        desc = item.findtext("description") or ""

        result: dict = {}

        patterns = {
            "temp_ext": r"(?:Outside|Ext(?:erieur)?)\s*Temp(?:erature)?\s*[:\s]+(-?\d+(?:[.,]\d+)?)",
            "temp_int": r"(?:Inside|Int(?:erieur)?)\s*Temp(?:erature)?\s*[:\s]+(-?\d+(?:[.,]\d+)?)",
            "humidite": r"(?:Outside\s*)?Hum(?:idity)?\s*[:\s]+(\d+(?:[.,]\d+)?)",
            "pression": r"(?:Bar(?:ometer)?|Pression)\s*[:\s]+(\d+(?:[.,]\d+)?)",
            "pluie_mm": r"(?:Rain(?:fall)?|Pluie)\s*[:\s]+(\d+(?:[.,]\d+)?)",
            "vent_kmh": r"(?:Wind\s*Speed|Vent)\s*[:\s]+(\d+(?:[.,]\d+)?)",
            "uv": r"UV\s*[:\s]+(\d+(?:[.,]\d+)?)",
            "solaire": r"(?:Solar\s*Radiation|Solaire)\s*[:\s]+(\d+(?:[.,]\d+)?)",
        }

        for key, pattern in patterns.items():
            m = re.search(pattern, desc, re.IGNORECASE)
            result[key] = _safe_float(m.group(1)) if m else None

        vent_dir_m = re.search(
            r"(?:Wind\s*Dir(?:ection)?)\s*[:\s]+([NSEO]{1,2}|Nord|Sud|Est|Ouest|\d+)",
            desc, re.IGNORECASE,
        )
        if vent_dir_m:
            val = vent_dir_m.group(1).strip()
            if val.isdigit():
                result["vent_dir"] = _direction_to_abbr(float(val))
            else:
                result["vent_dir"] = val[:2].upper()
        else:
            result["vent_dir"] = None

        return result if any(v is not None for v in result.values()) else None

    except Exception as e:
        logger.warning(f"Station fetch_current error: {e}")
        return None


def fetch_yesterday_summary(base_url: str = STATION_URL) -> dict | None:
    """Récupère le résumé de la veille via le fichier NOAA mensuel de la station WeeWX.

    Retourne un dict avec : temp_ext (moy), t_min, t_max, pluie_mm — ou None.
    """
    yesterday = (datetime.now() - timedelta(days=1)).date()
    year = yesterday.strftime("%Y")
    month = yesterday.strftime("%m")
    day = yesterday.day

    try:
        url = f"{base_url.rstrip('/')}/NOAA/NOAA-{year}-{month}.txt"
        r = httpx.get(url, timeout=15)
        r.raise_for_status()

        for line in r.text.splitlines():
            parts = line.split()
            if len(parts) >= 7 and parts[0].isdigit() and int(parts[0]) == day:
                # Format NOAA : jour  tmax tmin tmoy  precip  ...
                return {
                    "t_max": _safe_float(parts[1]),
                    "t_min": _safe_float(parts[2]),
                    "temp_ext": _safe_float(parts[3]),
                    "pluie_mm": _safe_float(parts[5]),
                    "vent_kmh": _safe_float(parts[6]) if len(parts) > 6 else None,
                }
    except Exception as e:
        logger.warning(f"Station fetch_yesterday_summary error: {e}")
    return None
