"""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 jusfltuls.voicemqtt.audio import AudioRecorder
from jusfltuls.voicemqtt.clipboard import ClipboardManager
from jusfltuls.voicemqtt.mqtt_client import MQTTActivator
from jusfltuls.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")

        # Strip URL scheme (e.g., https://, mqtt://, mqtts://)
        if "://" in server:
            server = server.split("://", 1)[1]

        if ":" in server:
            host, port_str = server.rsplit(":", 1)
            port = int(port_str)
        else:
            host = server
            port = 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:
        if sys.stdin.isatty():
            old_settings = termios.tcgetattr(sys.stdin)
            tty.setcbreak(sys.stdin.fileno())
            try:
                while select.select([sys.stdin], [], [], 0)[0]:
                    if not sys.stdin.read(1):
                        break
            finally:
                termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
    except (termios.error, OSError, AttributeError):
        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")

    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]")

    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

    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()

    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:
            if not mqtt_activator.wait_for_activation():
                break

            def audio_status_callback(status):
                mqtt_activator.publish(recording_status_topic, status)

            audio_data = audio_recorder.record(status_callback=audio_status_callback)

            mqtt_activator.publish(recording_status_topic, "0")
            
            if audio_data is not None:
                transcript = transcriber.transcribe(audio_data)
                
                if transcript:
                    console.print(f"\n[bold]Transcript:[/bold] {transcript}")
                    clipboard.copy_text(transcript)
                else:
                    console.print("[yellow]No transcription produced.[/yellow]")
            
            console.print()
            sys.stdout.flush()

            drain_stdin()

            if single:
                break

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


if __name__ == "__main__":
    main()
