"""UPnP data models for TUI display."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Literal

# Flux API ports - these are the standard ports used by Flux nodes
FluxApiPorts = Literal[16127, 16137, 16147, 16157, 16167, 16177, 16187, 16197]

FLUX_API_PORTS: list[FluxApiPorts] = [
    16127,
    16137,
    16147,
    16157,
    16167,
    16177,
    16187,
    16197,
]


@dataclass
class UpnpLease:
    """UPnP port mapping lease information."""

    host: str
    remaining_s: int

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> UpnpLease:
        """Create from RPC response dict."""
        return cls(
            host=data.get("host", ""),
            remaining_s=data.get("remaining_s", 0),
        )

    def as_dict(self) -> dict[str, Any]:
        """Convert to dict for RPC calls."""
        return {
            "host": self.host,
            "remaining_s": self.remaining_s,
        }


@dataclass
class AddMappingResult:
    """Result of adding a UPnP port mapping."""

    port: int
    lease: UpnpLease | None = None

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> AddMappingResult:
        """Create from RPC response dict."""
        lease_data = data.get("lease")
        lease = UpnpLease.from_dict(lease_data) if lease_data else None
        return cls(
            port=data.get("port", 0),
            lease=lease,
        )

    def as_dict(self) -> dict[str, Any]:
        """Convert to dict."""
        return {
            "port": self.port,
            "host": self.lease.host if self.lease else "",
            "remaining": self.lease.remaining_s if self.lease else "",
        }

    @property
    def success(self) -> bool:
        """Check if mapping was successful."""
        return self.lease is not None


@dataclass
class UpnpStatus:
    """UPnP IGD status information."""

    igd_available: bool = False
    igd_address: str | None = None
    client_address: str | None = None
    external_ip: str | None = None
    port_map: dict[int, UpnpLease] = field(default_factory=dict)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> UpnpStatus:
        """Create from RPC response dict."""
        port_map_data = data.get("port_map", {})
        port_map = {int(k): UpnpLease.from_dict(v) for k, v in port_map_data.items()}
        return cls(
            igd_available=data.get("igd_available", False),
            igd_address=data.get("igd_address"),
            client_address=data.get("client_address"),
            external_ip=data.get("external_ip"),
            port_map=port_map,
        )

    @property
    def host_to_port_map(self) -> dict[str, int]:
        """Get reverse mapping of host to port."""
        return {v.host: k for k, v in self.port_map.items()}
