import click
import time
import serial
from serial.tools import list_ports, miniterm

def auto_detect_port():
    """
    Scans for serial ports and returns the most likely candidate.
    Prioritizes USB-Serial bridges (CP210x, CH340, FTDI).
    """
    ports = list_ports.comports()
    if not ports:
        return None

    # Priority keywords for drivers
    drivers = ["CP210", "CH340", "FTDI", "USB", "UART"]
    
    for p in ports:
        desc = p.description.upper()
        # Check if description matches common drivers
        if any(d in desc for d in drivers):
            return p.device
            
    # Fallback to first available if no specific driver found
    return ports[0].device

def send_serial_command(port, command, baud=115200):
    """
    Opens serial port and sends a line of text to the device.
    """
    try:
        # Standard baud for configuration is usually lower than flashing
        with serial.Serial(port, baud, timeout=2) as ser:
            time.sleep(1.5)  # Wait for DTR reset/boot if necessary
            
            # Send command with newline
            payload = f"{command}\n".encode('utf-8')
            ser.write(payload)
            click.echo(f"  -> Sent: {command}")
            
            # Read response (optional - depends on your firmware logic)
            response = ser.readline().decode('utf-8', errors='ignore').strip()
            if response:
                click.echo(f"  -> Device says: {response}")
                
    except serial.SerialException as e:
        click.echo(f"  -> Serial Error: {e}", err=True)

def start_monitor(port, baud=115200):
    """
    Starts a serial monitor session using pyserial's miniterm.
    """
    try:
        ser = serial.Serial(port, baud)
        # Miniterm setup
        click.echo(f"--- Serial Monitor on {port} @ {baud} ---")
        click.echo("--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T + Ctrl+H ---")
        
        # Create miniterm instance
        # echo=False prevents double typing (local echo)
        term = miniterm.Miniterm(ser, echo=False, eol='crlf', filters=['default'])
        
        # Change exit character to Ctrl+C (0x03)
        term.exit_character = miniterm.unichr(0x03)  
        term.menu_character = miniterm.unichr(0x14)  # DC4/Ctrl+T
        term.set_rx_encoding('UTF-8')
        term.set_tx_encoding('UTF-8')
        
        term.start()
        try:
            term.join(True)
        except KeyboardInterrupt:
            pass
        term.join()
        term.close()
        click.echo("\n--- Monitor Closed ---")
    except serial.SerialException as e:
        click.echo(f"Serial Error: {e}", err=True)
    except Exception as e:
            click.echo(f"Error: {e}", err=True)