import click
import os
import shutil

from .handler.serial_handler import auto_detect_port, send_serial_command, start_monitor

# Import flashing logic from the separate module
from .flash import (
    MEO_TELEMETRIX_GH_REPO, 
    MEO_FIRMWARE_GH_REPO, 
    get_latest_release_url, 
    download_firmware, 
    flash_binary
)

@click.group()
def cli():
    """MEO Tool - A command-line interface for managing MEO devices."""
    pass

@cli.command()
@click.argument('firmware')
@click.option('--latest', is_flag=True, help='Download latest binary from GitHub.')
@click.option('--auto-detect', is_flag=True, help='Auto-detect the serial port.')
@click.option('--port', help='Manually specify serial port.')
@click.option('--baud', default='460800', help='Flashing baud rate.')
def flash(firmware, latest, auto_detect, port, baud):
    """
    Flash firmware to a connected device.
    
    Example: meo flash thingbot-telemetrix --latest --auto-detect
    """
    # 1. Port Selection
    target_port = port
    if auto_detect:
        click.echo("Scanning for devices...")
        target_port = auto_detect_port()
        if target_port:
            click.echo(f"Found device at {target_port}")
        else:
            click.echo("No device found via auto-detect.")
            return

    if not target_port:
        click.echo("Error: No port specified. Use --port or --auto-detect.")
        return

    # 2. Firmware Acquisition
    bin_path = None
    tmp_dir = None

    if latest:
        # Determine which repo to use based on the firmware name
        fw_lower = firmware.lower()
        
        if "thingbot-telemetrix" in fw_lower:
            target_repo = MEO_TELEMETRIX_GH_REPO
        elif "thingbit-meo" in fw_lower:
            target_repo = MEO_FIRMWARE_GH_REPO
        else:
            # Return an error if the firmware keyword doesn't match known patterns
            click.echo(f"Firmware keyword '{firmware}' does not match known repositories.")
            return

        click.echo(f"Checking {target_repo} for updates...")
        url, name, size = get_latest_release_url(target_repo, firmware)
        
        if not url:
            click.echo(f"Could not find firmware matching '{firmware}' in latest release of {target_repo}.")
            return
            
        # Use the download function from flash.py
        bin_path, tmp_dir = download_firmware(url, name, size)
        
        if not bin_path:
            # Error handling is done inside download_firmware
            return
    else:
        # Check if user provided a local file path
        if os.path.exists(firmware):
            bin_path = firmware
        else:
            click.echo(f"Local file '{firmware}' not found. Did you mean to use --latest?")
            return

    # 3. Flashing
    try:
        flash_binary(target_port, baud, bin_path)
    finally:
        # Cleanup temp files if we created them
        if tmp_dir and os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
            
@cli.command()
@click.option('--port', help='Serial port')
@click.option('--baud', default=115200, help='Baud rate (default 115200)')
def monitor(port, baud):
    """
    Open a serial monitor to interact with the device.
    
    Usage: meo monitor --auto-detect
    """
    # If no port specified, try auto-detect
    target_port = port
    if not target_port:
        click.echo("Auto-detecting port...")
        target_port = auto_detect_port()
    
    if not target_port:
        click.echo("No device found. Please specify --port.")
        return
        
    start_monitor(target_port, baud)

# -------------------------------------------------------------------------
# GROUP: CONFIG
# -------------------------------------------------------------------------
@cli.group()
def config():
    """Configure device settings (WiFi, GPIO)."""
    pass

@config.command()
@click.argument('ssid')
@click.argument('password')
@click.option('--port', help='Serial port')
def wifi(ssid, password, port):
    """
    Set WiFi credentials.
    
    Usage: meo config wifi "MyNetwork" "SecretPass"
    """
    target = port or auto_detect_port()
    if not target:
        click.echo("No device found.")
        return

    # Format: WIFI:SSID:PASSWORD (Example protocol)
    cmd = f"WIFI:{ssid}:{password}"
    click.echo(f"Configuring WiFi on {target}...")
    send_serial_command(target, cmd)

@config.command()
@click.argument('pin', type=int)
@click.argument('modes', nargs=-1) # captures -input, -dht as a tuple
@click.option('--port', help='Serial port')
def gpio(pin, modes, port):
    """
    Configure a GPIO pin.
    
    Usage: meo config gpio 12 -input -pullup
    """
    target = port or auto_detect_port()
    if not target:
        click.echo("No device found.")
        return

    # Clean up modes (remove dashes if desired, or keep them)
    mode_str = ",".join(modes)
    
    # Format: GPIO:PIN:MODES
    cmd = f"GPIO:{pin}:{mode_str}"
    click.echo(f"Configuring Pin {pin} on {target}...")
    send_serial_command(target, cmd)

if __name__ == '__main__':
    cli()