#!/bin/bash

# GremlinModes Restore Script
# This script restores GremlinModes files from a backup to the original project

# Text formatting
BOLD='\033[1m'
GREMLIN='\033[1;38;2;31;204;0m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# Banner
echo -e "${BOLD}${GREMLIN}"
echo "   ▄▄ • ▄▄▄  ▄▄▄ .• ▌ ▄ ·. ▄▄▌  ▪   ▐ ▄ • ▌ ▄ ·.       ·▄▄▄▄  ▄▄▄ ..▄▄ · "
echo "  ▐█ ▀ ▪▀▄ █·▀▄.▀··██ ▐███▪██•  ██ •█▌▐█·██ ▐███▪▪     ██▪ ██ ▀▄.▀·▐█ ▀. "
echo "  ▄█ ▀█▄▐▀▀▄ ▐▀▀▪▄▐█ ▌▐▌▐█·██▪  ▐█·▐█▐▐▌▐█ ▌▐▌▐█· ▄█▀▄ ▐█· ▐█▌▐▀▀▪▄▄▀▀▀█▄"
echo "  ▐█▄▪▐█▐█•█▌▐█▄▄▌██ ██▌▐█▌▐█▌▐▌▐█▌██▐█▌██ ██▌▐█▌▐█▌.▐▌██. ██ ▐█▄▄▌▐█▄▪▐█"
echo "  ·▀▀▀▀ .▀  ▀ ▀▀▀ ▀▀  █▪▀▀▀.▀▀▀ ▀▀▀▀▀ █▪▀▀  █▪▀▀▀ ▀█▄▀▪▀▀▀▀▀•  ▀▀▀  ▀▀▀▀ "
echo -e "${NC}"
echo -e "${BOLD}GremlinModes Restore${NC}"
echo ""

# Determine the directory of the current script (should be in the GremlinModes repo)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Check if the history file exists
if [ ! -f "$SCRIPT_DIR/.data/history.json" ]; then
    echo -e "${RED}Error: No installation history found. Cannot restore without history.${NC}"
    exit 1
fi

# Read the installation history
echo -e "${BLUE}Reading installation history...${NC}"

