"""Main CLI for VoiceMQTT."""

import configparser
import os
import select
import sys
import termios
import time
import tty

import click
from rich.console import Console

from voicemqtt.audio import AudioRecorder
from voicemqtt.clipboard import ClipboardManager
from voicemqtt.mqtt_client import MQTTActivator
from voicemqtt.transcriber import Transcriber


console = Console()
VERSION = "0.1.0"


def load_public_mqtt_config():
    """Load public MQTT configuration from ~/.config/influxdb/totalconfig.conf.

    Returns:
        tuple: (host, port, username, password, use_tls) or None if config not found
    """
    config_path = os.path.expanduser("~/.config/influxdb/totalconfig.conf")

    if not os.path.exists(config_path):
        return None

    try:
        config = configparser.ConfigParser()
        config.read(config_path)

        if "mqtt public" not in config:
            return None

        server = config.get("mqtt public", "server")
        username = config.get("mqtt public", "username")
        password = config.get("mqtt public", "password")

        # Parse server string (format: host:port or just host)
        if ":" in server:
            host, port_str = server.rsplit(":", 1)
            port = int(port_str)
        else:
            host = server
            port = 8883  # Default TLS port

        # Auto-enable TLS if port is 8883
        use_tls = (port == 8883)

        return host, port, username, password, use_tls
    except Exception as e:
        console.print(f"[red]Error reading MQTT config: {e}[/red]")
        return None


def drain_stdin():
    """Drain any pending input from stdin to prevent blocking."""
    try:
        # Check if stdin is a tty
        if sys.stdin.isatty():
            # Set stdin to non-blocking mode temporarily
            old_settings = termios.tcgetattr(sys.stdin)
            tty.setcbreak(sys.stdin.fileno())
            try:
                # Read any pending input
                while select.select([sys.stdin], [], [], 0)[0]:
                    if not sys.stdin.read(1):
                        break
            finally:
                # Restore terminal settings
                termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
    except (termios.error, OSError, AttributeError):
        # Not a tty or other error, ignore
        pass


