"""WiFi manager for network configuration and mode switching."""
import asyncio
import logging
import re
import subprocess
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional, Dict
from pathlib import Path

from .. import config

logger = logging.getLogger(__name__)

# Persistent storage for WiFi mode
WIFI_MODE_FILE = Path("/opt/dangerous-pi/data/wifi_mode")
WIFI_DATA_DIR = Path("/opt/dangerous-pi/data")


class WiFiMode(str, Enum):
    """WiFi operation modes."""
    AP = "ap"  # Access Point only
    CLIENT = "client"  # Client mode only
    DUAL = "dual"  # AP + Client (requires USB WiFi)
    AUTO = "auto"  # Automatically choose best mode
    OFF = "off"  # WiFi disabled


@dataclass
class WiFiInterface:
    """WiFi interface information."""
    name: str
    mac: str
    is_usb: bool
    is_up: bool
    connected: bool
    ssid: Optional[str] = None
    ip_address: Optional[str] = None
    mode: str = "managed"  # "AP" or "managed" (client)


@dataclass
class WiFiNetwork:
    """Available WiFi network."""
    ssid: str
    bssid: str
    signal_strength: int
    frequency: int
    encrypted: bool
    in_use: bool = False


@dataclass
class WiFiStatus:
    """Current WiFi status."""
    mode: WiFiMode
    interfaces: List[WiFiInterface]
    current_ssid: Optional[str]
    current_ip: Optional[str]
    ap_ssid: Optional[str]
    ap_ip: Optional[str]
    supports_dual: bool