# Check if jq is available
if command -v jq &> /dev/null; then
    # Use jq to parse the JSON
    installation_count=$(jq '.installations | length' "$SCRIPT_DIR/.data/history.json")

    if [ "$installation_count" -eq 0 ]; then
        echo -e "${RED}Error: No installations found in history.${NC}"
        exit 1
    fi

    echo -e "${GREEN}Found $installation_count installation(s) in history.${NC}"

    # Create an array to store installations with backups
    declare -a installations_with_backups
    declare -a installation_indices
    
    # Find installations with backups
    count=0
    for (( i=0; i<$installation_count; i++ )); do
        path=$(jq -r ".installations[$i].path" "$SCRIPT_DIR/.data/history.json")
        has_backups=$(jq -r ".installations[$i].backups != null" "$SCRIPT_DIR/.data/history.json" 2>/dev/null || echo "false")
        
        if [ "$has_backups" = "true" ]; then
            backup_count=$(jq -r ".installations[$i].backups | length" "$SCRIPT_DIR/.data/history.json")
            
            if [ "$backup_count" -gt 0 ]; then
                # Add to the array of installations with backups
                installations_with_backups[$count]="$path"
                installation_indices[$count]="$i"
                count=$((count + 1))
            fi
        fi
    done
    
    if [ ${#installations_with_backups[@]} -eq 0 ]; then
        echo -e "${RED}Error: No installations with backups found.${NC}"
        echo -e "${YELLOW}Run backup.sh first to create a backup.${NC}"
        exit 1
    fi

    # Display the installations with backups for user selection
    echo -e "${BLUE}Select an installation to restore:${NC}"

    for (( i=0; i<${#installations_with_backups[@]}; i++ )); do
        path="${installations_with_backups[$i]}"
        idx="${installation_indices[$i]}"
        
        # Check if the path exists
        if [ -d "$path" ]; then
            backup_count=$(jq -r ".installations[$idx].backups | length" "$SCRIPT_DIR/.data/history.json")
            echo "  $((i+1)). $path ($backup_count backup(s))"
        else
            backup_count=$(jq -r ".installations[$idx].backups | length" "$SCRIPT_DIR/.data/history.json")
            echo "  $((i+1)). $path (PATH NO LONGER EXISTS) ($backup_count backup(s))"
        fi
    done
else
    echo -e "${RED}Error: jq is required for this script to work.${NC}"
    echo -e "${YELLOW}Please install jq using your package manager (e.g., apt install jq, brew install jq)${NC}"
    exit 1
fi

# Get user selection
read -p "> " selection

# Validate user selection
if ! [[ "$selection" =~ ^[0-9]+$ ]]; then
    echo -e "${RED}Error: Please enter a number.${NC}"
    exit 1
fi

if [ "$selection" -lt 1 ] || [ "$selection" -gt "${#installations_with_backups[@]}" ]; then
    echo -e "${RED}Error: Selection out of range.${NC}"
    exit 1
fi

# Get the selected installation index
selected_idx="${installation_indices[$((selection-1))]}"
selected_path=$(jq -r ".installations[$selected_idx].path" "$SCRIPT_DIR/.data/history.json")

# Get the backups for the selected installation
backup_count=$(jq -r ".installations[$selected_idx].backups | length" "$SCRIPT_DIR/.data/history.json")

echo -e "${GREEN}Selected installation: $selected_path${NC}"
echo -e "${BLUE}Available backups:${NC}"

# Display the backups for the selected installation
for (( i=0; i<$backup_count; i++ )); do
    backup_date=$(jq -r ".installations[$selected_idx].backups[$i].date" "$SCRIPT_DIR/.data/history.json")
    backup_path=$(jq -r ".installations[$selected_idx].backups[$i].path" "$SCRIPT_DIR/.data/history.json")
    
    if [ -d "$backup_path" ]; then
        echo "  $((i+1)). $backup_date"
    else
        echo "  $((i+1)). $backup_date (BACKUP FILES MISSING)"
    fi
done

# Get user selection for backup
echo -e "${BLUE}Select a backup to restore (1-$backup_count):${NC}"
read -p "> " backup_selection

# Validate backup selection
if ! [[ "$backup_selection" =~ ^[0-9]+$ ]]; then
    echo -e "${RED}Error: Please enter a number.${NC}"
    exit 1
fi

if [ "$backup_selection" -lt 1 ] || [ "$backup_selection" -gt "$backup_count" ]; then
    echo -e "${RED}Error: Selection out of range.${NC}"
    exit 1
fi

# Get the selected backup
backup_path=$(jq -r ".installations[$selected_idx].backups[$((backup_selection-1))].path" "$SCRIPT_DIR/.data/history.json")

# Verify that the selected backup still exists
if [ ! -d "$backup_path" ]; then
    echo -e "${RED}Error: Selected backup directory $backup_path does not exist.${NC}"
    exit 1
fi

echo -e "${GREEN}Selected backup: $backup_path${NC}"

# Check if the original project path still exists
if [ ! -d "$selected_path" ]; then
    echo -e "${YELLOW}Warning: The original project directory $selected_path no longer exists.${NC}"
    echo -e "${BLUE}Would you like to specify a different destination path? (y/n)${NC}"
    read -p "> " change_dest
    
    if [[ "$change_dest" =~ ^[Yy]$ ]]; then
        echo -e "${BLUE}Enter new destination path:${NC}"
        read -p "> " selected_path
        
        # Expand ~ to home directory if present
        selected_path="${selected_path/#\~/$HOME}"
        
        # Handle relative paths by converting to absolute paths
        if [[ ! "$selected_path" = /* ]]; then
            selected_path="$(pwd)/$selected_path"
        fi
        
        # Create the directory if it doesn't exist
        if [ ! -d "$selected_path" ]; then
            mkdir -p "$selected_path"
            if [ $? -ne 0 ]; then
                echo -e "${RED}Error: Could not create directory $selected_path${NC}"
                exit 1
            fi
        fi
    else
        echo -e "${RED}Cannot restore to a non-existent directory. Exiting.${NC}"
        exit 1
    fi
fi

# Ensure the destination path exists
if [ ! -d "$selected_path" ]; then
    mkdir -p "$selected_path"
    if [ $? -ne 0 ]; then
        echo -e "${RED}Error: Could not create directory $selected_path${NC}"
        exit 1
    fi
fi

# Check for existing GremlinModes files at the destination
GREMLIN_EXISTS=false
if [ -d "$selected_path/gremlinmodes" ] || [ -d "$selected_path/.gremlinmodes" ] || [ -f "$selected_path/agent.sh" ] || [ -f "$selected_path/stash.sh" ] || [ -f "$selected_path/.roomodes" ]; then
    GREMLIN_EXISTS=true
    echo -e "${YELLOW}Warning: GremlinModes files already exist at the destination.${NC}"
    echo -e "${BLUE}How would you like to proceed?${NC}"
    echo "  1. Merge (keep existing files, add missing ones)"
    echo "  2. Replace (remove existing files, then restore from backup)"
    echo "  3. Cancel"
    read -p "> " conflict_resolution
    
    case $conflict_resolution in
        1)
            echo -e "${BLUE}Will merge files from backup with existing files.${NC}"
            ;;
        2)
            echo -e "${BLUE}Will replace existing files with backup.${NC}"
            # Remove existing GremlinModes files
            if [ -d "$selected_path/gremlinmodes" ]; then
                rm -rf "$selected_path/gremlinmodes"
            fi
            if [ -d "$selected_path/.gremlinmodes" ]; then
                rm -rf "$selected_path/.gremlinmodes"
            fi
            if [ -f "$selected_path/agent.sh" ]; then
                rm "$selected_path/agent.sh"
            fi
            if [ -f "$selected_path/stash.sh" ]; then
                rm "$selected_path/stash.sh"
            fi
            if [ -f "$selected_path/.roomodes" ]; then
                rm "$selected_path/.roomodes"
            fi
            ;;
        3)
            echo -e "${YELLOW}Restore cancelled.${NC}"
            exit 0
            ;;
        *)
            echo -e "${RED}Invalid option. Exiting.${NC}"
            exit 1
            ;;
    esac
fi

echo -e "${BLUE}Restoring GremlinModes files to: $selected_path${NC}"

# Restore directories
for dir in "gremlinmodes" ".gremlinmodes"; do
    if [ -d "$backup_path/$dir" ]; then
        # Create the directory if it doesn't exist
        if [ ! -d "$selected_path/$dir" ]; then
            mkdir -p "$selected_path/$dir"
        fi
        
        # Copy files from backup
        cp -R "$backup_path/$dir/"* "$selected_path/$dir/" 2>/dev/null || true
        echo -e "${GREEN}✓ Restored $dir${NC}"
    else
        echo -e "${YELLOW}⚠ Directory $dir not found in backup, skipping${NC}"
    fi
done

# Restore individual files
for file in "agent.sh" "stash.sh" ".roomodes"; do
    if [ -f "$backup_path/$file" ]; then
        cp "$backup_path/$file" "$selected_path/"
        
        # Make scripts executable
        if [ "$file" = "agent.sh" ] || [ "$file" = "stash.sh" ]; then
            chmod +x "$selected_path/$file"
        fi
        
        echo -e "${GREEN}✓ Restored $file${NC}"
    else
        echo -e "${YELLOW}⚠ File $file not found in backup, skipping${NC}"
    fi
done

# Update the history file with the restore operation if the destination path has changed
if [ "$selected_path" != "$(jq -r ".installations[$selected_idx].path" "$SCRIPT_DIR/.data/history.json")" ]; then
    echo -e "${BLUE}Updating history with new destination path...${NC}"
    
    # Add a new installation entry for the new path
    current_datetime=$(date +"%Y-%m-%d %H:%M:%S")
    new_installation="{\"path\":\"$selected_path\",\"date\":\"$current_datetime\",\"type\":\"restore\",\"restored_from\":\"$backup_path\"}"
    
    jq --arg new "$new_installation" '.installations += [$new | fromjson]' "$SCRIPT_DIR/.data/history.json" > "$SCRIPT_DIR/.data/history.json.tmp" && mv "$SCRIPT_DIR/.data/history.json.tmp" "$SCRIPT_DIR/.data/history.json"
else
    # Add a restore record to the existing installation
    echo -e "${BLUE}Adding restore record to history...${NC}"
    current_datetime=$(date +"%Y-%m-%d %H:%M:%S")
    
    # Check if the installation has a restores array
    has_restores=$(jq -r ".installations[$selected_idx].restores != null" "$SCRIPT_DIR/.data/history.json" 2>/dev/null || echo "false")
    
    if [ "$has_restores" = "true" ]; then
        # Add to existing restores array
        jq --arg idx "$selected_idx" --arg date "$current_datetime" --arg backup_path "$backup_path" \
            '.installations[$idx | tonumber].restores += [{"date": $date, "restored_from": $backup_path}]' "$SCRIPT_DIR/.data/history.json" > "$SCRIPT_DIR/.data/history.json.tmp" && \
            mv "$SCRIPT_DIR/.data/history.json.tmp" "$SCRIPT_DIR/.data/history.json"
    else
        # Create restores array
        jq --arg idx "$selected_idx" --arg date "$current_datetime" --arg backup_path "$backup_path" \
            '.installations[$idx | tonumber].restores = [{"date": $date, "restored_from": $backup_path}]' "$SCRIPT_DIR/.data/history.json" > "$SCRIPT_DIR/.data/history.json.tmp" && \
            mv "$SCRIPT_DIR/.data/history.json.tmp" "$SCRIPT_DIR/.data/history.json"
    fi
fi

echo -e "${GREEN}${BOLD}GremlinModes restore complete!${NC}"
echo ""
echo -e "Restored files from: ${BOLD}$backup_path${NC}"
echo -e "To: ${BOLD}$selected_path${NC}"
echo ""
echo -e "${BLUE}Next Steps:${NC}"
echo -e "1. Navigate to your project folder: cd ${BOLD}$selected_path${NC}"
echo -e "2. Select an agent to begin working with: ${BOLD}./agent.sh${NC}"
echo -e "3. Use ${BOLD}./stash.sh${NC} to manage GremlinModes files for git commits"
echo ""
echo -e "${GREMLIN}Made with 💚 mischief by gremlinlabs${NC}"