"""
Fiber + radio port: central domain object for a row in fiber_map.json.

Power (USB hub downstream ports), SSH routing, PCIe / wlan / USB metadata all hang off this
aggregate. ``FiWiConcentrator`` supplies BrainStem power; not the conceptual center.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Dict, Iterator, List, Optional, Tuple

from fiwi import fiber_map_io as fm
from fiwi.ssh import SshNode


@dataclass
class FiberRadioPort:
    """
    One logical fiber/radio attachment: ``fiber_ports[<map_key>]`` in the map document.

    ``entry`` is the live dict from the document (mutations persist when the doc is saved).
    """

    map_key: str
    entry: Optional[Dict[str, Any]]

    @property
    def port_id(self) -> Optional[int]:
        """Integer fiber id when ``map_key`` is decimal; else None."""
        if self.map_key.isdigit():
            return int(self.map_key)
        return None

    def hub_port(self) -> Optional[Tuple[int, int]]:
        """(hub_1based, port_0based) or None if unmapped / invalid."""
        return fm.fiber_entry_hub_port(self.entry)

    def ssh_target(self) -> Optional[str]:
        """user@host when this port’s hubs are reached via SSH; else None."""
        return fm.fiber_ssh_target(self.entry) if isinstance(self.entry, dict) else None

    def ssh_node(self) -> Optional[SshNode]:
        """Remote Fi-Wi host (``SshNode``) for this port, or None when mapped locally."""
        t = self.ssh_target()
        if not t:
            return None
        try:
            return SshNode.parse(t)
        except ValueError:
            return None

    def is_mapped(self) -> bool:
        """True when hub.port is valid in the entry."""
        return self.hub_port() is not None

    def chip_preview(self, width: int = 26) -> str:
        return fm.stored_chip_preview(self.entry) if isinstance(self.entry, dict) else ""

    def pcie_preview(self, width: int = 22) -> str:
        return fm.stored_pcie_preview(self.entry) if isinstance(self.entry, dict) else ""

    @classmethod
    def from_map_key(cls, doc: Dict[str, Any], map_key: str) -> FiberRadioPort:
        ports = doc.get("fiber_ports") if isinstance(doc, dict) else None
        if not isinstance(ports, dict):
            return cls(str(map_key), None)
        ent = ports.get(str(map_key))
        return cls(
            str(map_key),
            ent if isinstance(ent, dict) else None,
        )

    @classmethod
    def from_port_id(cls, doc: Dict[str, Any], port_id: int) -> FiberRadioPort:
        return cls.from_map_key(doc, str(int(port_id)))

    @staticmethod
    def each_from_document(doc: Dict[str, Any]) -> Iterator[FiberRadioPort]:
        """All ``fiber_ports`` rows (sorted), including unmapped / empty values."""
        ports = doc.get("fiber_ports") if isinstance(doc, dict) else None
        if not isinstance(ports, dict):
            return
        for key in sorted(ports.keys(), key=fm.fiber_sort_key):
            ent = ports[key]
            yield FiberRadioPort(
                str(key),
                ent if isinstance(ent, dict) else None,
            )


def load_fiber_radio_ports(doc: Dict[str, Any]) -> List[FiberRadioPort]:
    """Registry of all fiber map rows (sorted keys)."""
    return list(FiberRadioPort.each_from_document(doc))
