#!/bin/bash
# =============================================================================
# Backup & Restore Script with Dialog Progress Bars
# =============================================================================
# Usage:
#   Source this file: source /Data/Backup/backup_restore.sh
#   Then run: backup_function /source/dir /dest/backup.tar.gz
#   Or run:   restore_function /dest/dir
# =============================================================================

# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# =============================================================================
# BACKUP FUNCTION
# =============================================================================
# Usage: backup_function "/path/to/source" "/path/to/backup.tar.gz"
backup_function() {
    local oD_="${1%/}"  # Source directory (remove trailing slash)
    local dF_="$2"       # Destination backup file
    
    # Validate inputs
    if [ -z "$oD_" ] || [ -z "$dF_" ]; then
        echo -e "${RED}Usage: backup_function <source_dir> <backup_file.tar.gz>${NC}"
        return 1
    fi
    
    if [ ! -d "$oD_" ]; then
        echo -e "${RED}Error: Source directory not found: $oD_${NC}"
        return 1
    fi
    
    # Create backup directory if needed
    local backup_dir
    backup_dir=$(dirname "$dF_")
    if ! mkdir -p "$backup_dir"; then
        echo -e "${RED}Error: Cannot create directory: $backup_dir${NC}"
        return 1
    fi
    
    # Get size (use \du to bypass any alias)
    local SIZE
    SIZE=$(\du -sb "$oD_" 2>/dev/null | awk '{print $1}')
    
    if [ -z "$SIZE" ] || [ "$SIZE" -eq 0 ]; then
        echo -e "${RED}Error: Could not determine size of source directory${NC}"
        return 1
    fi
    
    echo -e "${BLUE}Source:${NC} $oD_"
    echo -e "${BLUE}Destination:${NC} $dF_"
    echo -e "${BLUE}Size:${NC} $(numfmt --to=iec $SIZE)"
    echo -e "${YELLOW}Creating backup...${NC}"
    echo ""
    
    # Create backup with dialog progress bar
    (tar cf - "$oD_" | pv -n -s "$SIZE" -i 0.3 | gzip > "$dF_") 2>&1 | \
        dialog --gauge "Creating backup of $(basename "$oD_")..." 10 70 0
    
    clear
    
    # Check result
    if [ $? -eq 0 ] && [ -f "$dF_" ]; then
        echo -e "${GREEN}✓ Backup completed successfully!${NC}"
        echo -e "${GREEN}Saved to:${NC} $dF_"
        echo -e "${BLUE}Size:${NC} $(stat -c%s "$dF_" | numfmt --to=iec)"
        return 0
    else
        echo -e "${RED}✗ Backup failed${NC}"
        return 1
    fi
}