class WiFiManager:
    """Manages WiFi configuration and mode switching."""

    def __init__(self):
        """Initialize WiFi manager."""
        self._current_mode = WiFiMode.AUTO
        self._interfaces: List[WiFiInterface] = []
        self._supports_dual = False
        self._startup_applied = False

    def _save_mode(self, mode: WiFiMode) -> bool:
        """Save WiFi mode to persistent storage.

        Args:
            mode: WiFi mode to save

        Returns:
            True if saved successfully
        """
        try:
            # Ensure data directory exists
            WIFI_DATA_DIR.mkdir(parents=True, exist_ok=True)

            # Write mode to file
            WIFI_MODE_FILE.write_text(mode.value)
            logger.info(f"WiFi mode saved: {mode.value}")
            return True
        except Exception as e:
            logger.error(f"Failed to save WiFi mode: {e}")
            return False

    def _load_mode(self) -> Optional[WiFiMode]:
        """Load WiFi mode from persistent storage.

        Returns:
            Saved WiFi mode or None if not found
        """
        try:
            if WIFI_MODE_FILE.exists():
                mode_str = WIFI_MODE_FILE.read_text().strip()
                mode = WiFiMode(mode_str)
                logger.info(f"WiFi mode loaded: {mode.value}")
                return mode
        except Exception as e:
            logger.warning(f"Failed to load WiFi mode: {e}")
        return None

    async def apply_saved_mode(self) -> bool:
        """Apply the saved WiFi mode on startup.

        This should be called once during service startup to restore
        the previously configured WiFi mode.

        Returns:
            True if mode was applied successfully
        """
        if self._startup_applied:
            logger.debug("Saved mode already applied, skipping")
            return True

        saved_mode = self._load_mode()
        if saved_mode:
            logger.info(f"Applying saved WiFi mode: {saved_mode.value}")
            success = await self.set_mode(saved_mode, persist=False)  # Don't re-save
            self._startup_applied = True
            return success
        else:
            logger.info("No saved WiFi mode found, using default (AUTO)")
            self._startup_applied = True
            return True

    async def detect_interfaces(self) -> List[WiFiInterface]:
        """Detect available WiFi interfaces.

        Returns:
            List of WiFi interfaces found
        """
        interfaces = []

        try:
            # Get all wireless interfaces using iw
            result = await self._run_command("iw dev")

            if not result:
                return interfaces

            # Parse iw dev output
            # Example output:
            # phy#0
            #     Interface wlan0
            #         ifindex 2
            #         wdev 0x1
            #         addr 2c:cf:67:87:db:13
            #         ssid Dangerous-Pi
            #         type AP
            #         channel 6 (2437 MHz), width: 20 MHz
            current_interface = None
            for line in result.split('\n'):
                line = line.strip()

                if line.startswith('Interface '):
                    if current_interface:
                        interfaces.append(current_interface)

                    iface_name = line.split()[1]
                    current_interface = {
                        'name': iface_name,
                        'mac': '',
                        'is_usb': self._is_usb_interface(iface_name),
                        'is_up': False,
                        'connected': False,
                        'ssid': None,
                        'ip_address': None,
                        'mode': 'managed'  # Default to managed (client) mode
                    }

                elif current_interface and line.startswith('addr '):
                    current_interface['mac'] = line.split()[1]

                elif current_interface and line.startswith('ssid '):
                    current_interface['ssid'] = ' '.join(line.split()[1:])

                elif current_interface and line.startswith('type '):
                    # Parse interface type: "AP" or "managed"
                    iface_type = line.split()[1]
                    current_interface['mode'] = iface_type
                    # Only mark as "connected" if in managed (client) mode with SSID
                    if iface_type == 'managed' and current_interface.get('ssid'):
                        current_interface['connected'] = True

            if current_interface:
                interfaces.append(current_interface)

            # Get interface status and IP addresses
            for iface_dict in interfaces:
                # Check if interface is up
                iface_dict['is_up'] = await self._is_interface_up(iface_dict['name'])

                # Get IP address if interface is up
                if iface_dict['is_up']:
                    iface_dict['ip_address'] = await self._get_interface_ip(iface_dict['name'])

                # For AP mode, mark connected if we have IP (AP is "active")
                if iface_dict['mode'] == 'AP' and iface_dict['ip_address']:
                    iface_dict['connected'] = True

            # Convert dicts to WiFiInterface objects
            self._interfaces = [WiFiInterface(**iface) for iface in interfaces]

            # Check if dual mode is supported (requires at least 2 interfaces)
            self._supports_dual = len(self._interfaces) >= 2

            return self._interfaces

        except Exception as e:
            print(f"Error detecting WiFi interfaces: {e}")
            return []

    def _is_usb_interface(self, iface_name: str) -> bool:
        """Check if interface is USB-based.

        Args:
            iface_name: Interface name (e.g., wlan0)

        Returns:
            True if USB interface, False otherwise
        """
        try:
            # Check if device is USB by looking at sysfs
            device_path = Path(f"/sys/class/net/{iface_name}/device")
            if not device_path.exists():
                return False

            # Read uevent to check for USB
            uevent_path = device_path / "uevent"
            if uevent_path.exists():
                content = uevent_path.read_text()
                return "usb" in content.lower()

            return False
        except Exception:
            return False

    async def _is_interface_up(self, iface_name: str) -> bool:
        """Check if interface is up.

        Args:
            iface_name: Interface name

        Returns:
            True if interface is up
        """
        try:
            result = await self._run_command(f"ip link show {iface_name}")
            return "UP" in result
        except Exception:
            return False

    async def _get_interface_ip(self, iface_name: str) -> Optional[str]:
        """Get IP address of interface.

        Args:
            iface_name: Interface name

        Returns:
            IP address or None
        """
        try:
            result = await self._run_command(f"ip -4 addr show {iface_name}")
            match = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', result)
            return match.group(1) if match else None
        except Exception:
            return None

    async def get_status(self) -> WiFiStatus:
        """Get current WiFi status.

        Returns:
            WiFiStatus object with current state
        """
        await self.detect_interfaces()

        # Determine current mode
        current_mode = await self._detect_current_mode()

        # Find client and AP interfaces
        client_ssid = None
        client_ip = None
        ap_ssid = None
        ap_ip = None

        for iface in self._interfaces:
            # Check for AP mode interface
            if iface.mode == 'AP':
                ap_ip = iface.ip_address
                ap_ssid = iface.ssid  # SSID from iw dev output
                # If no SSID from iw, try hostapd config
                if not ap_ssid:
                    ap_ssid = await self._get_ap_ssid()

            # Check for client mode interface that's connected
            elif iface.mode == 'managed' and iface.connected and iface.ssid:
                client_ssid = iface.ssid
                client_ip = iface.ip_address

        # Fallback: try to get AP SSID from hostapd if we detected AP mode
        if current_mode == WiFiMode.AP and not ap_ssid:
            ap_ssid = await self._get_ap_ssid()

        return WiFiStatus(
            mode=current_mode,
            interfaces=self._interfaces,
            current_ssid=client_ssid,
            current_ip=client_ip,
            ap_ssid=ap_ssid or "Dangerous-Pi",  # Default
            ap_ip=ap_ip,
            supports_dual=self._supports_dual
        )

    async def _detect_current_mode(self) -> WiFiMode:
        """Detect current WiFi mode based on interface types.

        Returns:
            Current WiFi mode
        """
        if not self._interfaces:
            return WiFiMode.OFF

        # Check interface modes from iw dev output
        has_ap = any(iface.mode == 'AP' for iface in self._interfaces)
        has_client = any(
            iface.mode == 'managed' and iface.connected
            for iface in self._interfaces
        )

        # Also check if hostapd is running as backup detection
        if not has_ap:
            has_ap = await self._is_hostapd_running()

        if has_ap and has_client:
            return WiFiMode.DUAL
        elif has_ap:
            return WiFiMode.AP
        elif has_client:
            return WiFiMode.CLIENT
        elif any(iface.is_up for iface in self._interfaces):
            return WiFiMode.AUTO  # Interface up but not in AP or connected
        else:
            return WiFiMode.OFF

    async def _is_hostapd_running(self) -> bool:
        """Check if hostapd service is running.

        Returns:
            True if hostapd is active
        """
        try:
            result = await self._run_command(
                "systemctl is-active hostapd",
                check=False
            )
            return result.strip() == "active"
        except Exception:
            return False

    async def _get_ap_ssid(self) -> Optional[str]:
        """Get AP SSID from hostapd config.

        Returns:
            AP SSID or None
        """
        try:
            config_path = Path("/etc/hostapd/hostapd.conf")
            if config_path.exists():
                content = config_path.read_text()
                match = re.search(r'ssid=(.+)', content)
                return match.group(1) if match else None
        except Exception:
            return None

    async def scan_networks(self, interface: Optional[str] = None) -> List[WiFiNetwork]:
        """Scan for available WiFi networks.

        Args:
            interface: Interface to scan with (default: first available)

        Returns:
            List of available networks
        """
        # Ensure interfaces are detected
        if not self._interfaces:
            await self.detect_interfaces()

        if not interface:
            # Use first non-USB interface, or first available
            for iface in self._interfaces:
                if not iface.is_usb:
                    interface = iface.name
                    break

            if not interface and self._interfaces:
                interface = self._interfaces[0].name

        if not interface:
            return []

        try:
            # Request scan
            # Note: Requires CAP_NET_ADMIN capability (set via systemd service)
            await self._run_command(f"iw dev {interface} scan trigger", check=False)

            # Wait for scan to complete
            await asyncio.sleep(2)

            # Get scan results
            result = await self._run_command(f"iw dev {interface} scan")

            networks = []
            current_network = None

            for line in result.split('\n'):
                line = line.strip()

                if line.startswith('BSS ') and line.split()[1].count(':') >= 5:
                    # Match BSS lines with MAC addresses (xx:xx:xx:xx:xx:xx), not "BSS Load:" etc.
                    if current_network:
                        networks.append(current_network)

                    # Handle format: BSS aa:bb:cc:dd:ee:ff(on wlan0)
                    bssid = line.split()[1].split('(')[0]
                    current_network = {
                        'ssid': '',
                        'bssid': bssid,
                        'signal_strength': 0,
                        'frequency': 0,
                        'encrypted': False,
                        'in_use': False
                    }

                elif current_network:
                    if line.startswith('SSID: '):
                        current_network['ssid'] = line[6:]
                    elif line.startswith('freq: '):
                        # freq can be "2437" or "2437.0" depending on iw version
                        current_network['frequency'] = int(float(line[6:]))
                    elif line.startswith('signal: '):
                        # Parse signal strength (e.g., "-50.00 dBm")
                        signal = line[8:].split()[0]
                        current_network['signal_strength'] = int(float(signal))
                    elif 'RSN:' in line or 'WPA:' in line:
                        current_network['encrypted'] = True

            if current_network:
                networks.append(current_network)

            # Convert to WiFiNetwork objects and filter out empty SSIDs
            return [
                WiFiNetwork(**net)
                for net in networks
                if net['ssid']
            ]

        except Exception as e:
            print(f"Error scanning networks: {e}")
            return []

    async def set_mode(self, mode: WiFiMode, persist: bool = True) -> bool:
        """Set WiFi mode.

        Args:
            mode: Desired WiFi mode
            persist: If True, save mode to persistent storage for boot persistence

        Returns:
            True if mode was set successfully
        """
        if mode == WiFiMode.DUAL and not self._supports_dual:
            raise ValueError("Dual mode requires USB WiFi adapter")

        try:
            if mode == WiFiMode.AP:
                await self._enable_ap_mode()
            elif mode == WiFiMode.CLIENT:
                await self._enable_client_mode()
            elif mode == WiFiMode.DUAL:
                await self._enable_dual_mode()
            elif mode == WiFiMode.OFF:
                await self._disable_wifi()
            elif mode == WiFiMode.AUTO:
                await self._enable_auto_mode()

            self._current_mode = mode

            # Persist mode for boot persistence
            if persist:
                self._save_mode(mode)

            return True
        except Exception as e:
            print(f"Error setting WiFi mode: {e}")
            return False

    async def _systemctl(self, action: str, service: str):
        """Control systemd service via dbus (no sudo required with polkit rule).

        Args:
            action: "start", "stop", or "restart"
            service: Service name (e.g., "hostapd.service")
        """
        if not service.endswith(".service"):
            service = f"{service}.service"

        method = {
            "start": "StartUnit",
            "stop": "StopUnit",
            "restart": "RestartUnit"
        }.get(action, "StartUnit")

        cmd = (
            f'busctl call org.freedesktop.systemd1 '
            f'/org/freedesktop/systemd1 org.freedesktop.systemd1.Manager '
            f'{method} ss "{service}" "replace"'
        )
        await self._run_command(cmd, check=False)

    async def _enable_nm_management(self):
        """Enable NetworkManager to manage wlan0 for client mode.

        Uses nmcli to set wlan0 as managed (no file permissions needed).
        """
        import logging
        logger = logging.getLogger(__name__)

        # Check current device status
        status = await self._run_command("nmcli device status", check=False)
        logger.warning(f"[NM Management] Current status:\n{status}")

        # Use nmcli to set device as managed (works without root)
        logger.warning("[NM Management] Setting wlan0 as managed...")
        result = await self._run_command("nmcli device set wlan0 managed yes", check=False)
        logger.warning(f"[NM Management] nmcli set managed result: '{result}'")

        # Give NM time to pick up the device
        logger.warning("[NM Management] Waiting 2s...")
        await asyncio.sleep(2)

        # Verify device is now managed
        status = await self._run_command("nmcli device status", check=False)
        logger.warning(f"[NM Management] Status after:\n{status}")

    async def _disable_nm_management(self):
        """Disable NetworkManager management of wlan0 for AP mode.

        Uses nmcli to set wlan0 as unmanaged (for hostapd).
        """
        import logging
        logger = logging.getLogger(__name__)

        # Use nmcli to set device as unmanaged
        logger.warning("[NM Management] Setting wlan0 as unmanaged...")
        result = await self._run_command("nmcli device set wlan0 managed no", check=False)
        logger.warning(f"[NM Management] nmcli set unmanaged result: '{result}'")
        await asyncio.sleep(1)

    async def _enable_ap_mode(self):
        """Enable Access Point mode."""
        # Ensure NM doesn't manage wlan0
        await self._disable_nm_management()
        # Start hostapd and dnsmasq for AP
        await self._systemctl("start", "hostapd")
        await self._systemctl("start", "dnsmasq")
        # Set static IP for AP
        await self._run_command("ip addr add 192.168.4.1/24 dev wlan0", check=False)
        print("AP mode enabled")

    async def _enable_client_mode(self):
        """Enable Client mode using NetworkManager."""
        import logging
        logger = logging.getLogger(__name__)

        # Stop AP services
        logger.warning("[Client Mode] Stopping hostapd...")
        await self._systemctl("stop", "hostapd")
        logger.warning("[Client Mode] Stopping dnsmasq...")
        await self._systemctl("stop", "dnsmasq")

        # Check hostapd status
        hostapd_status = await self._run_command("systemctl is-active hostapd", check=False)
        logger.warning(f"[Client Mode] hostapd status after stop: {hostapd_status.strip()}")

        # Enable NetworkManager to manage wlan0
        logger.warning("[Client Mode] Enabling NM management...")
        await self._enable_nm_management()
        logger.warning("[Client Mode] Client mode enabled")

    async def _enable_dual_mode(self):
        """Enable Dual mode (AP + Client)."""
        # Enable both AP and client
        await self._systemctl("start", "hostapd")
        await self._systemctl("start", "dnsmasq")
        await self._systemctl("start", "wpa_supplicant")
        print("Dual mode enabled")

    async def _disable_wifi(self):
        """Disable all WiFi."""
        await self._systemctl("stop", "hostapd")
        await self._systemctl("stop", "dnsmasq")
        await self._systemctl("stop", "wpa_supplicant")
        print("WiFi disabled")

    async def _enable_auto_mode(self):
        """Enable Auto mode."""
        # Auto-detect best mode based on saved networks and hardware
        if self._supports_dual:
            await self._enable_dual_mode()
        else:
            # Check if we have saved networks
            saved_networks = await self.get_saved_networks()
            if saved_networks:
                await self._enable_client_mode()
            else:
                await self._enable_ap_mode()
        print("Auto mode enabled")

    async def connect_to_network(
        self,
        ssid: str,
        password: Optional[str] = None,
        interface: Optional[str] = None,
        hidden: bool = False,
        fallback_to_ap: bool = True
    ) -> bool:
        """Connect to a WiFi network using NetworkManager.

        Args:
            ssid: Network SSID
            password: Network password (if encrypted)
            interface: Interface to use (default: first available)
            hidden: Whether network is hidden
            fallback_to_ap: If True, revert to AP mode on connection failure

        Returns:
            True if connection successful
        """
        # Ensure interfaces are detected before trying to connect
        if not self._interfaces:
            await self.detect_interfaces()

        if not interface:
            # Use first non-USB interface, or first available
            for iface in self._interfaces:
                if not iface.is_usb:
                    interface = iface.name
                    break
            if not interface and self._interfaces:
                interface = self._interfaces[0].name

        if not interface:
            import logging
            logger = logging.getLogger(__name__)
            logger.warning("[WiFi Connect] No interface found!")
            return False

        try:
            import logging
            logger = logging.getLogger(__name__)

            logger.warning(f"[WiFi Connect] Starting connect to {ssid}")

            # Switch to client mode (stops hostapd, enables NM management)
            logger.warning("[WiFi Connect] Step 1: Enabling client mode...")
            await self._enable_client_mode()
            logger.warning("[WiFi Connect] Step 1: Client mode enabled")

            # Wait for NM to be ready and detect wlan0
            logger.warning("[WiFi Connect] Step 2: Waiting 2s for NM...")
            await asyncio.sleep(2)

            # Check device status
            dev_status = await self._run_command("nmcli device status", check=False)
            logger.warning(f"[WiFi Connect] Device status after wait:\n{dev_status}")

            # Delete any existing saved connection for this SSID
            # (handles corrupted connections with missing key-mgmt property)
            ssid_escaped = ssid.replace("'", "'\\''")
            logger.warning(f"[WiFi Connect] Step 3: Deleting existing connection for {ssid}...")
            del_result = await self._run_command(
                f"nmcli connection delete '{ssid_escaped}'",
                check=False
            )
            logger.warning(f"[WiFi Connect] Delete result: {del_result}")
            await asyncio.sleep(1)

            # Build nmcli connect command
            cmd = f"nmcli device wifi connect '{ssid_escaped}'"

            if password:
                password_escaped = password.replace("'", "'\\''")
                cmd += f" password '{password_escaped}'"

            if hidden:
                cmd += " hidden yes"

            # Attempt connection
            logger.warning(f"[WiFi Connect] Step 4: Running nmcli connect...")
            result = await self._run_command(cmd, check=False)
            logger.warning(f"[WiFi Connect] Connect result: {result}")

            # Check if connection was successful
            if "successfully activated" in result.lower():
                logger.warning(f"[WiFi Connect] SUCCESS - connected to {ssid}")

                # Verify we have an IP address
                await asyncio.sleep(2)
                ip_result = await self._run_command(f"ip addr show {interface}")
                logger.warning(f"[WiFi Connect] IP result: {ip_result}")
                if "inet " in ip_result and "192.168.4." not in ip_result:
                    # Save client mode for boot persistence
                    self._current_mode = WiFiMode.CLIENT
                    self._save_mode(WiFiMode.CLIENT)
                    logger.info(f"WiFi client mode saved for boot persistence")
                    return True

            # Connection failed
            logger.warning(f"[WiFi Connect] FAILED - {result}")

            if fallback_to_ap:
                print("Falling back to AP mode...")
                await self._enable_ap_mode()

            return False

        except Exception as e:
            print(f"Error connecting to network: {e}")
            return False

    async def _add_network_via_wpa_cli(self, ssid: str, password: Optional[str], hidden: bool):
        """Add network using wpa_cli commands."""
        try:
            # Add network
            result = await self._run_command("sudo wpa_cli add_network")
            network_id = result.strip().split('\n')[-1]

            # Set SSID
            await self._run_command(f'sudo wpa_cli set_network {network_id} ssid \\"{ssid}\\"')

            # Set password or open network
            if password:
                await self._run_command(f'sudo wpa_cli set_network {network_id} psk \\"{password}\\"')
            else:
                await self._run_command(f'sudo wpa_cli set_network {network_id} key_mgmt NONE')

            # Set scan_ssid for hidden networks
            if hidden:
                await self._run_command(f'sudo wpa_cli set_network {network_id} scan_ssid 1')

            # Enable network
            await self._run_command(f'sudo wpa_cli enable_network {network_id}')

            # Save configuration
            await self._run_command('sudo wpa_cli save_config')

            return True
        except Exception as e:
            print(f"Error adding network via wpa_cli: {e}")
            return False

    async def disconnect_from_network(self, interface: Optional[str] = None) -> bool:
        """Disconnect from current network and return to AP mode.

        Args:
            interface: Interface to disconnect (default: first connected)

        Returns:
            True if disconnection successful
        """
        if not interface:
            for iface in self._interfaces:
                if iface.connected:
                    interface = iface.name
                    break

        if not interface:
            return False

        try:
            # Disconnect using nmcli
            await self._run_command(f"nmcli device disconnect {interface}", check=False)
            # Return to AP mode
            await self._enable_ap_mode()
            return True
        except Exception as e:
            print(f"Error disconnecting: {e}")
            return False

    async def get_saved_networks(self) -> List[Dict[str, str]]:
        """Get list of saved WiFi networks from NetworkManager.

        Returns:
            List of saved networks with SSID and other info
        """
        try:
            result = await self._run_command(
                "nmcli -t -f NAME,TYPE connection show",
                check=False
            )
            networks = []

            for line in result.split('\n'):
                if line.strip():
                    parts = line.split(':')
                    if len(parts) >= 2 and parts[1] == '802-11-wireless':
                        networks.append({
                            'ssid': parts[0],
                            'type': 'wifi',
                            'enabled': True
                        })

            return networks
        except Exception as e:
            print(f"Error getting saved networks: {e}")
            return []

    async def forget_network(self, ssid: str) -> bool:
        """Forget a saved network.

        Args:
            ssid: SSID of network to forget

        Returns:
            True if network was forgotten
        """
        try:
            # Delete connection using nmcli
            ssid_escaped = ssid.replace("'", "'\\''")
            result = await self._run_command(
                f"nmcli connection delete '{ssid_escaped}'",
                check=False
            )

            return "successfully deleted" in result.lower()
        except Exception as e:
            print(f"Error forgetting network: {e}")
            return False

    async def set_static_ip(
        self,
        interface: str,
        ip_address: str,
        netmask: str = "255.255.255.0",
        gateway: Optional[str] = None,
        dns: Optional[List[str]] = None
    ) -> bool:
        """Set static IP for interface.

        Args:
            interface: Interface name
            ip_address: Static IP address
            netmask: Network mask
            gateway: Gateway IP (optional)
            dns: DNS servers (optional)

        Returns:
            True if configuration successful
        """
        try:
            # Configure static IP using dhcpcd
            config_path = Path("/etc/dhcpcd.conf")

            # Read existing config
            if config_path.exists():
                content = config_path.read_text()
            else:
                content = ""

            # Remove existing config for this interface
            lines = content.split('\n')
            new_lines = []
            skip_interface = False

            for line in lines:
                if line.startswith(f'interface {interface}'):
                    skip_interface = True
                    continue
                if skip_interface and (line.startswith('interface ') or line.strip() == ''):
                    skip_interface = False
                if not skip_interface:
                    new_lines.append(line)

            # Add new configuration
            new_config = f"\ninterface {interface}\n"
            new_config += f"static ip_address={ip_address}/{self._netmask_to_cidr(netmask)}\n"

            if gateway:
                new_config += f"static routers={gateway}\n"

            if dns:
                new_config += f"static domain_name_servers={' '.join(dns)}\n"

            new_content = '\n'.join(new_lines) + new_config

            # Write configuration (would need sudo)
            # In production, this should use a proper mechanism
            print(f"Would write to {config_path}:\n{new_config}")

            # Restart interface
            await self._run_command(f"sudo ip link set {interface} down")
            await self._run_command(f"sudo ip link set {interface} up")
            await self._run_command("sudo systemctl restart dhcpcd")

            return True
        except Exception as e:
            print(f"Error setting static IP: {e}")
            return False

    def _netmask_to_cidr(self, netmask: str) -> int:
        """Convert netmask to CIDR notation.

        Args:
            netmask: Netmask (e.g., 255.255.255.0)

        Returns:
            CIDR prefix length (e.g., 24)
        """
        return sum([bin(int(x)).count('1') for x in netmask.split('.')])

    async def enable_dhcp(self, interface: str) -> bool:
        """Enable DHCP for interface.

        Args:
            interface: Interface name

        Returns:
            True if DHCP enabled
        """
        try:
            # Remove static IP configuration
            config_path = Path("/etc/dhcpcd.conf")

            if config_path.exists():
                content = config_path.read_text()
                lines = content.split('\n')
                new_lines = []
                skip_interface = False

                for line in lines:
                    if line.startswith(f'interface {interface}'):
                        skip_interface = True
                        continue
                    if skip_interface and (line.startswith('interface ') or line.strip() == ''):
                        skip_interface = False
                    if not skip_interface:
                        new_lines.append(line)

                # Write back
                print(f"Would update {config_path} to enable DHCP")

            # Restart interface
            await self._run_command(f"sudo ip link set {interface} down")
            await self._run_command(f"sudo ip link set {interface} up")
            await self._run_command("sudo systemctl restart dhcpcd")

            return True
        except Exception as e:
            print(f"Error enabling DHCP: {e}")
            return False

    async def _run_command(self, command: str, check: bool = True) -> str:
        """Run a shell command asynchronously.

        Args:
            command: Command to run
            check: Raise exception on non-zero exit code

        Returns:
            Command output

        Raises:
            subprocess.CalledProcessError: If command fails and check=True
        """
        loop = asyncio.get_event_loop()

        def _execute():
            result = subprocess.run(
                command,
                shell=True,
                capture_output=True,
                text=True,
                check=check
            )
            return result.stdout

        return await loop.run_in_executor(None, _execute)


# Global instance
wifi_manager = WiFiManager()
