"""Shared MeshCentral presence and last-seen helpers.

The MeshCentral CLI uses slightly different key names and nesting depending on
whether ListDevices is called with --details and on the MeshCentral version.
This module keeps timestamp parsing and state derivation in one place.
"""
from __future__ import annotations

from datetime import datetime, timezone
from typing import Any


def _nested(data: Any, *path: str) -> Any:
    current = data
    for key in path:
        if not isinstance(current, dict):
            return None
        current = current.get(key)
    return current


def parse_mesh_datetime(value: Any) -> datetime | None:
    """Parse MeshCentral Unix timestamps (seconds/ms) and ISO strings as UTC-naive."""
    if value is None or isinstance(value, bool):
        return None
    if isinstance(value, datetime):
        if value.tzinfo:
            return value.astimezone(timezone.utc).replace(tzinfo=None)
        return value
    if isinstance(value, dict):
        for key in ("time", "timestamp", "value"):
            parsed = parse_mesh_datetime(value.get(key))
            if parsed:
                return parsed
        return None
    if isinstance(value, (int, float)):
        numeric = float(value)
        if numeric <= 0:
            return None
        # MeshCentral commonly emits JavaScript timestamps in milliseconds.
        if numeric > 100_000_000_000:
            numeric /= 1000.0
        try:
            return datetime.fromtimestamp(numeric, tz=timezone.utc).replace(tzinfo=None)
        except (OverflowError, OSError, ValueError):
            return None

    text = str(value).strip()
    if not text or text in {"0", "-"}:
        return None
    try:
        return parse_mesh_datetime(float(text))
    except ValueError:
        pass
    try:
        normalized = text[:-1] + "+00:00" if text.endswith("Z") else text
        parsed = datetime.fromisoformat(normalized)
        if parsed.tzinfo:
            parsed = parsed.astimezone(timezone.utc).replace(tzinfo=None)
        return parsed
    except ValueError:
        return None


def extract_last_seen(device: dict[str, Any] | None) -> datetime | None:
    """Return the best historical connection timestamp exposed by MeshCentral."""
    if not isinstance(device, dict):
        return None
    candidates = (
        device.get("lastConnect"),
        device.get("lastconnect"),
        device.get("lastSeen"),
        device.get("lastseen"),
        device.get("lastOnline"),
        device.get("lastonline"),
        _nested(device, "node", "lastConnect"),
        _nested(device, "node", "lastconnect"),
        _nested(device, "node", "lastSeen"),
        _nested(device, "node", "lastseen"),
    )
    for candidate in candidates:
        parsed = parse_mesh_datetime(candidate)
        if parsed:
            return parsed
    return None


def extract_last_address(device: dict[str, Any] | None) -> str | None:
    if not isinstance(device, dict):
        return None
    candidates = (
        _nested(device, "lastConnect", "addr"),
        _nested(device, "lastconnect", "addr"),
        device.get("lastaddr"),
        device.get("lastAddress"),
        _nested(device, "node", "lastaddr"),
        _nested(device, "node", "lastAddress"),
        _nested(device, "node", "ip"),
        _nested(device, "node", "host"),
    )
    for value in candidates:
        text = str(value or "").strip()
        if text:
            return text
    return None


def derive_presence_state(live_online: bool | None, last_seen: datetime | None) -> str:
    """Derive UI state: live true=online; historical connection=offline; else unknown."""
    if live_online is True:
        return "online"
    if last_seen is not None:
        return "offline"
    return "unknown"
