#!/bin/bash

# filemd_restore - Consolidated restore tool for AGENTS.md, plugins, skills, and subagents
# Usage: filemd_restore
# Interactive 4-column selection mode

set -e

STORAGE_DIR="$HOME/00_central/volatile"
TYPE_DESC_FILE="$STORAGE_DIR/.type_descriptions"
PLUGINS_DIR=".opencode/plugins"
SKILLS_DIR=".opencode/skills"
AGENTS_DIR=".opencode/agents"
ASKILLS_DIR=".agents/skills"

# Check dependencies
compare_files() {
    local f1="$1"
    local f2="$2"
    if command -v icdiff >/dev/null 2>&1; then
        icdiff "$f1" "$f2" -t --show-no-spaces --no-bold | grep -ve "^\s*$" || true
    else
        diff -u "$f1" "$f2" || true
    fi
}

normalize_type_category() {
    local cat="$1"
    local lowered="${cat,,}"
    lowered="${lowered%.md}"
    lowered="${lowered// /}"
    case "$lowered" in
        agent|agents) echo "AGENTS.md" ;;
        plugin|plugins) echo "PLUGIN" ;;
        skill|skills) echo "SKILL" ;;
        subagent|subagents) echo "SUBAGENT" ;;
        *) echo "$cat" ;;
    esac
}

load_type_descriptions() {
    TYPE_DESCRIPTIONS=()
    if [[ -f "$TYPE_DESC_FILE" ]]; then
        while IFS='|' read -r cat type_name desc; do
            cat="$(normalize_type_category "$cat")"
            TYPE_DESCRIPTIONS["${cat}:${type_name}"]="$desc"
        done < "$TYPE_DESC_FILE"
    fi
}

# Ensure storage exists
mkdir -p "$STORAGE_DIR"

# --- Data Gathering ---

# Fixed timestamp length (YYYYMMDD_HHMMSS_)
TS_LEN=16

get_types() {
    local pattern="$1"
    local suffix="$2"
    ls "$STORAGE_DIR" 2>/dev/null | grep -E "$pattern" | while read -r file; do
        # Strip prefix and suffix
        local type_part="${file:$TS_LEN}"
        echo "${type_part%$suffix}"
    done | sort -u
}

# Column 1: AGENTS.md types
AGENT_TYPES=($(get_types "_AGENTS.md$" "_AGENTS.md"))
# Column 2: Plugin types
PLUGIN_TYPES=($(get_types "_PLUGIN" "_PLUGIN*"))
# Column 3: Skill types
SKILL_TYPES=($(get_types "_SKILL.tar.gz$" "_SKILL.tar.gz"))
# Column 4: Subagent types
SUBAGENT_TYPES=($(get_types "_SUBAGENT.md$" "_SUBAGENT.md"))

# Index-to-display: 1..9, 11..N (skip 10)
_idx2disp() { local i=$1; if [[ $i -lt 9 ]]; then echo $((i+1)); else echo $((i+2)); fi; }
_disp2idx() { local n=$1; if [[ $n -le 9 ]]; then echo $((n-1)); else echo $((n-2)); fi; }

ALL_LETTERS=(a b c d e f g h i j k l m n o p r s t u v w x y z)

