"""SWPC space-weather event formatter — Phase-1 refactor.

Reads canonical event.data schema:
    driver      : "kp" | "flare" | None  — what drove the event (proton/S-scale
                  events carry driver=None from env/swpc.py; dispatched below
                  via scale_code prefix "S", not driver)
    scalar      : float (Kp value) | str (flare class | proton "N pfu") | None
    scale_code  : "G3" | "R3" | "S1" | etc.  — NOAA scale code
    message     : str  — raw SWPC alert message body (or "")
    issued_at   : str | None  — ISO timestamp for the time tag line

Wire format (multi-line, identical structure to swpc_handler._render()):
    Geomag:   🧲 New: G3 Geomagnetic Storm — Kp7
              HF degraded, aurora possible
              SWPC · 2026-07-04 05:09

    Flare:    ☀️ New: X1.0 Solar Flare — R3
              HF radio fading, GPS may glitch
              SWPC · 2026-06-03 11:59

    Proton:   ☢️ New: S1 Radiation Storm — 10 pfu
              Polar HF radio affected
              SWPC · 2026-07-04 06:00

    (when scalar is None the dash-separated tail is omitted; native env/swpc.py
    never supplies a proton scalar, so live S-scale wires omit the tail)

Tier-b fix note: `_severity_override` is set by the decider (gating/swpc.py)
so geomag/flare events dispatch at priority/immediate severity instead of the
"routine" default the old swpc_handler always produced.

All other formatting is identical to swpc_handler._render().

Time contract: `now` is accepted but not used for rendering (structural seam
for future relative-time annotations).  All time reads MUST go through
meshai.notifications.clock — never the stdlib equivalents — so golden-file
tests can freeze the clock via monkeypatch.
"""
from __future__ import annotations

from typing import TYPE_CHECKING

from meshai.notifications.formatters._budget import fit_to_budget

if TYPE_CHECKING:
    from meshai.notifications.events import Event


def _trunc(s: str, limit: int = 120) -> str:
    """Truncate *s* at the last word boundary at or before *limit* chars."""
    if len(s) <= limit:
        return s
    cut = s[:limit].rsplit(" ", 1)[0]
    if not cut:
        cut = s[:limit]
    return cut + "…"


def format(event: "Event", *, now: float, budget: int) -> str:
    """Render SWPC wire string from canonical event.data.

    Args:
        event:  Pipeline Event — reads from event.data (canonical schema).
        now:    Frozen-clock epoch (structural seam; not used in rendering).
        budget: Mesh-packet character budget.

    Returns:
        UTF-8 string fitting within *budget* characters.
    """
    d = event.data or {}

    driver = d.get("driver")          # "kp" | "flare"
    scalar = d.get("scalar")          # float (Kp) | str (flare class) | None
    scale_code = d.get("scale_code") or ""   # "G3", "R3", etc.

    # ── Detail line (line 2) ─────────────────────────────────────────────────
    message = d.get("message") or ""
    if isinstance(message, str):
        message = _trunc(message.strip())
    else:
        message = ""

    # ── Time tag (line 3) ────────────────────────────────────────────────────
    time_tag = ""
    issued_at = d.get("issued_at") or d.get("time_tag") or ""
    if isinstance(issued_at, str) and issued_at:
        time_tag = issued_at[:16].replace("T", " ")

    prefix = "New:"   # SWPC events are point-in-time; "Update:" not used

    if driver == "kp":
        # ── Geomagnetic storm ────────────────────────────────────────────────
        if isinstance(scalar, (int, float)):
            scalar_str: str | None = f"Kp{int(round(scalar))}"
        else:
            scalar_str = None

        if scalar_str:
            line1 = f"🧲 {prefix} {scale_code} Geomagnetic Storm — {scalar_str}"
        else:
            line1 = f"🧲 {prefix} {scale_code} Geomagnetic Storm"

        line2 = message if message else "HF degraded, aurora possible"
        line3 = f"SWPC · {time_tag}" if time_tag else "SWPC"

    elif driver == "flare":
        # ── Solar flare ──────────────────────────────────────────────────────
        if isinstance(scalar, str) and scalar:
            line1 = f"☀️ {prefix} {scalar} Solar Flare — {scale_code}"
        else:
            line1 = f"☀️ {prefix} {scale_code} Solar Flare"

        line2 = message if message else "HF radio fading, GPS may glitch"
        line3 = f"SWPC · {time_tag}" if time_tag else "SWPC"

    elif scale_code.startswith("S"):
        # ── Solar radiation storm (proton) ──────────────────────────────────────
        # Dispatched on scale_code, not driver: env/swpc.py's native adapter
        # always sets driver=None for S-scale events (no per-reading pfu value
        # available from noaa-scales.json), so there is no "proton" driver value
        # to switch on. scalar (when present, e.g. from a future producer with a
        # real pfu reading) is a pre-formatted string like "10 pfu", matching
        # central/swpc_handler.py's scalar_str convention for this event kind.
        if isinstance(scalar, str) and scalar:
            line1 = f"☢️ {prefix} {scale_code} Radiation Storm — {scalar}"
        else:
            line1 = f"☢️ {prefix} {scale_code} Radiation Storm"

        line2 = message if message else "Polar HF radio affected"
        line3 = f"SWPC · {time_tag}" if time_tag else "SWPC"

    else:
        # ── Unknown driver (fallback — should not occur in normal operation) ─
        line1 = f"⚠️ {prefix} Space Weather Event — {scale_code or '?'}"
        line2 = message if message else None
        line3 = f"SWPC · {time_tag}" if time_tag else "SWPC"

    msg = "\n".join(l for l in [line1, line2, line3] if l)
    return fit_to_budget(msg, budget)
