#!/bin/bash
# SubConfirm — Proaktiver Stasis-Detektor für Subagenten
#
# Läuft als Hintergrund-Daemon und prüft alle 30 Sekunden alle tmux-Sessions.
# Wenn eine Session ihren Output seit >30s nicht verändert hat (Stasis),
# wird der vollständige Pane-Inhalt in die Alert-Datei geschrieben UND
# direkt in die Orchestrator-Session injiziert (tmux send-keys).
#
# Architektur:
#   SubConfirm → /tmp/.pi-subagent-alert → arbeitsweise-guard.ts → Orchestrator
#   SubConfirm → tmux send-keys → Orchestrator-Session (direkter Push)
#
# Nutzung:
#   SubConfirm --orchestrator "session-name" &   # Mit Push in Orchestrator-Session
#   SubConfirm --interval 15 &                   # Kürzeres Intervall
#   SubConfirm --skip "main-session" &           # Session ausschließen
#   pkill -f SubConfirm                          # Beenden
#
# Der --orchestrator und --skip Parameter sind oft gleich:
#   NAME=$(tmux display-message -p '#S')
#   SubConfirm --orchestrator "$NAME" --skip "$NAME" &

set -euo pipefail

INTERVAL=30
SKIP_SESSION=""
ORCHESTRATOR_SESSION=""
REPORT_COOLDOWN=90   # Sekunden zwischen wiederholten Meldungen zur selben Session
ALERT_FILE="/tmp/.pi-subagent-alert"
STATE_DIR="/tmp/.pi-subconfirm-state"
PID_FILE="/tmp/.pi-subconfirm.pid"

while [[ $# -gt 0 ]]; do
    case "$1" in
        --interval)     INTERVAL="$2"; shift 2 ;;
        --skip)         SKIP_SESSION="$2"; shift 2 ;;
        --orchestrator) ORCHESTRATOR_SESSION="$2"; shift 2 ;;
        *) shift ;;
    esac
done

mkdir -p "$STATE_DIR"
echo $$ > "$PID_FILE"

log() {
    echo "[SubConfirm $(date '+%H:%M:%S')] $1" >&2
}

# Prüft ob Pi im Orchestrator-Terminal gerade auf Eingabe wartet.
# Pi zeigt am Ende des Pane-Inhalts einen Eingabe-Cursor (leere Zeile oder ">").
orchestrator_is_idle() {
    [ -z "$ORCHESTRATOR_SESSION" ] && return 1
    local last
    last=$(tmux capture-pane -t "$ORCHESTRATOR_SESSION" -p 2>/dev/null \
        | sed 's/\x1b\[[0-9;]*[mGKHF]//g' \
        | grep -v '^[[:space:]]*$' \
        | tail -3)
    # Pi ist idle wenn die letzte sichtbare Zeile den Status-Bar zeigt
    # (kein "Working..." oder Spinner sichtbar)
    echo "$last" | grep -qE '(Working\.\.\.|⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏)' && return 1
    return 0
}

# Injiziert eine Nachricht in die Orchestrator-Session via tmux send-keys.
inject_to_orchestrator() {
    local msg="$1"
    [ -z "$ORCHESTRATOR_SESSION" ] && return
    orchestrator_is_idle || return
    # Nachricht tippen + Enter → Pi verarbeitet es als User-Input
    tmux send-keys -t "$ORCHESTRATOR_SESSION" "$msg" Enter 2>/dev/null || true
    log "Injiziert in Orchestrator-Session: ${msg:0:60}..."
}

alert() {
    local session="$1"
    local pane_display="$2"
    local short_msg="⏸️ SUBAGENT-STASIS [$session] — braucht Eingabe"

    # 1. In Alert-Datei schreiben (Guard zeigt das beim nächsten Tool-Call)
    cat >> "$ALERT_FILE" <<EOF
$(date '+%H:%M:%S') $short_msg

Pane-Inhalt [$session]:
$pane_display

Mögliche Reaktionen:
  Bestätigen (Yes):  tmux send-keys -t "$session" "" Enter
  Ablehnen  (No):    tmux send-keys -t "$session" "Down" && tmux send-keys -t "$session" "" Enter
  Ignorieren:        (nächste Meldung in ${REPORT_COOLDOWN}s)

EOF

    # 2. Desktop-Notification
    zenity --notification --text="SubConfirm: $short_msg" 2>/dev/null &
    echo -e "\a" 2>/dev/null || true

    # 3. Direkt in Orchestrator-Session injizieren wenn idle
    inject_to_orchestrator "$short_msg — bitte prüfen und reagieren (tmux capture-pane -t '$session' -p | tail -20)"
}

log "Gestartet (PID $$, Intervall: ${INTERVAL}s, Skip: '${SKIP_SESSION}', Orchestrator: '${ORCHESTRATOR_SESSION}')"

while true; do
    sleep "$INTERVAL"

    SESSIONS=$(tmux ls -F '#{session_name}' 2>/dev/null || echo "")
    [ -z "$SESSIONS" ] && continue

    while IFS= read -r session; do
        [ -z "$session" ] && continue
        [ "$session" = "$SKIP_SESSION" ] && continue

        # Pane-Inhalt holen (letzte 25 Zeilen, ANSI-Escape-Codes entfernen)
        CURRENT=$(tmux capture-pane -t "$session" -p 2>/dev/null \
            | sed 's/\x1b\[[0-9;]*[mGKHF]//g' \
            | grep -v '^[[:space:]]*$' \
            | tail -25 \
            | tr '\n' '§')

        [ -z "$CURRENT" ] && continue

        STATE_FILE="${STATE_DIR}/${session//\//_}.state"
        REPORT_FILE="${STATE_DIR}/${session//\//_}.reported"
        PREV=$(cat "$STATE_FILE" 2>/dev/null || echo "")

        if [ "$CURRENT" = "$PREV" ]; then
            NOW=$(date +%s)
            LAST_REPORT=$(cat "$REPORT_FILE" 2>/dev/null || echo 0)

            if [ $((NOW - LAST_REPORT)) -gt "$REPORT_COOLDOWN" ]; then
                PANE_DISPLAY=$(echo "$CURRENT" | tr '§' '\n')
                alert "$session" "$PANE_DISPLAY"
                log "Stasis gemeldet: $session"
                echo "$NOW" > "$REPORT_FILE"
            fi
        else
            echo "$CURRENT" > "$STATE_FILE"
            rm -f "$REPORT_FILE"
        fi
    done <<< "$SESSIONS"
done
