#!/bin/bash

# GremlinModes Backup Script
# This script backs up GremlinModes files from a project to the source GremlinModes repo
# and optionally removes them from the project to allow for clean commits

# 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 Backup${NC}"
echo ""

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

# Make sure .data directory exists
if [ ! -d "$SCRIPT_DIR/.data" ]; then
    mkdir -p "$SCRIPT_DIR/.data"
fi

# Initialize history file if it doesn't exist
if [ ! -f "$SCRIPT_DIR/.data/history.json" ]; then
    echo '{"installations": []}' > "$SCRIPT_DIR/.data/history.json"
fi

# Initialize backups directory
if [ ! -d "$SCRIPT_DIR/.data/backups" ]; then
    mkdir -p "$SCRIPT_DIR/.data/backups"
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}"

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

    for (( i=0; i<$installation_count; i++ )); do
        path=$(jq -r ".installations[$i].path" "$SCRIPT_DIR/.data/history.json")
        
        # Check if the path exists
        if [ -d "$path" ]; then
            install_date=$(jq -r ".installations[$i].date" "$SCRIPT_DIR/.data/history.json")
            echo "  $((i+1)). $path (Installed on $install_date)"
        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 "$installation_count" ]; then
    echo -e "${RED}Error: Selection out of range.${NC}"
    exit 1
fi

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

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

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

# Create a timestamp for the backup
TIMESTAMP=$(date +%Y%m%d%H%M%S)
PROJECT_NAME=$(basename "$selected_path")

# Create backup directory
BACKUP_DIR="$SCRIPT_DIR/.data/backups/${PROJECT_NAME}_${TIMESTAMP}"
mkdir -p "$BACKUP_DIR"

echo -e "${BLUE}Backing up GremlinModes files to: $BACKUP_DIR${NC}"

# Directories to backup (both visible and hidden)
DIRECTORIES=(
    "gremlinmodes"
    ".gremlinmodes"
)

# Files to backup
FILES=(
    "agent.sh"
    "stash.sh"
    ".roomodes"
)

# Function to backup a directory if it exists
backup_directory() {
    local src="$1"
    local dest="$2"
    
    if [ -d "$src" ]; then
        mkdir -p "$dest"
        cp -R "$src"/* "$dest/" 2>/dev/null || true
        echo -e "${GREEN}✓ Backed up $src${NC}"
        return 0
    else
        echo -e "${YELLOW}⚠ Directory $src does not exist, skipping${NC}"
        return 1
    fi
}

# Function to backup a file if it exists
backup_file() {
    local src="$1"
    local dest="$2"
    
    if [ -f "$src" ]; then
        cp "$src" "$dest/"
        echo -e "${GREEN}✓ Backed up $src${NC}"
        return 0
    else
        echo -e "${YELLOW}⚠ File $src does not exist, skipping${NC}"
        return 1
    fi
}

# Backup directories
echo -e "${BLUE}Backing up directories...${NC}"
for dir in "${DIRECTORIES[@]}"; do
    backup_directory "$selected_path/$dir" "$BACKUP_DIR/$dir"
done

# Backup files
echo -e "${BLUE}Backing up files...${NC}"
for file in "${FILES[@]}"; do
    backup_file "$selected_path/$file" "$BACKUP_DIR"
done

# Create a manifest file with information about the backup
cat > "$BACKUP_DIR/backup_manifest.json" << EOL
{
  "project": "$PROJECT_NAME",
  "path": "$selected_path",
  "timestamp": "$TIMESTAMP",
  "date": "$(date)",
  "type": "backup"
}
EOL

# Update backup history in main history file
if command -v jq &> /dev/null; then
    # Check if the installation has a backups array
    has_backups=$(jq -r ".installations[$((selection-1))].backups != null" "$SCRIPT_DIR/.data/history.json" 2>/dev/null || echo "false")

    if [ "$has_backups" = "true" ]; then
        # Add to existing backups array
        jq --arg idx "$((selection-1))" --arg date "$(date +"%Y-%m-%d %H:%M:%S")" --arg backup_dir "$BACKUP_DIR" \
            '.installations[$idx | tonumber].backups += [{"date": $date, "path": $backup_dir}]' "$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 backups array
        jq --arg idx "$((selection-1))" --arg date "$(date +"%Y-%m-%d %H:%M:%S")" --arg backup_dir "$BACKUP_DIR" \
            '.installations[$idx | tonumber].backups = [{"date": $date, "path": $backup_dir}]' "$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

# Ask user if they want to remove the GremlinModes files from the project
echo -e "${BLUE}Do you want to remove the GremlinModes files from the project? (y/n)${NC}"
read -p "> " remove_files

if [[ "$remove_files" =~ ^[Yy]$ ]]; then
    echo -e "${BLUE}Removing GremlinModes files from the project...${NC}"
    
    # Remove directories
    for dir in "${DIRECTORIES[@]}"; do
        if [ -d "$selected_path/$dir" ]; then
            rm -rf "$selected_path/$dir"
            echo -e "${GREEN}✓ Removed $selected_path/$dir${NC}"
        fi
    done
    
    # Remove files
    for file in "${FILES[@]}"; do
        if [ -f "$selected_path/$file" ]; then
            rm "$selected_path/$file"
            echo -e "${GREEN}✓ Removed $selected_path/$file${NC}"
        fi
    done
    
    echo -e "${GREEN}All GremlinModes files have been removed from the project.${NC}"
fi

echo -e "${GREEN}${BOLD}GremlinModes backup complete!${NC}"
echo ""
echo -e "Backup stored in: ${BOLD}$BACKUP_DIR${NC}"
echo ""
echo -e "${BLUE}Next Steps:${NC}"
if [[ "$remove_files" =~ ^[Yy]$ ]]; then
    echo -e "1. Your GremlinModes files have been backed up and removed from the project."
    echo -e "2. You can now commit your code without GremlinModes files included."
    echo -e "3. To restore your GremlinModes files later, run: ${BOLD}./restore.sh${NC}"
else
    echo -e "1. Your GremlinModes files have been backed up but remain in your project."
    echo -e "2. You can restore from this backup later if needed using: ${BOLD}./restore.sh${NC}"
fi
echo ""
echo -e "${GREMLIN}Made with 💚 mischief by gremlinlabs${NC}"