#!/bin/bash

# 🤖 Agent Manager - エージェント管理ツール
# 各ペインのエージェントを動的に管理

set -e

# 共通ライブラリの読み込み
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# MCPルートディレクトリの検出
if [ -f "$SCRIPT_DIR/../common/utils.sh" ]; then
    source "$SCRIPT_DIR/../common/utils.sh"
else
    # NPX経由で実行された場合のパス解決
    MCP_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
    if [ -f "$MCP_ROOT/scripts/common/utils.sh" ]; then
        source "$MCP_ROOT/scripts/common/utils.sh"
    else
        echo "[ERROR] utils.shが見つかりません" >&2
        exit 1
    fi
fi

# setup_directories関数が存在する場合のみ実行
if declare -f setup_directories > /dev/null 2>&1; then
    setup_directories "$SCRIPT_DIR"
fi

# スクリプトパスの設定
# 同じディレクトリにあるはず
PANE_CONTROLLER="$SCRIPT_DIR/pane_controller.sh"
AUTH_HELPER="$SCRIPT_DIR/auth_helper.sh"

# ファイルが存在しない場合はMCPルートから探す
if [ ! -f "$PANE_CONTROLLER" ]; then
    MCP_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
    PANE_CONTROLLER="$MCP_ROOT/scripts/agent_tools/pane_controller.sh"
    AUTH_HELPER="$MCP_ROOT/scripts/agent_tools/auth_helper.sh"
fi

# エージェント設定ファイル
AGENT_AUTH_CONFIG="$PROJECT_DIR/.agent_auth_config.json"

# ログ関数のエイリアス（後方互換性のため）
log_info() { log "INFO" "$1" "AGENT"; }
log_error() { log "ERROR" "$1" "ERROR"; }
log_success() { log "SUCCESS" "$1" "SUCCESS"; }
log_warn() { log "WARN" "$1" "WARN"; }

# エージェントタイプ定義は共通設定から取得
# AGENT_COMMANDS と AGENT_DESCRIPTIONS は config.sh で定義済み

# ペイン番号取得は共通ライブラリのget_pane_number()を使用

# 画面から直接エージェント状態を取得
get_agent_state() {
    local pane="$1"
    local pane_num=$(get_pane_number "$pane")
    
    if [ -z "$pane_num" ]; then
        echo "stopped"
        return 1
    fi
    
    # 画面内容から状態を判定
    local auth_state=$("$AUTH_HELPER" check "$pane" 2>/dev/null || echo "stopped")
    
    case "$auth_state" in
        "authenticated")
            echo "running"
            ;;
        "auth_required"|"browser_auth"|"theme_selection"|"permission_prompt"|"continue_prompt"|"terminal_setup")
            echo "auth_pending"
            ;;
        *)
            echo "stopped"
            ;;
    esac
}

# エージェント起動
start_agent() {
    local pane="$1"
    local agent_type="${2:-claude}"
    shift 2
    local additional_args="$@"
    
    local pane_num=$(get_pane_number "$pane")
    if [ -z "$pane_num" ]; then
        log_error "無効なペイン指定: $pane"
        return 1
    fi
    
    # エージェントタイプ確認
    if [ -z "${AGENT_COMMANDS[$agent_type]}" ] && [ "$agent_type" != "custom" ]; then
        log_error "不明なエージェントタイプ: $agent_type"
        log_info "利用可能: ${!AGENT_COMMANDS[@]}"
        return 1
    fi
    
    # 現在の状態確認（リトライ付き）
    local retry_count=0
    local max_retries=3
    local current_status=""
    
    while [ $retry_count -lt $max_retries ]; do
        current_status=$(get_agent_state "$pane")
        if [ -n "$current_status" ]; then
            break
        fi
        retry_count=$((retry_count + 1))
        log_warn "状態確認失敗 (リトライ $retry_count/$max_retries)"
        sleep 1
    done
    
    if [ "$current_status" = "running" ]; then
        log_warn "ペイン $pane でエージェントが実行中です - 停止して新しいエージェントを起動します"
        stop_agent "$pane"
        sleep 2  # 停止完了を確実に待つ
    fi
    
    # コマンド決定
    local command
    if [ "$agent_type" = "custom" ]; then
        command="$additional_args"
        log_info "カスタムコマンド起動: $command"
    else
        command="${AGENT_COMMANDS[$agent_type]} $additional_args"
        log_info "$agent_type 起動中 (ペイン $pane)"
    fi
    
    # エージェント起動（リトライ付き）
    local launch_retry=0
    local max_launch_retries=3
    local launch_success=false
    
    while [ $launch_retry -lt $max_launch_retries ]; do
        if "$PANE_CONTROLLER" exec "$pane" "$command"; then
            launch_success=true
            break
        else
            launch_retry=$((launch_retry + 1))
            if [ $launch_retry -lt $max_launch_retries ]; then
                log_warn "起動コマンド送信失敗 (リトライ $launch_retry/$max_launch_retries)"
                sleep 2
            fi
        fi
    done
    
    if [ "$launch_success" = "false" ]; then
        log_error "エージェント起動コマンドの送信に失敗しました"
        return 1
    fi
    
    # エージェントタイプ別の認証・起動確認
    log_info "$agent_type 認証/起動プロセスを監視中..."
    
    # プロセスが起動するまで少し待つ
    sleep 1
    
    # Geminiの場合は認証状態を定期的にチェック
    if [ "$agent_type" = "gemini" ]; then
        # 一旦認証待機状態をチェック
        sleep 3
        local auth_state=$("$AUTH_HELPER" check "$pane" 2>&1 | grep -o "auth_required\|authenticated" || echo "unknown")
        if [ "$auth_state" = "auth_required" ]; then
            log_warn "Gemini認証待機中 - 手動で認証を完了してください"
        fi
    fi
    
    # 起動完了待機（タイムアウトを300秒に設定）
    if "$AUTH_HELPER" wait "$pane" 300 "$agent_type"; then
        log_success "$agent_type 起動・認証完了"
        return 0
    else
        log_error "$agent_type 認証/起動失敗"
        return 1
    fi
}

