"""Attach alert_logs to fleet metric sample windows (10min flush alignment)."""

from __future__ import annotations

from datetime import datetime, timedelta
from typing import Any

from server.utils.display_time import to_naive_utc

ALERT_TYPE_LABELS = {
    "cpu": "CPU",
    "mem": "内存",
    "disk": "磁盘",
    "time_drift": "时钟漂移",
    "system": "系统",
}


def _parse_naive_utc(value: datetime | str | None) -> datetime | None:
    if value is None:
        return None
    if isinstance(value, datetime):
        return to_naive_utc(value)
    raw = str(value).strip()
    if not raw:
        return None
    normalized = raw.replace(" ", "T") if " " in raw and "T" not in raw else raw
    if normalized.endswith("Z"):
        normalized = normalized[:-1] + "+00:00"
    try:
        dt = datetime.fromisoformat(normalized)
    except ValueError:
        return None
    return to_naive_utc(dt)


def _alert_to_dict(alert: Any) -> dict[str, Any]:
    atype = str(getattr(alert, "alert_type", "") or "")
    return {
        "server_name": getattr(alert, "server_name", None) or "",
        "server_id": getattr(alert, "server_id", None),
        "alert_type": atype,
        "alert_type_label": ALERT_TYPE_LABELS.get(atype, atype),
        "value": getattr(alert, "value", None) or "",
        "is_recovery": bool(getattr(alert, "is_recovery", False)),
        "created_at": str(getattr(alert, "created_at", "") or ""),
    }


def attach_alerts_to_fleet_points(
    points: list[dict[str, Any]],
    alerts: list[Any],
    *,
    interval_minutes: int = 10,
) -> list[dict[str, Any]]:
    """Map each sample to alerts in (previous_sample, current_sample] window."""
    if not points:
        return []

    parsed: list[tuple[datetime | None, dict[str, Any]]] = []
    for p in points:
        parsed.append((_parse_naive_utc(p.get("recorded_at")), p))

    alert_rows: list[tuple[datetime, dict[str, Any]]] = []
    for a in alerts:
        adt = _parse_naive_utc(getattr(a, "created_at", None))
        if adt is not None:
            alert_rows.append((adt, _alert_to_dict(a)))

    window = timedelta(minutes=max(1, interval_minutes))
    enriched: list[dict[str, Any]] = []

    for i, (pt_dt, p) in enumerate(parsed):
        if pt_dt is None:
            enriched.append({**p, "alerts": [], "alert_count": 0})
            continue

        prev_dt = parsed[i - 1][0] if i > 0 else None
        start = prev_dt if prev_dt is not None else pt_dt - window
        bucket = [
            item
            for adt, item in alert_rows
            if start < adt <= pt_dt
        ]
        enriched.append({**p, "alerts": bucket, "alert_count": len(bucket)})

    return enriched