@click.command()
@click.option(
    "--mqtt-host",
    default="localhost",
    help="MQTT broker host (default: localhost)",
    show_default=True
)
@click.option(
    "--mqtt-port",
    default=1883,
    help="MQTT broker port (default: 1883)",
    show_default=True
)
@click.option(
    "--mqtt-topic",
    default="voicemqtt/activate",
    help="MQTT topic for activation (default: voicemqtt/activate)",
    show_default=True
)
@click.option(
    "--mqtt-user",
    default=None,
    help="MQTT username for authentication",
    show_default=True
)
@click.option(
    "--mqtt-pass",
    default=None,
    help="MQTT password for authentication",
    show_default=True
)
@click.option(
    "--mqtt-tls",
    is_flag=True,
    help="Enable TLS/SSL encryption for MQTT",
    default=False
)
@click.option(
    "--mqtt-ca-certs",
    default=None,
    help="Path to CA certificates file for TLS",
    show_default=True
)
@click.option(
    "--public-mqtt",
    is_flag=True,
    help="Use public MQTT broker from ~/.config/influxdb/totalconfig.conf",
    default=False
)
@click.option(
    "--recording-status-topic",
    default="voicemqtt/recording",
    help="MQTT topic for recording status (2=sound, 1=silence, 0=idle)",
    show_default=True
)
@click.option(
    "--model",
    default="base",
    help="Whisper model size (tiny, base, small, medium, large-v1/v2/v3)",
    show_default=True
)
@click.option(
    "--device",
    default="cpu",
    help="Device for Whisper (cpu, cuda)",
    show_default=True
)
@click.option(
    "--silence-threshold",
    default=0.01,
    help="Audio level threshold for silence detection",
    show_default=True
)
@click.option(
    "--silence-duration",
    default=3.0,
    help="Seconds of silence before stopping recording",
    show_default=True
)
@click.option(
    "--single/--continuous",
    default=False,
    help="Run once and exit (single) or wait for multiple activations (continuous)",
    show_default=True
)
@click.option(
    "--calibrate",
    is_flag=True,
    help="Calibrate silence threshold (records 10s, use last 3s for silence)",
    default=False
)
@click.version_option(version=VERSION, prog_name="voicemqtt")
@click.help_option()
def main(
    mqtt_host,
    mqtt_port,
    mqtt_topic,
    mqtt_user,
    mqtt_pass,
    mqtt_tls,
    mqtt_ca_certs,
    public_mqtt,
    recording_status_topic,
    model,
    device,
    silence_threshold,
    silence_duration,
    single,
    calibrate
):
    """VoiceMQTT - MQTT-activated voice transcription to clipboard.

    Listens for activation messages on MQTT topic, records audio with
    real-time level display, transcribes using local Whisper, and copies
    text to Wayland clipboard.

    \b
    Examples:
        voicemqtt                           # Use default settings
        voicemqtt --mqtt-host 192.168.1.5   # Custom MQTT broker
        voicemqtt --model small             # Use better quality model
        voicemqtt --single                  # Run once and exit
        voicemqtt --public-mqtt             # Use public MQTT from config
        voicemqtt --mqtt-host mqtt.example.com --mqtt-port 8883 --mqtt-tls --mqtt-user myuser --mqtt-pass mypass
    """
    console.print("[bold cyan]VoiceMQTT[/bold cyan]", style="bold")
    console.print(f"[dim]Version {VERSION}[/dim]\n")

    # Handle public MQTT option
    if public_mqtt:
        config = load_public_mqtt_config()
        if config is None:
            console.print("[red]Failed to load public MQTT configuration.[/red]")
            console.print("[dim]Ensure ~/.config/influxdb/totalconfig.conf exists with [mqtt public] section.[/dim]")
            sys.exit(1)
        mqtt_host, mqtt_port, mqtt_user, mqtt_pass, mqtt_tls = config
        console.print(f"[green]Loaded public MQTT config: {mqtt_host}:{mqtt_port}[/green]")

    # Handle calibration mode
    if calibrate:
        audio_recorder = AudioRecorder()
        recommended_threshold = audio_recorder.calibrate_silence()

        if recommended_threshold:
            console.print(f"\n[dim]Use this threshold with: --silence-threshold {recommended_threshold:.6f}[/dim]")
        else:
            console.print("[red]Calibration failed[/red]")
            sys.exit(1)
        return

    # Initialize components
    mqtt_activator = MQTTActivator(
        host=mqtt_host,
        port=mqtt_port,
        topic=mqtt_topic,
        username=mqtt_user,
        password=mqtt_pass,
        use_tls=mqtt_tls,
        tls_ca_certs=mqtt_ca_certs
    )

    audio_recorder = AudioRecorder(
        silence_threshold=silence_threshold,
        silence_duration=silence_duration
    )

    transcriber = Transcriber(
        model_size=model,
        device=device
    )

    clipboard = ClipboardManager()

    # Connect to MQTT
    console.print("[bold]Connecting to MQTT broker...[/bold]")
    if not mqtt_activator.connect():
        console.print("[red]Failed to connect to MQTT broker. Exiting.[/red]")
        sys.exit(1)
    
    try:
        while True:
            # Wait for activation
            if not mqtt_activator.wait_for_activation():
                break

            # Create callback for audio status updates
            def audio_status_callback(status):
                mqtt_activator.publish(recording_status_topic, status)

            # Record audio with status callback
            audio_data = audio_recorder.record(status_callback=audio_status_callback)

            # Publish recording finished status
            mqtt_activator.publish(recording_status_topic, "0")
            
            if audio_data is not None:
                # Transcribe
                transcript = transcriber.transcribe(audio_data)
                
                if transcript:
                    # Copy to clipboard
                    console.print(f"\n[bold]Transcript:[/bold] {transcript}")
                    clipboard.copy_text(transcript)
                else:
                    console.print("[yellow]No transcription produced.[/yellow]")
            
            console.print()  # Empty line for readability
            sys.stdout.flush()

            # Drain any pending stdin to prevent blocking
            drain_stdin()

            # If single mode, exit after one recording
            if single:
                break

            console.print("[dim]Waiting for next activation...[/dim]")
            sys.stdout.flush()
            time.sleep(0.1)  # Small delay to let terminal settle
            
    except KeyboardInterrupt:
        console.print("\n[yellow]Interrupted by user[/yellow]")
    finally:
        mqtt_activator.disconnect()
        console.print("[dim]Goodbye![/dim]")


if __name__ == "__main__":
    main()