# エージェント停止
stop_agent() {
    local pane="$1"
    local force="${2:-false}"
    
    local pane_num=$(get_pane_number "$pane")
    if [ -z "$pane_num" ]; then
        log_error "無効なペイン指定: $pane"
        return 1
    fi
    
    log_info "エージェント停止中 (ペイン $pane)"
    
    # プロセス停止
    "$PANE_CONTROLLER" stop "$pane" "$force"
    
    log_success "エージェント停止完了"
}

# エージェント再起動
restart_agent() {
    local pane="$1"
    local new_agent_type="$2"
    shift 2
    local additional_args="$@"
    
    # 新しいタイプが指定されていない場合はclaudeを使用
    if [ -z "$new_agent_type" ]; then
        new_agent_type="claude"
    fi
    
    log_info "エージェント再起動: → $new_agent_type"
    
    # 停止
    stop_agent "$pane" true
    sleep 2
    
    # 起動
    start_agent "$pane" "$new_agent_type" $additional_args
}

# エージェント状態確認
check_agent_status() {
    local pane="$1"
    
    if [ -z "$pane" ]; then
        # 全ペイン状態表示
        log_info "全エージェント状態:"
        echo "============================================"
        printf "%-12s %-10s %-10s %s\n" "ペイン" "タイプ" "状態" "最終更新"
        echo "--------------------------------------------"
        
        # 実際に存在するペインを動的に取得
        local pane_list=$(get_all_panes)
        local pane_count=$(echo "$pane_list" | wc -w)
        
        for i in $pane_list; do
            local name="pane-$i"
            
            # 画面から直接状態を取得
            local status=$(get_agent_state $i)
            local auth_detail=$("$AUTH_HELPER" check "$i" 2>/dev/null || echo "stopped")
            local agent_type="unknown"
            
            # エージェントタイプを画面から推定
            local screen=$("$PANE_CONTROLLER" capture "$i" 2>/dev/null || echo "")
            if echo "$screen" | grep -q "claude\|Claude"; then
                agent_type="claude"
            elif echo "$screen" | grep -q "gemini\|Gemini"; then
                agent_type="gemini"
            elif echo "$screen" | grep -q "python\|Python\|>>>"; then
                agent_type="python"
            elif echo "$screen" | grep -q "bash\|\$"; then
                agent_type="bash"
            fi
            
            # 状態アイコン
            local status_icon
            case "$status" in
                "running") status_icon="🟢" ;;
                "auth_pending") status_icon="🔄" ;;
                "stopped") status_icon="⚫" ;;
                *) status_icon="❓" ;;
            esac
            
            local timestamp=$(date +"%H:%M:%S")
            printf "%-12s %-10s %s %-12s %s\n" "$name" "$agent_type" "$status_icon" "$status" "$timestamp"
        done
        
        # サマリー
        echo "============================================"
        local running=0
        local auth_pending=0
        local total=$pane_count
        
        for i in $pane_list; do
            local status=$(get_agent_state $i)
            case "$status" in
                "running") running=$((running + 1)) ;;
                "auth_pending") auth_pending=$((auth_pending + 1)) ;;
            esac
        done
        
        echo "実行中: $running/$total"
        if [ $auth_pending -gt 0 ]; then
            echo "認証待機中: $auth_pending"
        fi
        
    else
        # 特定ペイン状態
        local status=$(get_agent_state "$pane")
        local auth_detail=$("$AUTH_HELPER" check "$pane" 2>/dev/null || echo "stopped")
        
        echo "ペイン: $pane"
        echo "状態: $status"
        echo "詳細: $auth_detail"
        echo "タイムスタンプ: $(date)"
        
        # 画面の最新状態も表示
        echo ""
        echo "画面状態:"
        echo "=================================="
        "$PANE_CONTROLLER" capture "$pane" "-5" | tail -5
    fi
}

