#!/bin/sh
# Menú de bluetooth con dmenu (clic izquierdo en BT de la barra). Arriba, los
# dispositivos conocidos (emparejados o de confianza; 󰂱 = conectado): elegir
# uno lo desconecta si está conectado y, si no, lo busca y se conecta (y lo
# vuelve a emparejar si hace falta). Debajo, buscar y emparejar uno nuevo y
# apagar el adaptador. Si está apagado, ofrece encenderlo.

avisar() {
	notify-send -h string:x-dunst-stack-tag:bluetooth -i bluetooth "Bluetooth" "$1"
}

# "Device AA:BB:CC:DD:EE:FF Nombre" -> "Nombre (AA:BB:CC:DD:EE:FF)"
lista() { sed -n 's/^Device \([^ ]*\) \(.*\)/\2 (\1)/p'; }
mac() { printf '%s\n' "$1" | sed 's/.*(\([^)]*\))$/\1/'; }
buscar() { bluetoothctl --timeout "$1" scan on >/dev/null; }

# Sin agente, bluetoothctl no puede emparejar; los auriculares no piden PIN.
emparejar() {
	bluetoothctl --agent NoInputNoOutput pair "$1" >/dev/null &&
		bluetoothctl trust "$1" >/dev/null
}

# conectar MAC: si no está emparejado lo empareja; si no está a la vista, lo
# busca unos segundos y lo vuelve a intentar.
conectar() {
	if ! bluetoothctl info "$1" | grep -q 'Paired: yes'; then
		emparejar "$1" || { buscar 8 && emparejar "$1"; } || return 1
	fi
	bluetoothctl connect "$1" >/dev/null ||
		{ buscar 8 && bluetoothctl connect "$1" >/dev/null; }
}

# conectar_y_avisar "Nombre (MAC)"
conectar_y_avisar() {
	nombre=${1% (*}
	avisar "Conectando: $nombre..."
	if conectar "$(mac "$1")"; then
		avisar "Conectado: $nombre"
	elif ! pgrep -x wireplumber >/dev/null; then
		avisar "No se pudo conectar $nombre: wireplumber no está en marcha (sin él no hay audio)"
	else
		avisar "No se pudo conectar $nombre: ¿está encendido y cerca?"
	fi
}

if ! bluetoothctl show | grep -q 'Powered: yes'; then
	[ "$(echo Encender | menu -p Bluetooth:)" = Encender ] || exit 0
	bluetoothctl power on >/dev/null
	pkill -USR1 -x slstatus
fi

conectados=$(bluetoothctl devices Connected | lista)
conocidos=$({ bluetoothctl devices Paired; bluetoothctl devices Trusted; } | lista | sort -u)

opcion=$(
	printf '%s\n' "$conocidos" | while IFS= read -r d; do
		[ -n "$d" ] || continue
		if printf '%s\n' "$conectados" | grep -qxF "$d"; then
			echo "󰂱 $d"
		else
			echo "  $d"
		fi
	done
	echo "󰍉  Buscar dispositivos"
	echo "󰂲  Apagar"
)
opcion=$(printf '%s\n' "$opcion" | menu -p Bluetooth:)

case $opcion in
'') exit 0 ;;
*"  Apagar")
	bluetoothctl power off >/dev/null
	;;
*"  Buscar dispositivos")
	avisar "Buscando dispositivos durante 10 s..."
	buscar 10
	nuevo=$(bluetoothctl devices | lista | awk -v e="$conocidos" '
		BEGIN { n = split(e, a, "\n"); for (i = 1; i <= n; i++) visto[a[i]] }
		!($0 in visto)' | menu -p Emparejar:)
	[ -n "$nuevo" ] || exit 0
	conectar_y_avisar "$nuevo"
	;;
"󰂱 "*)
	bluetoothctl disconnect "$(mac "$opcion")" >/dev/null &&
		avisar "Desconectado: ${opcion#"󰂱 "}"
	;;
*)
	conectar_y_avisar "${opcion#"  "}"
	;;
esac
pkill -USR1 -x slstatus
