"""System information endpoints — network, subsystems, dashboard binding."""

from __future__ import annotations

import asyncio
import os
import platform
import socket
import sys
from typing import Any

from fastapi import APIRouter

from Project.Sanad.config import (
    BASE_DIR,
    DASHBOARD_HOST,
    DASHBOARD_INTERFACE,
    DASHBOARD_PORT,
    DDS_NETWORK_INTERFACE,
    list_network_interfaces,
)
from Project.Sanad.core.logger import get_logger

log = get_logger("system_route")

router = APIRouter()


def _safe_status(component, name: str) -> dict[str, Any]:
    if component is None:
        return {"available": False}
    try:
        if hasattr(component, "status") and callable(component.status):
            s = component.status()
            if not isinstance(s, dict):
                s = {"raw": str(s)}
            s.setdefault("available", True)
            return s
        return {"available": True}
    except Exception as exc:
        log.warning("status() failed for %s: %s", name, exc)
        return {"available": True, "error": str(exc)}


@router.get("/info")
async def system_info():
    """One-shot system snapshot for the dashboard system panel."""
    def _do():
        # Subsystems
        try:
            from Project.Sanad.main import SUBSYSTEMS
        except Exception:
            SUBSYSTEMS = {}

        subsystem_list = []
        for name in sorted(SUBSYSTEMS):
            comp = SUBSYSTEMS[name]
            entry = {
                "name": name,
                "connected": comp is not None,
            }
            if comp is not None and hasattr(comp, "status") and callable(comp.status):
                try:
                    s = comp.status()
                    if isinstance(s, dict):
                        entry["status"] = s
                except Exception as exc:
                    entry["status_error"] = str(exc)
            subsystem_list.append(entry)

        connected_count = sum(1 for s in subsystem_list if s["connected"])

        # Audio device current selection (best-effort)
        audio_info = {}
        try:
            from Project.Sanad.voice import audio_devices as ad
            audio_info = {
                "pactl_available": ad.pactl_available(),
                "current": ad.current_selection(),
                "detected_profile_ids": [
                    d["profile"]["id"] for d in ad.detect_plugged_profiles()
                ] if ad.pactl_available() else [],
            }
        except Exception as exc:
            audio_info = {"error": str(exc)}

        # Network interfaces
        try:
            interfaces = list_network_interfaces()
        except Exception:
            interfaces = []

        # Determine the URL the dashboard is reachable at
        bound_host = DASHBOARD_HOST
        if bound_host == "0.0.0.0":
            # Try to find the wlan0 IP for display purposes
            up_ifaces = [i for i in interfaces if i["is_up"] and i["ip"] and not i["ip"].startswith("127.")]
            display_host = up_ifaces[0]["ip"] if up_ifaces else bound_host
        else:
            display_host = bound_host

        return {
            "host": {
                "hostname": socket.gethostname(),
                "platform": platform.platform(),
                "python": sys.version.split()[0],
                "executable": sys.executable,
                "base_dir": str(BASE_DIR),
                "pid": os.getpid(),
            },
            "dashboard": {
                "interface": DASHBOARD_INTERFACE,
                "bound_host": bound_host,
                "display_host": display_host,
                "port": DASHBOARD_PORT,
                "url": f"http://{display_host}:{DASHBOARD_PORT}",
            },
            "dds": {
                "interface": DDS_NETWORK_INTERFACE,
            },
            "network": {
                "interfaces": interfaces,
            },
            "subsystems": {
                "total": len(subsystem_list),
                "connected": connected_count,
                "disconnected": len(subsystem_list) - connected_count,
                "list": subsystem_list,
            },
            "audio": audio_info,
        }

    return await asyncio.to_thread(_do)