# =============================================================================
# RESTORE FUNCTION
# =============================================================================
# Usage: restore_function "/path/to/restore/destination"
restore_function() {
    local RESTORE_TO="$1"
    local BACKUP_DIR
    
    # Set default restore location if not provided
    if [ -z "$RESTORE_TO" ]; then
        echo -e "${YELLOW}No restore path provided.${NC}"
        read -p "Enter restore destination: " RESTORE_TO
        if [ -z "$RESTORE_TO" ]; then
            echo -e "${RED}No destination specified. Exiting.${NC}"
            return 1
        fi
    fi
    
    # Detect backup directory (use current dir if backups are here, else ask)
    if [ -f *.tar.gz ] 2>/dev/null || [ -n "$(find . -maxdepth 1 -name '*.tar.gz' -print -quit 2>/dev/null)" ]; then
        BACKUP_DIR="$(pwd)"
    else
        read -p "Enter backup directory path: " BACKUP_DIR
        if [ -z "$BACKUP_DIR" ]; then
            echo -e "${RED}No backup directory specified.${NC}"
            return 1
        fi
    fi
    
    if ! cd "$BACKUP_DIR"; then
        echo -e "${RED}Error: Cannot access directory: $BACKUP_DIR${NC}"
        return 1
    fi
    
    # Get all backup files into array (use \ls to bypass eza aliases)
    local BACKUPS=()
    mapfile -t BACKUPS < <(\ls -1t *.tar.gz 2>/dev/null)
    
    if [ ${#BACKUPS[@]} -eq 0 ]; then
        echo -e "${RED}No backup files (.tar.gz) found in $BACKUP_DIR${NC}"
        return 1
    fi
    
    # Display numbered list
    echo ""
    echo -e "${BLUE}Available backups:${NC}"
    echo "--------------------------------------------------"
    local i
    for i in "${!BACKUPS[@]}"; do
        local file_size
        local file_time
        file_size=$(stat -c%s "${BACKUPS[$i]}" 2>/dev/null | numfmt --to=iec)
        file_time=$(stat -c%y "${BACKUPS[$i]}" 2>/dev/null | cut -d'.' -f1)
        printf "%2d) %-50s %8s  [%s]\n" $((i+1)) "${BACKUPS[$i]}" "$file_size" "$file_time"
    done
    echo "--------------------------------------------------"
    
    # Get user choice
    local CHOICE
    read -p "Select backup to restore (1-${#BACKUPS[@]}, or 'q' to quit): " CHOICE
    
    if [[ "$CHOICE" == "q" ]] || [[ "$CHOICE" == "Q" ]]; then
        echo "Cancelled."
        return 0
    fi
    
    # Validate choice
    if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || [ "$CHOICE" -lt 1 ] || [ "$CHOICE" -gt ${#BACKUPS[@]} ]; then
        echo -e "${RED}Invalid selection${NC}"
        return 1
    fi
    
    local SELECTED="${BACKUPS[$((CHOICE-1))]}"
    local SIZE
    SIZE=$(stat -c%s "$SELECTED")
    
    echo ""
    echo -e "${BLUE}Selected:${NC} $SELECTED"
    echo -e "${BLUE}Size:${NC} $(numfmt --to=iec $SIZE)"
    echo -e "${BLUE}Restore to:${NC} $RESTORE_TO"
    echo ""
    
    # Preview archive contents
    echo -e "${YELLOW}Archive contents (first 10 files):${NC}"
    tar tzf "$SELECTED" | head -10
    echo "..."
    echo ""
    
    # Confirm
    local CONFIRM
    read -p "Proceed with restore? (y/N): " CONFIRM
    if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then
        echo "Cancelled."
        return 0
    fi
    
    # Create restore directory
    if ! mkdir -p "$RESTORE_TO"; then
        echo -e "${RED}Error: Cannot create restore directory${NC}"
        return 1
    fi
    
    # Restore with dialog progress bar
    # Using --skip-old-files to avoid overwriting existing files (safe mode)
    echo -e "${YELLOW}Restoring...${NC}"
    
    (pv -n -s "$SIZE" -i 0.5 "$SELECTED" | tar xzf - --skip-old-files -C "$RESTORE_TO") 2>&1 | \
        dialog --gauge "Restoring $(basename "$SELECTED")..." 10 70 0
    
    clear
    
    # Check result
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}✓ Restore completed successfully!${NC}"
        echo -e "${GREEN}Restored to:${NC} $RESTORE_TO"
        echo ""
        echo -e "${BLUE}Restored files:${NC}"
        ls -la "$RESTORE_TO"
        return 0
    else
        echo -e "${RED}✗ Restore failed${NC}"
        return 1
    fi
}

# =============================================================================
# QUICK COMMANDS (optional shortcuts)
# =============================================================================

# Quick backup current directory
backup_here() {
    local name
    name="$(basename "$(pwd)")_$(date +%Y_%m_%d_%H.%M.%S).tar.gz"
    backup_function "$(pwd)" "../$name"
}

# =============================================================================
# MAIN MENU (run without arguments to show menu)
# =============================================================================
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
    # Script was executed directly, not sourced
    cat << 'EOF'
===============================================================================
Backup & Restore Script loaded!
===============================================================================

USAGE:
  backup_function   "/source/dir" "/dest/backup.tar.gz"
  restore_function  "/restore/destination"
  backup_here       (backup current dir with timestamp)

EXAMPLES:
  backup_function "/Data/Documents/Test" "/Data/Backup/test_backup.tar.gz"
  restore_function "/Data/Documents/RestoreHere"

OPTIONS:
  All functions use dialog progress bars and show accurate percentages.
  Restore skips existing files (won't overwrite) for safety.

===============================================================================
EOF
fi