# 利用可能なエージェントタイプ一覧
list_agent_types() {
    log_info "利用可能なエージェントタイプ:"
    echo "=================================="
    
    for agent_type in "${!AGENT_COMMANDS[@]}"; do
        printf "%-10s : %s\n" "$agent_type" "${AGENT_DESCRIPTIONS[$agent_type]}"
        printf "           コマンド: %s\n" "${AGENT_COMMANDS[$agent_type]}"
        
        # 認証情報を表示
        if [ -f "$AGENT_AUTH_CONFIG" ] && command -v jq >/dev/null 2>&1; then
            local auth_method=$(jq -r ".$agent_type.auth_method // \"unknown\"" "$AGENT_AUTH_CONFIG")
            local auth_desc=$(jq -r ".$agent_type.description // \"\"" "$AGENT_AUTH_CONFIG")
            printf "           認証: %s\n" "$auth_method"
            if [ -n "$auth_desc" ]; then
                printf "           %s\n" "$auth_desc"
            fi
        fi
        echo ""
    done
    
    echo "custom     : カスタムコマンド実行"
    echo "           使用例: agent_manager.sh start worker-a01 custom 'python script.py'"
    
    # 認証設定ファイルの状態
    echo ""
    echo "認証設定:"
    if [ -f "$AGENT_AUTH_CONFIG" ]; then
        echo "  設定ファイル: $AGENT_AUTH_CONFIG"
        if command -v jq >/dev/null 2>&1; then
            echo "  設定済みエージェント: $(jq -r 'keys | join(", ")' "$AGENT_AUTH_CONFIG")"
        fi
    else
        echo "  設定ファイルなし"
    fi
}

# バッチ起動（並列処理対応）
batch_start() {
    local agent_type="${1:-claude}"
    local panes="${2:-all}"
    local parallel="${3:-true}"  # デフォルトは並列処理
    
    log_info "バッチ起動開始: $agent_type (並列=$parallel)"
    
    local target_panes=()
    if [ "$panes" = "all" ]; then
        # 全てのペインを番号で指定（汎用的）
        local pane_count=$(get_pane_count)
        for ((i=0; i<pane_count; i++)); do
            target_panes+=("$i")
        done
    else
        # カンマ区切りのペイン指定（番号のみ）
        IFS=',' read -ra target_panes <<< "$panes"
    fi
    
    if [ "$parallel" = "true" ] && [ "$agent_type" != "claude" ]; then
        # 並列起動（Claude以外）
        log_info "並列起動モード: ${#target_panes[@]} エージェント"
        
        local pids=()
        local temp_dir=$(mktemp -d)
        
        # バックグラウンドで起動
        for pane in "${target_panes[@]}"; do
            (
                log_info "起動開始: $pane"
                if start_agent "$pane" "$agent_type"; then
                    echo "success" > "$temp_dir/$pane.result"
                else
                    echo "failed" > "$temp_dir/$pane.result"
                fi
            ) &
            pids+=($!)
            
            # 少し間隔を空ける（同時アクセス回避）
            sleep 0.2
        done
        
        # 全プロセス完了待機
        log_info "全エージェント起動待機中..."
        for pid in "${pids[@]}"; do
            wait $pid
        done
        
        # 結果集計
        local success=0
        local failed=0
        for pane in "${target_panes[@]}"; do
            if [ -f "$temp_dir/$pane.result" ]; then
                result=$(cat "$temp_dir/$pane.result")
                if [ "$result" = "success" ]; then
                    success=$((success + 1))
                else
                    failed=$((failed + 1))
                fi
            fi
        done
        
        rm -rf "$temp_dir"
        log_info "並列バッチ起動完了: 成功=$success, 失敗=$failed"
        
    else
        # 順次起動（Claudeまたは非並列モード）
        log_info "順次起動モード: ${#target_panes[@]} エージェント"
        
        local success=0
        local failed=0
        
        for pane in "${target_panes[@]}"; do
            log_info "起動中: $pane"
            if start_agent "$pane" "$agent_type"; then
                success=$((success + 1))
            else
                failed=$((failed + 1))
            fi
            sleep 1
        done
        
        log_info "順次バッチ起動完了: 成功=$success, 失敗=$failed"
    fi
}