PLUGIN_KEYS=()
SKILL_KEYS=()
SUBAGENT_KEYS=()
_ki=0
for ((i=0; i<${#PLUGIN_TYPES[@]}; i++)); do
    PLUGIN_KEYS+=("${ALL_LETTERS[$_ki]}")
    _ki=$((_ki+1))
done
for ((i=0; i<${#SKILL_TYPES[@]}; i++)); do
    SKILL_KEYS+=("${ALL_LETTERS[$_ki]}")
    _ki=$((_ki+1))
done
for ((i=0; i<${#SUBAGENT_TYPES[@]}; i++)); do
    SUBAGENT_KEYS+=("${ALL_LETTERS[$_ki]}")
    _ki=$((_ki+1))
done

key_category() {
    local key="$1"
    local i
    for i in "${!PLUGIN_KEYS[@]}"; do
        if [[ "${PLUGIN_KEYS[$i]}" == "$key" ]]; then
            echo "plugin"
            return 0
        fi
    done
    for i in "${!SKILL_KEYS[@]}"; do
        if [[ "${SKILL_KEYS[$i]}" == "$key" ]]; then
            echo "skill"
            return 0
        fi
    done
    for i in "${!SUBAGENT_KEYS[@]}"; do
        if [[ "${SUBAGENT_KEYS[$i]}" == "$key" ]]; then
            echo "subagent"
            return 0
        fi
    done
    return 1
}

key_range() {
    local -n arr=$1
    if [[ ${#arr[@]} -eq 0 ]]; then
        echo "-"
        return
    fi
    if [[ ${#arr[@]} -eq 1 ]]; then
        echo "${arr[0]}"
        return
    fi
    echo "${arr[0]}-${arr[-1]}"
}

key_for_index() {
    local prefix="$1"
    local idx="$2"
    case "$prefix" in
        plugin) echo "${PLUGIN_KEYS[$idx]}" ;;
        skill) echo "${SKILL_KEYS[$idx]}" ;;
        subagent) echo "${SUBAGENT_KEYS[$idx]}" ;;
    esac
}

index_for_key() {
    local prefix="$1"
    local key="$2"
    local -n keys_ref="$3"
    local i
    for i in "${!keys_ref[@]}"; do
        if [[ "${keys_ref[$i]}" == "$key" ]]; then
            echo "$i"
            return 0
        fi
    done
    return 1
}

# Selection states
SELECTED_AGENT=""
declare -A SELECTED_PLUGINS
declare -A SELECTED_SKILLS
declare -A SELECTED_SUBAGENTS
declare -A TYPE_DESCRIPTIONS
LAST_DESC=""

# --- UI Functions ---

draw_menu() {
    clear
    echo -e "\033[33m=== filemd_restore - Consolidated Selection ===\033[0m"
    echo ""
    printf "%-25s %-25s %-25s %-25s\n" "COL 1: AGENTS.md" "COL 2: PLUGINS" "COL 3: SKILLS" "COL 4: SUBAGENTS"
    printf "%-25s %-25s %-25s %-25s\n" "----------------" "--------------" "-------------" "----------------"

    local max_rows=${#AGENT_TYPES[@]}
    [[ ${#PLUGIN_TYPES[@]} -gt $max_rows ]] && max_rows=${#PLUGIN_TYPES[@]}
    [[ ${#SKILL_TYPES[@]} -gt $max_rows ]] && max_rows=${#SKILL_TYPES[@]}
    [[ ${#SUBAGENT_TYPES[@]} -gt $max_rows ]] && max_rows=${#SUBAGENT_TYPES[@]}

    for ((i=0; i<max_rows; i++)); do
        # Column 1: Agents (numbered keys, skip 10)
        local col1_text=""
        if [[ $i -lt ${#AGENT_TYPES[@]} ]]; then
            local type="${AGENT_TYPES[$i]}"
            local key=$(_idx2disp $i)
            local mark="[ ]"
            [[ "$SELECTED_AGENT" == "$type" ]] && mark="[x]"
            col1_text="${key}) $mark $type"
        fi

        # Column 2: Plugins (keys a-i)
        local col2_text=""
        if [[ $i -lt ${#PLUGIN_TYPES[@]} ]]; then
            local type="${PLUGIN_TYPES[$i]}"
            local key="$(key_for_index plugin "$i")"
            local mark="[ ]"
            [[ "${SELECTED_PLUGINS[$type]}" == "1" ]] && mark="[x]"
            # Truncate long plugin names
            local display_name="$type"
            if [[ ${#display_name} -gt 18 ]]; then
                display_name="${display_name:0:15}..."
            fi
            col2_text="${key}) $mark $display_name"
        fi

        # Column 3: Skills (keys j-r)
        local col3_text=""
        if [[ $i -lt ${#SKILL_TYPES[@]} ]]; then
            local type="${SKILL_TYPES[$i]}"
            local key="$(key_for_index skill "$i")"
            local mark="[ ]"
            [[ "${SELECTED_SKILLS[$type]}" == "1" ]] && mark="[x]"
            col3_text="${key}) $mark $type"
        fi

        # Column 4: Subagents (keys from z backwards)
        local col4_text=""
        if [[ $i -lt ${#SUBAGENT_TYPES[@]} ]]; then
            local type="${SUBAGENT_TYPES[$i]}"
            local key="$(key_for_index subagent "$i")"
            local mark="[ ]"
            [[ "${SELECTED_SUBAGENTS[$type]}" == "1" ]] && mark="[x]"
            col4_text="${key}) $mark $type"
        fi

        printf "%-25s %-25s %-25s %-25s\n" "$col1_text" "$col2_text" "$col3_text" "$col4_text"
    done

    echo ""
    local sub_help=""
    if [[ ${#SUBAGENT_TYPES[@]} -gt 0 ]]; then
        sub_help=" | [$(key_range SUBAGENT_KEYS)]: Subagents"
    fi
    echo -e "\033[33m[number]: Agents | [$(key_range PLUGIN_KEYS)]: Plugins | [$(key_range SKILL_KEYS)]: Skills${sub_help} | [ENTER]: Confirm | [q]: Quit\033[0m"
    if [[ -n "$LAST_DESC" ]]; then
        echo ""
        echo -e "\033[2m${LAST_DESC}\033[0m"
    fi
}

# --- Restoration Logic ---

restore_agent() {
    local type="$1"
    local md_file="AGENTS.md"
    echo -e "\n\033[34m>>> Processing AGENTS.md ($type)\033[0m"
    
    local latest=$(ls -t "$STORAGE_DIR"/*"${type}_${md_file}" 2>/dev/null | head -1)
    if [[ -z "$latest" ]]; then
        echo -e "\033[31mError: Stored file not found for type $type\033[0m"
        return
    fi

    if [[ -f "$md_file" ]]; then
        if ! diff -q "$md_file" "$latest" > /dev/null; then
            echo "Differences found in $md_file:"
            compare_files "$md_file" "$latest"
            echo -n -e "\033[33mOverwrite $md_file? (y/N) \033[0m"
            read -n 1 -r REPLY
            echo
            if [[ "$REPLY" =~ ^[Yy]$ ]]; then
                cp "$latest" "$md_file"
                echo -e "\033[32mRestored: $md_file\033[0m"
            fi
        else
            echo -e "\033[32m$md_file is already up to date.\033[0m"
        fi
    else
        cp "$latest" "$md_file"
        echo -e "\033[32mRestored: $md_file\033[0m"
    fi
}

restore_plugin() {
    local type="$1"
    echo -e "\n\033[34m>>> Processing Plugin ($type)\033[0m"
    
    local latest=$(ls -t "$STORAGE_DIR"/*_"${type}_PLUGIN"* 2>/dev/null | grep -E "[0-9]{8}_[0-9]{6}_${type}_PLUGIN(\..*)?$" | head -1)
    if [[ -z "$latest" ]]; then
        echo -e "\033[31mError: Stored plugin not found for type $type\033[0m"
        return
    fi

    local filename_ext=$(basename "$latest")
    local ext="${filename_ext##*.}"
    local plugin_name
    if [[ "$ext" == "$filename_ext" ]]; then
        plugin_name="$type"
    else
        plugin_name="$type.$ext"
    fi
    local target="$PLUGINS_DIR/$plugin_name"

    mkdir -p "$PLUGINS_DIR"

    if [[ -f "$target" ]]; then
        if ! diff -q "$target" "$latest" > /dev/null; then
            echo "Differences found in $plugin_name:"
            compare_files "$target" "$latest"
            echo -n -e "\033[33mOverwrite $target? (y/N) \033[0m"
            read -n 1 -r REPLY
            echo
            if [[ "$REPLY" =~ ^[Yy]$ ]]; then
                cp "$latest" "$target"
                echo -e "\033[32mRestored: $target\033[0m"
            fi
        else
            echo -e "\033[32m$target is already up to date.\033[0m"
        fi
    else
        cp "$latest" "$target"
        echo -e "\033[32mRestored: $target\033[0m"
    fi
}

restore_skill() {
    local type="$1"
    local skill_name="$type"

    echo -e "\n\033[34m>>> Processing Skill ($type)\033[0m"

    local latest=$(ls -t "$STORAGE_DIR"/*"${type}_SKILL.tar.gz" 2>/dev/null | head -1)
    if [[ -z "$latest" ]]; then
        echo -e "\033[31mError: Stored skill archive not found for type $type\033[0m"
        return
    fi

    # Check archive contents for .opencode and .agents
    local has_opencode=0
    local has_agents=0
    local opencode_kind=""
    local agents_kind=""
    local archive_contents=$(tar -tzf "$latest")

    # Determine skill name from archive (for backward compatibility)
    local archive_skill_name=$(echo "$archive_contents" | grep -m1 "^[^.]*/$" | sed 's|/$||')
    if [[ -z "$archive_skill_name" ]]; then
        archive_skill_name=$(echo "$archive_contents" | grep -m1 '^[^.].*\.md$' | sed 's|\.md$||')
    fi
    if [[ -n "$archive_skill_name" ]] && [[ "$archive_skill_name" != ".agents" ]]; then
        skill_name="$archive_skill_name"
    fi

    if echo "$archive_contents" | grep -q "^${skill_name}/"; then
        has_opencode=1
        opencode_kind="dir"
    elif echo "$archive_contents" | grep -q "^${skill_name}\.md$"; then
        has_opencode=1
        opencode_kind="file"
    fi
    if echo "$archive_contents" | grep -q "^\.agents/skills/${skill_name}/"; then
        has_agents=1
        agents_kind="dir"
    elif echo "$archive_contents" | grep -q "^\.agents/skills/${skill_name}\.md$"; then
        has_agents=1
        agents_kind="file"
    fi

    local target_dir="$SKILLS_DIR/$skill_name"
    local atarget_dir="$ASKILLS_DIR/$skill_name"
    local target_file="$SKILLS_DIR/${skill_name}.md"
    local atarget_file="$ASKILLS_DIR/${skill_name}.md"

    # Show what will be restored
    if [[ $has_opencode -eq 1 ]]; then
        if [[ "$opencode_kind" == "dir" ]]; then
            echo -e "  .opencode: $target_dir"
        else
            echo -e "  .opencode: $target_file"
        fi
    fi
    if [[ $has_agents -eq 1 ]]; then
        if [[ "$agents_kind" == "dir" ]]; then
            echo -e "  .agents:   $atarget_dir"
        else
            echo -e "  .agents:   $atarget_file"
        fi
    fi

    # Extract archive to temp dir for comparison
    local temp_dir=$(mktemp -d)
    tar -xzf "$latest" -C "$temp_dir" --exclude="*undo-tree~"

    local diff_found=0
    local need_confirm=0

    # Compare .opencode skills
    if [[ $has_opencode -eq 1 ]]; then
        local extracted_oc
        local target_oc
        if [[ "$opencode_kind" == "dir" ]]; then
            extracted_oc="$temp_dir/$skill_name"
            target_oc="$target_dir"
        else
            extracted_oc="$temp_dir/${skill_name}.md"
            target_oc="$target_file"
        fi
        mkdir -p "$SKILLS_DIR"

        if [[ "$opencode_kind" == "dir" && -d "$target_oc" ]]; then
            echo -e "\033[33m.opencode: $target_oc exists. Comparing...\033[0m"
            find "$target_oc" -type f ! -name "*undo-tree~" -printf "%P\n" | sort > "$temp_dir/local_oc.txt"
            find "$extracted_oc" -type f ! -name "*undo-tree~" -printf "%P\n" | sort > "$temp_dir/archive_oc.txt"

            while IFS= read -r file; do
                local_file="$target_oc/$file"
                archive_file="$extracted_oc/$file"
                if [[ -f "$local_file" && -f "$archive_file" ]]; then
                    if [[ $(stat -c%s "$local_file") -ne $(stat -c%s "$archive_file") ]]; then
                        echo -e "  \033[31m[.opencode] $file (DIFFERENT SIZE)\033[0m"
                        diff_found=1
                    fi
                elif [[ -f "$local_file" ]]; then
                    echo -e "  \033[31m[.opencode] $file (Missing in archive)\033[0m"
                    diff_found=1
                else
                    echo -e "  \033[32m[.opencode] $file (New in archive)\033[0m"
                    diff_found=1
                fi
            done < <(cat "$temp_dir/local_oc.txt" "$temp_dir/archive_oc.txt" | sort -u)

            need_confirm=1
        elif [[ "$opencode_kind" == "file" && -f "$target_oc" ]]; then
            echo -e "\033[33m.opencode: $target_oc exists. Comparing...\033[0m"
            if ! diff -q "$target_oc" "$extracted_oc" > /dev/null; then
                echo -e "  \033[31m[.opencode] ${skill_name}.md differs\033[0m"
                diff_found=1
            fi
            need_confirm=1
        else
            echo -e "\033[32m[.opencode] New ${opencode_kind}: $target_oc\033[0m"
        fi
    fi

    # Compare .agents skills
    if [[ $has_agents -eq 1 ]]; then
        local extracted_ag
        local target_ag
        if [[ "$agents_kind" == "dir" ]]; then
            extracted_ag="$temp_dir/.agents/skills/$skill_name"
            target_ag="$atarget_dir"
        else
            extracted_ag="$temp_dir/.agents/skills/${skill_name}.md"
            target_ag="$atarget_file"
        fi
        mkdir -p "$ASKILLS_DIR"

        if [[ "$agents_kind" == "dir" && -d "$target_ag" ]]; then
            echo -e "\033[33m.agents: $target_ag exists. Comparing...\033[0m"
            find "$target_ag" -type f ! -name "*undo-tree~" -printf "%P\n" | sort > "$temp_dir/local_ag.txt"
            find "$extracted_ag" -type f ! -name "*undo-tree~" -printf "%P\n" | sort > "$temp_dir/archive_ag.txt"

            while IFS= read -r file; do
                local_file="$target_ag/$file"
                archive_file="$extracted_ag/$file"
                if [[ -f "$local_file" && -f "$archive_file" ]]; then
                    if [[ $(stat -c%s "$local_file") -ne $(stat -c%s "$archive_file") ]]; then
                        echo -e "  \033[31m[.agents] $file (DIFFERENT SIZE)\033[0m"
                        diff_found=1
                    fi
                elif [[ -f "$local_file" ]]; then
                    echo -e "  \033[31m[.agents] $file (Missing in archive)\033[0m"
                    diff_found=1
                else
                    echo -e "  \033[32m[.agents] $file (New in archive)\033[0m"
                    diff_found=1
                fi
            done < <(cat "$temp_dir/local_ag.txt" "$temp_dir/archive_ag.txt" | sort -u)

            need_confirm=1
        elif [[ "$agents_kind" == "file" && -f "$target_ag" ]]; then
            echo -e "\033[33m.agents: $target_ag exists. Comparing...\033[0m"
            if ! diff -q "$target_ag" "$extracted_ag" > /dev/null; then
                echo -e "  \033[31m[.agents] ${skill_name}.md differs\033[0m"
                diff_found=1
            fi
            need_confirm=1
        else
            echo -e "\033[32m[.agents] New ${agents_kind}: $target_ag\033[0m"
        fi
    fi

    if [[ $diff_found -eq 0 ]] && [[ $need_confirm -eq 0 ]]; then
        rm -rf "$temp_dir"
    else
        if [[ $diff_found -eq 0 ]]; then
            echo -e "\033[32mNo differences found.\033[0m"
        else
            echo -e "\033[32mNo differences found.\033[0m"
        fi

        echo -n -e "\033[33mOverwrite? (y/N) \033[0m"
        read -n 1 -r REPLY
        echo
        rm -rf "$temp_dir"
        if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then
            echo "Skipped $type"
            return
        fi

        # Remove existing directories before restore
        if [[ $has_opencode -eq 1 ]]; then
            if [[ "$opencode_kind" == "dir" && -d "$target_dir" ]]; then
                rm -rf "$target_dir"
            elif [[ "$opencode_kind" == "file" && -f "$target_file" ]]; then
                rm -f "$target_file"
            fi
        fi
        if [[ $has_agents -eq 1 ]]; then
            if [[ "$agents_kind" == "dir" && -d "$atarget_dir" ]]; then
                rm -rf "$atarget_dir"
            elif [[ "$agents_kind" == "file" && -f "$atarget_file" ]]; then
                rm -f "$atarget_file"
            fi
        fi
    fi

    # Restore .opencode skills
    if [[ $has_opencode -eq 1 ]]; then
        mkdir -p "$SKILLS_DIR"
        if [[ "$opencode_kind" == "dir" ]]; then
            tar -xzf "$latest" -C "$SKILLS_DIR" --exclude="*undo-tree~" "$skill_name"
            echo -e "\033[32mRestored skill to: $target_dir\033[0m"
        else
            tar -xzf "$latest" -C "$SKILLS_DIR" --exclude="*undo-tree~" "${skill_name}.md"
            echo -e "\033[32mRestored skill to: $target_file\033[0m"
        fi
    fi

    # Restore .agents skills
    if [[ $has_agents -eq 1 ]]; then
        mkdir -p "$ASKILLS_DIR"
        local ag_temp=$(mktemp -d)
        tar -xzf "$latest" -C "$ag_temp" --exclude="*undo-tree~" ".agents"
        if [[ "$agents_kind" == "dir" ]]; then
            cp -a "$ag_temp/.agents/skills/$skill_name" "$ASKILLS_DIR/"
            echo -e "\033[32mRestored .agents skill to: $atarget_dir\033[0m"
        else
            cp -a "$ag_temp/.agents/skills/${skill_name}.md" "$ASKILLS_DIR/"
            echo -e "\033[32mRestored .agents skill to: $atarget_file\033[0m"
        fi
        rm -rf "$ag_temp"
    fi
}

restore_subagent() {
    local type="$1"
    echo -e "\n\033[34m>>> Processing Subagent ($type)\033[0m"
    
    local latest=$(ls -t "$STORAGE_DIR"/*"${type}_SUBAGENT.md" 2>/dev/null | head -1)
    if [[ -z "$latest" ]]; then
        echo -e "\033[31mError: Stored subagent not found for type $type\033[0m"
        return
    fi

    local target="$AGENTS_DIR/${type}.md"

    mkdir -p "$AGENTS_DIR"

    if [[ -f "$target" ]]; then
        if ! diff -q "$target" "$latest" > /dev/null; then
            echo "Differences found in ${type}.md:"
            compare_files "$target" "$latest"
            echo -n -e "\033[33mOverwrite $target? (y/N) \033[0m"
            read -n 1 -r REPLY
            echo
            if [[ "$REPLY" =~ ^[Yy]$ ]]; then
                cp "$latest" "$target"
                echo -e "\033[32mRestored: $target\033[0m"
            fi
        else
            echo -e "\033[32m$target is already up to date.\033[0m"
        fi
    else
        cp "$latest" "$target"
        echo -e "\033[32mRestored: $target\033[0m"
    fi
}

load_type_descriptions

# --- Main Loop ---

while true; do
    draw_menu
    read -r input
    
    if [[ "$input" == "q" ]] || [[ "$input" == "Q" ]]; then
        echo -e "\033[31mAborted.\033[0m"
        exit 0
    elif [[ -z "$input" ]]; then
        break
    fi
    
    category=$(key_category "$input" || true)
    if [[ "$category" == "plugin" ]]; then
        idx=$(index_for_key plugin "$input" PLUGIN_KEYS || true)
        if [[ -n "$idx" ]] && [[ $idx -lt ${#PLUGIN_TYPES[@]} ]]; then
            type="${PLUGIN_TYPES[$idx]}"
            tdesc="${TYPE_DESCRIPTIONS["PLUGIN:${type}"]}"
            LAST_DESC=$([[ -n "$tdesc" ]] && echo "${type}: ${tdesc}" || echo "")
            if [[ "${SELECTED_PLUGINS[$type]}" == "1" ]]; then
                unset SELECTED_PLUGINS["$type"]
            else
                SELECTED_PLUGINS["$type"]="1"
            fi
        fi
    elif [[ "$category" == "skill" ]]; then
        idx=$(index_for_key skill "$input" SKILL_KEYS || true)
        if [[ -n "$idx" ]] && [[ $idx -lt ${#SKILL_TYPES[@]} ]]; then
            type="${SKILL_TYPES[$idx]}"
            tdesc="${TYPE_DESCRIPTIONS["SKILL:${type}"]}"
            LAST_DESC=$([[ -n "$tdesc" ]] && echo "${type}: ${tdesc}" || echo "")
            if [[ "${SELECTED_SKILLS[$type]}" == "1" ]]; then
                unset SELECTED_SKILLS["$type"]
            else
                SELECTED_SKILLS["$type"]="1"
            fi
        fi
    elif [[ "$category" == "subagent" ]]; then
        idx=$(index_for_key subagent "$input" SUBAGENT_KEYS || true)
        if [[ -n "$idx" ]] && [[ $idx -lt ${#SUBAGENT_TYPES[@]} ]]; then
            type="${SUBAGENT_TYPES[$idx]}"
            tdesc="${TYPE_DESCRIPTIONS["SUBAGENT:${type}"]}"
            LAST_DESC=$([[ -n "$tdesc" ]] && echo "${type}: ${tdesc}" || echo "")
            if [[ "${SELECTED_SUBAGENTS[$type]}" == "1" ]]; then
                unset SELECTED_SUBAGENTS["$type"]
            else
                SELECTED_SUBAGENTS["$type"]="1"
            fi
        fi
    elif [[ "$input" =~ ^[0-9]+$ ]] && [[ "$input" -ne 10 ]] && [[ "$input" -ge 1 ]]; then
        idx=$(_disp2idx "$input")
        if [[ $idx -ge 0 ]] && [[ $idx -lt ${#AGENT_TYPES[@]} ]]; then
            type="${AGENT_TYPES[$idx]}"
            tdesc="${TYPE_DESCRIPTIONS["AGENTS.md:${type}"]}"
            LAST_DESC=$([[ -n "$tdesc" ]] && echo "${type}: ${tdesc}" || echo "")
            if [[ "$SELECTED_AGENT" == "$type" ]]; then
                SELECTED_AGENT=""
            else
                SELECTED_AGENT="$type"
            fi
        fi
    fi
done

# --- Execute Restorations ---

if [[ -n "$SELECTED_AGENT" ]]; then
    restore_agent "$SELECTED_AGENT"
fi

for type in "${!SELECTED_PLUGINS[@]}"; do
    restore_plugin "$type"
done

for type in "${!SELECTED_SKILLS[@]}"; do
    restore_skill "$type"
done

for type in "${!SELECTED_SUBAGENTS[@]}"; do
    restore_subagent "$type"
done

echo -e "\n\033[32mAll tasks completed.\033[0m"
