"""WiFi management API endpoints.

Refactored to use WiFiService for all business logic.
Endpoints are now thin adapters that convert HTTP requests/responses.
"""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import List, Optional

from ..services.container import container

router = APIRouter()


class WiFiStatusResponse(BaseModel):
    """WiFi status response."""
    mode: str
    interfaces: List[dict]
    current_ssid: Optional[str]
    current_ip: Optional[str]
    ap_ssid: Optional[str]
    ap_ip: Optional[str]
    supports_dual: bool


class WiFiNetworkResponse(BaseModel):
    """WiFi network response."""
    ssid: str
    bssid: str
    signal_strength: int
    frequency: int
    encrypted: bool
    in_use: bool


class SetModeRequest(BaseModel):
    """Request to set WiFi mode."""
    mode: str  # "ap", "client", "dual", "auto", "off"


class ConnectRequest(BaseModel):
    """Request to connect to network."""
    ssid: str
    password: Optional[str] = None
    interface: Optional[str] = None
    hidden: bool = False


def _service_error_to_http_status(error_code: str) -> int:
    """Map service error codes to HTTP status codes.

    Args:
        error_code: Service error code

    Returns:
        HTTP status code
    """
    codes = {
        "wifi_status_error": 500,
        "wifi_scan_error": 500,
        "connection_failed": 503,
        "wifi_connect_error": 500,
        "disconnect_failed": 500,
        "wifi_disconnect_error": 500,
        "invalid_mode": 400,
        "mode_not_supported": 400,
        "mode_change_failed": 500,
        "wifi_mode_error": 500,
        "saved_networks_error": 500,
        "network_not_found": 404,
        "forget_network_error": 500,
    }
    return codes.get(error_code, 500)


@router.get("/status", response_model=WiFiStatusResponse)
async def get_wifi_status():
    """Get current WiFi status and available interfaces.

    Uses WiFiService for business logic.
    """
    result = await container.wifi_service.get_status()

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    data = result.data
    return WiFiStatusResponse(
        mode=data["mode"],
        interfaces=data["interfaces"],
        current_ssid=data["client"]["ssid"] if data.get("client") else None,
        current_ip=data["client"]["ip"] if data.get("client") else None,
        ap_ssid=data["access_point"]["ssid"],
        ap_ip=data["access_point"]["ip"],
        supports_dual=data["supports_dual"]
    )


@router.get("/scan", response_model=List[WiFiNetworkResponse])
async def scan_networks(interface: Optional[str] = None):
    """Scan for available WiFi networks.

    Uses WiFiService for business logic.

    Args:
        interface: Optional interface to scan with
    """
    result = await container.wifi_service.scan_networks(interface)

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return [
        WiFiNetworkResponse(**net)
        for net in result.data["networks"]
    ]


@router.post("/mode")
async def set_wifi_mode(request: SetModeRequest):
    """Set WiFi operation mode.

    Uses WiFiService for business logic.

    Args:
        request: Mode to set (ap, client, dual, auto, off)
    """
    result = await container.wifi_service.set_mode(request.mode)

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {
        "success": True,
        "message": result.data["message"],
        "mode": result.data["mode"]
    }


@router.post("/connect")
async def connect_to_network(request: ConnectRequest):
    """Connect to a WiFi network.

    Uses WiFiService for business logic.

    Args:
        request: Connection details (SSID, password, interface, hidden)
    """
    result = await container.wifi_service.connect(
        ssid=request.ssid,
        password=request.password,
        interface=request.interface,
        hidden=request.hidden
    )

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {
        "success": True,
        "message": result.data["message"],
        "ssid": result.data["ssid"],
        "ip": result.data.get("ip")
    }


@router.get("/interfaces")
async def get_interfaces():
    """Get available WiFi interfaces.

    Uses WiFiService for business logic.
    """
    result = await container.wifi_service.get_status()

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {
        "interfaces": result.data["interfaces"],
        "supports_dual": result.data["supports_dual"]
    }


@router.post("/disconnect")
async def disconnect_from_network(interface: Optional[str] = None):
    """Disconnect from current network.

    Uses WiFiService for business logic.

    Args:
        interface: Interface to disconnect (optional)
    """
    result = await container.wifi_service.disconnect(interface)

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {
        "success": True,
        "message": result.data["message"]
    }


@router.get("/saved")
async def get_saved_networks():
    """Get list of saved networks.

    Uses WiFiService for business logic.
    """
    result = await container.wifi_service.get_saved_networks()

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {"networks": result.data["networks"]}


@router.delete("/saved/{ssid}")
async def forget_network(ssid: str):
    """Forget a saved network.

    Uses WiFiService for business logic.

    Args:
        ssid: SSID of network to forget
    """
    result = await container.wifi_service.forget_network(ssid)

    if not result.success:
        raise HTTPException(
            status_code=_service_error_to_http_status(result.error.code),
            detail=result.error.message
        )

    return {
        "success": True,
        "message": result.data["message"]
    }


@router.post("/static-ip")
async def set_static_ip(
    interface: str,
    ip_address: str,
    netmask: str = "255.255.255.0",
    gateway: Optional[str] = None,
    dns: Optional[List[str]] = None,
):
    """Set static IP for interface.

    NOTE: This is a direct manager operation (not yet in WiFiService).
    TODO: Move to WiFiService in future iteration.

    Args:
        interface: Interface name
        ip_address: Static IP address
        netmask: Network mask (default: 255.255.255.0)
        gateway: Gateway IP (optional)
        dns: DNS servers (optional)
    """
    try:
        success = await container.wifi_manager.set_static_ip(
            interface, ip_address, netmask, gateway, dns
        )

        if not success:
            raise HTTPException(status_code=500, detail="Failed to set static IP")

        return {
            "success": True,
            "message": f"Static IP {ip_address} set for {interface}",
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to set static IP: {e}")


@router.post("/dhcp")
async def enable_dhcp(interface: str):
    """Enable DHCP for interface.

    NOTE: This is a direct manager operation (not yet in WiFiService).
    TODO: Move to WiFiService in future iteration.

    Args:
        interface: Interface name
    """
    try:
        success = await container.wifi_manager.enable_dhcp(interface)

        if not success:
            raise HTTPException(status_code=500, detail="Failed to enable DHCP")

        return {
            "success": True,
            "message": f"DHCP enabled for {interface}",
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to enable DHCP: {e}")
