"""
📡 BLE GATT Server for BlueLobster.

Advertises a writable characteristic for receiving messages from your phone.
Optimized for horizontal development.
"""

import asyncio
import logging
import platform
from typing import Callable, Awaitable, Optional
from dataclasses import dataclass

logger = logging.getLogger(__name__)

# BlueLobster Service UUIDs
SERVICE_UUID = "12345678-1234-5678-1234-56789abcdef0"
WRITE_CHAR_UUID = "12345678-1234-5678-1234-56789abcdef1"
NOTIFY_CHAR_UUID = "12345678-1234-5678-1234-56789abcdef2"


@dataclass
class BLEConfig:
    """Configuration for the BLE server."""
    service_uuid: str = SERVICE_UUID
    write_char_uuid: str = WRITE_CHAR_UUID
    notify_char_uuid: str = NOTIFY_CHAR_UUID
    device_name: str = "BlueLobster"


class BLEServer:
    """
    BLE GATT Server that accepts text input from mobile devices.
    
    Platform support:
    - macOS: Uses CoreBluetooth via pyobjc
    - Linux: Uses BlueZ D-Bus API via dbus-next
    """
    
    def __init__(
        self,
        config: Optional[BLEConfig] = None,
        on_message: Optional[Callable[[str], Awaitable[None]]] = None,
    ):
        """
        Initialize the BLE server.
        
        Args:
            config: BLE configuration (UUIDs, device name).
            on_message: Async callback when a message is received.
        """
        self.config = config or BLEConfig()
        self.on_message = on_message
        self._running = False
        self._server = None
        self._system = platform.system()
    
    async def start(self) -> bool:
        """
        Start the BLE GATT server.
        
        Returns:
            True if server started successfully, False otherwise.
        """
        logger.info(f"Starting BlueLobster BLE server on {self._system}...")
        logger.info(f"Service UUID: {self.config.service_uuid}")
        logger.info(f"Write Characteristic: {self.config.write_char_uuid}")
        
        try:
            if self._system == "Darwin":
                return await self._start_macos()
            elif self._system == "Linux":
                return await self._start_linux()
            else:
                logger.error(f"❌ Unsupported platform: {self._system}")
                logger.info("💡 BlueLobster supports macOS and Linux")
                return False
        except Exception as e:
            logger.error(f"❌ Failed to start BLE server: {e}")
            return False
    
    async def stop(self) -> None:
        """Stop the BLE server."""
        self._running = False
        if self._server:
            # Platform-specific cleanup would go here
            self._server = None
        logger.info("📡 BLE server stopped")
    
    def send_notification(self, text: str) -> bool:
        """
        Send a notification to connected clients.
        
        Args:
            text: Text to send as notification.
        
        Returns:
            True if sent successfully, False otherwise.
        """
        if not self._running or not self._server:
            logger.warning("⚠️ BLE server not running")
            return False
        
        # Delegate to platform-specific implementation
        if hasattr(self._server, 'send_notification'):
            return self._server.send_notification(text)
        
        logger.debug(f"📤 Would notify: {text[:50]}")
        return True
    
    async def _start_macos(self) -> bool:
        """Start BLE server on macOS using CoreBluetooth."""
        try:
            from .ble_macos import MacOSBLEServer
            self._server = MacOSBLEServer(self.config, self.on_message)
            self._running = True
            return await self._server.start()
        except ImportError:
            logger.error("❌ macOS BLE requires pyobjc-framework-CoreBluetooth")
            logger.info("💡 Install with: pip install 'bluelobster[macos]'")
            # Fall back to simulation mode
            return await self._start_simulation()
    
    async def _start_linux(self) -> bool:
        """Start BLE server on Linux using BlueZ D-Bus."""
        try:
            from .ble_linux import LinuxBLEServer
            self._server = LinuxBLEServer(self.config, self.on_message)
            self._running = True
            return await self._server.start()
        except ImportError:
            logger.error("❌ Linux BLE requires dbus-next")
            logger.info("💡 Install with: pip install 'bluelobster[linux]'")
            # Fall back to simulation mode
            return await self._start_simulation()
    
    async def _start_simulation(self) -> bool:
        """
        Start in simulation mode for testing without BLE hardware.
        
        Listens on stdin for messages instead of BLE.
        """
        logger.warning("🧪 Starting in SIMULATION mode (no BLE)")
        logger.info("💡 Type messages and press Enter to simulate BLE input")
        logger.info("💡 Type 'quit' to exit")
        
        self._running = True
        
        async def stdin_loop():
            loop = asyncio.get_event_loop()
            while self._running:
                try:
                    # Read from stdin in a non-blocking way
                    line = await loop.run_in_executor(None, input, "🦞 > ")
                    line = line.strip()
                    
                    if line.lower() == 'quit':
                        self._running = False
                        break
                    
                    if line and self.on_message:
                        await self.on_message(line)
                except EOFError:
                    break
                except Exception as e:
                    logger.error(f"Stdin error: {e}")
                    break
        
        # Start the stdin loop in background
        asyncio.create_task(stdin_loop())
        return True


def get_setup_instructions() -> str:
    """Get mobile app setup instructions."""
    return f"""
╔══════════════════════════════════════════════════════════════════╗
║                    🦞 BlueLobster Mobile Setup                   ║
╠══════════════════════════════════════════════════════════════════╣
║                                                                  ║
║  Service UUID:     {SERVICE_UUID}          ║
║  Write Char UUID:  {WRITE_CHAR_UUID}          ║
║  Notify Char UUID: {NOTIFY_CHAR_UUID}          ║
║                                                                  ║
║═════════════════════════════════════════════════════════════════╣
║  1. Build and run iOS app                                ║
║  2. Send messages to Clawdbot/Moltbot                       ║
║  3. Vibe from your couch                                      ║
╚══════════════════════════════════════════════════════════════════╝
"""