# 認証待機中のエージェント状態を更新
update_auth_pending() {
    log_info "認証待機中のエージェントを確認中..."
    
    local updated=0
    local still_pending=0
    
    # 実際に存在するペインを動的に取得
    local pane_list=$(tmux list-panes -t multiagent -F "#{pane_index}" 2>/dev/null | sort -n)
    local pane_count=$(echo "$pane_list" | wc -w)
    
    # 全エージェントの状態を確認
    for i in $pane_list; do
        local status=$(get_agent_state $i)
        
        if [ "$status" = "auth_pending" ]; then
            # 認証状態を再確認
            local auth_state=$("$AUTH_HELPER" check "$i" 2>&1 | grep -o "authenticated" || echo "")
            
            if [ "$auth_state" = "authenticated" ]; then
                log_success "pane-$i 認証完了 → running"
                updated=$((updated + 1))
            else
                still_pending=$((still_pending + 1))
            fi
        fi
    done
    
    log_info "更新結果: 認証完了=$updated, 認証待機中=$still_pending"
}

# ヘルプ表示
show_usage() {
    cat << EOF
🤖 Agent Manager - エージェント管理ツール

使用方法:
  $(basename $0) <command> [options]

コマンド:
  start <pane> [type] [args]   エージェント起動
  stop <pane> [force]          エージェント停止
  restart <pane> [type] [args] エージェント再起動
  status [pane]                状態確認
  list                         利用可能なエージェントタイプ
  batch <type> [target]        バッチ起動
  update-auth                  認証待機中の状態を更新

エージェントタイプ:
  claude    - Claude Code (デフォルト)
  gemini    - Gemini CLI
  gpt       - GPT CLI
  python    - Python インタープリタ
  bash      - Bash シェル
  custom    - カスタムコマンド

バッチターゲット:
  all       - 全ペイン
  <list>    - カンマ区切りペイン番号

バッチオプション:
  第3引数にfalseを指定すると順次起動
  (デフォルトは並列起動、Claudeは常に順次)

例:
  $(basename $0) start 0 claude
  $(basename $0) start 1 gemini
  $(basename $0) start 2 custom "python main.py"
  $(basename $0) stop 3
  $(basename $0) restart 4 claude
  $(basename $0) batch claude all            # Claudeを全ペインで順次起動
  $(basename $0) batch gemini all            # Geminiを全ペインで並列起動
  $(basename $0) batch python all false      # Pythonを順次起動
  $(basename $0) batch gemini "0,1,2"
  $(basename $0) status
EOF
}

# メイン処理
main() {
    # 依存ツール確認
    if [ ! -f "$PANE_CONTROLLER" ]; then
        log_error "pane_controller.sh が見つかりません: $PANE_CONTROLLER"
        exit 1
    fi
    
    # 実行権限がない場合は付与
    if [ ! -x "$PANE_CONTROLLER" ]; then
        chmod +x "$PANE_CONTROLLER"
    fi
    
    if [ ! -f "$AUTH_HELPER" ]; then
        log_error "auth_helper.sh が見つかりません: $AUTH_HELPER"
        exit 1
    fi
    
    # 実行権限がない場合は付与
    if [ ! -x "$AUTH_HELPER" ]; then
        chmod +x "$AUTH_HELPER"
    fi
    
    case "${1:-}" in
        "start")
            shift
            if [ $# -lt 1 ]; then
                log_error "使用法: start <pane> [type] [args]"
                exit 1
            fi
            start_agent "$@"
            ;;
        "stop")
            shift
            if [ $# -lt 1 ]; then
                log_error "使用法: stop <pane> [force]"
                exit 1
            fi
            stop_agent "$@"
            ;;
        "restart")
            shift
            if [ $# -lt 1 ]; then
                log_error "使用法: restart <pane> [type] [args]"
                exit 1
            fi
            restart_agent "$@"
            ;;
        "status")
            shift
            check_agent_status "$@"
            ;;
        "list")
            list_agent_types
            ;;
        "batch")
            shift
            if [ $# -lt 1 ]; then
                log_error "使用法: batch <type> [target]"
                exit 1
            fi
            batch_start "$@"
            ;;
        "update-auth")
            update_auth_pending
            ;;
        "help"|"-h"|"--help")
            show_usage
            ;;
        *)
            log_error "不明なコマンド: $1"
            show_usage
            exit 1
            ;;
    esac
}

# スクリプト実行
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
    main "$@"
fi