#!/usr/bin/env bash
#
##################################################################
#                                                                #
# Attempt to automate installing Wabbajack on Linux Steam/Proton #
#                                                                #
#                     v0.20 - Refactored                         #1
#                                                                #
##################################################################

# Set up logging
LOGFILE="$HOME/wabbajack-via-proton-sh.log"
echo "" > "$LOGFILE"

# Script configuration
SCRIPT_VERSION="0.20"
STEAM_IS_FLATPAK=0
VERBOSE=0
CURRENT_TASK=""
TOTAL_TASKS=10
CURRENT_TASK_NUM=0
IN_MODIFICATION_PHASE=0  # Add this flag

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        -v|--verbose)
            VERBOSE=1
            shift
            ;;
        *)
            display "Unknown option: $1" "$RED"
            display "Usage: $0 [-v|--verbose]" "$YELLOW"
            exit 1
            ;;
    esac
done

# URLs for resources
WABBALIST_URL="https://raw.githubusercontent.com/wabbajack-tools/mod-lists/master/README.md"
WEBVIEW_INSTALLER_URL="https://files.omnigaming.org/MicrosoftEdgeWebView2RuntimeInstallerX64-WabbajackProton.exe"
SYSTEM_REG_URL="https://github.com/Omni-guides/Wabbajack-Modlist-Linux/raw/refs/heads/main/files/system.reg.github"
USER_REG_URL="https://github.com/Omni-guides/Wabbajack-Modlist-Linux/raw/refs/heads/main/files/user.reg.github"

# Color codes for pretty output
GREEN="\e[32m"
YELLOW="\e[33m"
RED="\e[31m"
RESET="\e[0m"

# Logging function
log() {
    local message="$1"
    local log_level="${2:-INFO}"
    local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$log_level] $message" >> "$LOGFILE"
    
    # If verbose mode is enabled, also print to console
    if [[ $VERBOSE -eq 1 ]]; then
        echo "[$timestamp] [$log_level] $message"
    fi
}

# Display and logging function
display() {
    local message="$1"
    local color="${2:-$RESET}"
    # Only log to file if it's not a user prompt or selection
    if [[ ! "$message" =~ "Please select" ]] && [[ ! "$message" =~ "Enter the number" ]]; then
        log "$message"
    fi
    echo -e "${color}${message}${RESET}"
}

# Verbose logging function
verbose_log() {
    if [[ $VERBOSE -eq 1 ]]; then
        log "$1" "VERBOSE"
    fi
}

# Section header function
log_section() {
    local message="$1"
    local separator="============================================"
    log "$separator"
    log "$message"
    log "$separator"
    if [[ $VERBOSE -eq 1 ]]; then
        echo -e "${YELLOW}$separator${RESET}"
        echo -e "${YELLOW}$message${RESET}"
        echo -e "${YELLOW}$separator${RESET}"
    fi
}

# Error handling function
error_exit() {
    display "$1" "$RED"
    log "$1" "ERROR"
    cleanup_wine_procs
    exit 1
}

# Progress bar function
update_progress() {
    # Only show progress bar during modification phase
    if [[ $IN_MODIFICATION_PHASE -eq 0 ]]; then
        return
    fi
    
    local percent=$1
    local bar_length=50
    local filled_length=$((percent * bar_length / 100))
    local bar=""
    
    # Create the bar string with = for filled portions
    for ((i = 0; i < bar_length; i++)); do
        if [ $i -lt $filled_length ]; then
            bar+="="
        else
            bar+=" "
        fi
    done
    
    # Use \r to return to start of line and overwrite previous progress
    printf "\r[%-${bar_length}s] %d%% - %s" "$bar" "$percent" "$CURRENT_TASK"
}

# Set current task function
set_current_task() {
    CURRENT_TASK="$1"
    
    # Only increment and show progress during modification phase
    if [[ $IN_MODIFICATION_PHASE -eq 1 ]]; then
        # Calculate percentage based on modification phase tasks
        local total_mod_tasks=11  # Updated to account for split configure_prefix tasks
        local percent=0
        
        # Only show 100% when we're actually complete
        if [[ "$CURRENT_TASK" == "Complete" ]]; then
            percent=100
        else
            # Calculate percentage based on current task number
            percent=$((CURRENT_TASK_NUM * 100 / total_mod_tasks))
            # Ensure we don't hit 100% before completion
            if [[ $percent -ge 100 ]]; then
                percent=99
            fi
        fi
        
        # Clear the current line before updating progress
        printf "\r%-100s\r" ""
        update_progress "$percent"
        
        # Increment task counter after displaying progress
        CURRENT_TASK_NUM=$((CURRENT_TASK_NUM + 1))
    fi
}

# Download function that uses either wget or curl
download_file() {
    local url="$1"
    local output_path="$2"
    local description="${3:-file}"
    
    # Only log to file, don't display to user
    log "Downloading $description..."
    
    if command -v wget &>/dev/null; then
        if wget "$url" -O "$output_path" >>"$LOGFILE" 2>&1; then
            log "Downloaded $description successfully using wget"
            return 0
        else
            error_exit "Failed to download $description with wget"
        fi
    elif command -v curl &>/dev/null; then
        if curl -sLo "$output_path" "$url" >>"$LOGFILE" 2>&1; then
            log "Downloaded $description successfully using curl"
            return 0
        else
            error_exit "Failed to download $description with curl"
        fi
    else
        error_exit "Neither wget nor curl is available. Cannot download $description"
    fi
}

display_banner() {
    echo "╔══════════════════════════════════════════════════════════════════╗"
    echo "║                  Wabbajack Proton Setup v$SCRIPT_VERSION                    ║"
    echo "║                                                                  ║"
    echo "║        A tool for running Wabbajack on Linux via Proton          ║"
    echo "╚══════════════════════════════════════════════════════════════════╝"
    
    echo ""
    display "This script automates setting up Wabbajack to run on Linux via Steam's Proton compatibility layer." "$YELLOW"
    echo "───────────────────────────────────────────────────────────────────"
    display "Please be aware that this is experimental software and is *NOT* supported by the Wabbajack team." "$YELLOW"
    display "If you encounter issues, please report them on GitHub or the #unofficial-linux-support channel on Discord." "$YELLOW"
    echo "───────────────────────────────────────────────────────────────────"
    display "⚠ IMPORTANT: Use this script at your own risk." "$RED"
    echo ""
    echo -e "\e[33mPress any key to continue...\e[0m"
    read -n 1 -s -r -p ""
    echo ""
}

detect_steamdeck() {
    if [ -f "/etc/os-release" ] && grep -q "steamdeck" "/etc/os-release"; then
        STEAMDECK=1
        log "Running on Steam Deck"
    else
        STEAMDECK=0
        log "NOT running on Steam Deck"
    fi
}

detect_protontricks() {
    # Only log to file, don't display to user
    log "Detecting protontricks installation..."

    if command -v protontricks >/dev/null 2>&1; then
        PROTONTRICKS_PATH=$(command -v protontricks)
        # Check if the detected binary is actually a Flatpak wrapper
        if [[ -f "$PROTONTRICKS_PATH" ]] && grep -q "flatpak run" "$PROTONTRICKS_PATH"; then
            log "Detected Protontricks is a Flatpak wrapper at $PROTONTRICKS_PATH"
            WHICH_PROTONTRICKS="flatpak"
            return 0
        else
            log "Native Protontricks found at $PROTONTRICKS_PATH"
            WHICH_PROTONTRICKS="native"
            return 0
        fi
    elif flatpak list | grep -iq protontricks; then
        log "Flatpak Protontricks is installed"
        WHICH_PROTONTRICKS="flatpak"
        return 0
    else
        log "Protontricks not found. Do you wish to install it? (y/n): "
        display "Protontricks not found. Do you wish to install it? (y/n): " "$RED"
        read -p " " answer
        if [[ $answer =~ ^[Yy]$ ]]; then
            if [[ $STEAMDECK -eq 1 ]]; then
                if flatpak install -u -y --noninteractive flathub com.github.Matoking.protontricks; then
                    WHICH_PROTONTRICKS="flatpak"
                    return 0
                else
                    display "\n\e[31mFailed to install Protontricks via Flatpak. Please install it manually and rerun this script.\e[0m" "$RED"
                    exit 1
                fi
            else
                read -p "Choose installation method: 1) Flatpak (preferred) 2) Native: " choice
                if [[ $choice =~ 1 ]]; then
                    if flatpak install -u -y --noninteractive flathub com.github.Matoking.protontricks; then
                        WHICH_PROTONTRICKS="flatpak"
                        return 0
                    else
                        display "\n\e[31mFailed to install Protontricks via Flatpak. Please install it manually and rerun this script.\e[0m" "$RED"
                        exit 1
                    fi
                else
                    display "Sorry, there are too many distros to automate this!"
                    display "Please check how to install Protontricks using your OS package manager (yum, dnf, apt, pacman, etc.)"
                    display "\e[31mProtontricks is required for this script to function. Exiting.\e[0m" "$RED"
                    exit 1
                fi
            fi
        else
            display "\e[31mProtontricks is required for this script to function. Exiting.\e[0m" "$RED"
            exit 1
        fi
    fi
}

setup_protontricks_alias() {
    set_current_task "Setting up Protontricks aliases"
    if [[ "$WHICH_PROTONTRICKS" = "flatpak" ]]; then
        local protontricks_alias_exists=$(grep "^alias protontricks=" ~/.bashrc)
        local launch_alias_exists=$(grep "^alias protontricks-launch" ~/.bashrc)

        if [[ -z "$protontricks_alias_exists" ]]; then
            display "Adding protontricks alias to ~/.bashrc" "$YELLOW"
            echo "alias protontricks='flatpak run com.github.Matoking.protontricks'" >> ~/.bashrc
            source ~/.bashrc
        else
            log "protontricks alias already exists in ~/.bashrc"
        fi

        if [[ -z "$launch_alias_exists" ]]; then
            display "Adding protontricks-launch alias to ~/.bashrc" "$YELLOW"
            echo "alias protontricks-launch='flatpak run --command=protontricks-launch com.github.Matoking.protontricks'" >> ~/.bashrc
            source ~/.bashrc
        else
            log "protontricks-launch alias already exists in ~/.bashrc"
        fi
    else
        log "Protontricks is not installed via flatpak, skipping alias creation"
    fi
}

run_protontricks() {
    # Determine the protontricks binary path
    verbose_log "Running protontricks with arguments: $*"
    
    if [ "$WHICH_PROTONTRICKS" = "flatpak" ]; then
        verbose_log "Using Flatpak protontricks"
        # Redirect Wine output to /dev/null but keep protontricks output
        if [[ "$*" == *"-c"* ]]; then
            # For Wine commands, suppress output but check exit code
            if flatpak run com.github.Matoking.protontricks "$@" >/dev/null 2>&1; then
                return 0
            else
                return 1
            fi
        else
            # For non-Wine commands, show output but redirect stderr to /dev/null
            flatpak run com.github.Matoking.protontricks "$@" 2>/dev/null
        fi
    else
        verbose_log "Using native protontricks"
        # Redirect Wine output to /dev/null but keep protontricks output
        if [[ "$*" == *"-c"* ]]; then
            # For Wine commands, suppress output but check exit code
            if protontricks "$@" >/dev/null 2>&1; then
                return 0
            else
                return 1
            fi
        else
            # For non-Wine commands, show output but redirect stderr to /dev/null
            protontricks "$@" 2>/dev/null
        fi
    fi
}

check_protontricks_version() {
    set_current_task "Checking Protontricks version"
    # Get the current version of protontricks
    local protontricks_version=$(run_protontricks -V | cut -d ' ' -f 2 | sed 's/[()]//g' | sed 's/\.[0-9]$//')
    local protontricks_version_cleaned=$(echo "$protontricks_version" | sed 's/[^0-9.]//g')
    
    log "Protontricks Version: $protontricks_version_cleaned"
    
    # Compare version strings
    if [[ "$protontricks_version_cleaned" < "1.12" ]]; then
        error_exit "Your protontricks version is too old! Update to version 1.12 or newer and rerun this script."
    fi
}

get_wabbajack_path() {
    set_current_task "Detecting Wabbajack path"
    local wabbajack_path=""
    local wabbajack_entries=()
    local app_ids=()
    local app_names=()
    local all_app_ids=()
    local all_app_names=()
    local selection=""
    local use_all_shortcuts=0

    log "Detecting Wabbajack Install Directory..."
    verbose_log "Attempting to find Wabbajack entries using protontricks -l"

    # First, try to find Wabbajack entries using protontricks
    local protontricks_entries=$(run_protontricks -l | grep -i 'Non-Steam shortcut' | grep -i wabbajack)
    verbose_log "Protontricks output: $protontricks_entries"

    if [[ -n "$protontricks_entries" ]]; then
        log "Found Wabbajack entries via protontricks (name match)"
        while IFS= read -r line; do
            local app_id=$(echo "$line" | awk '{print $NF}' | sed 's:^.\(.*\).$:\1:')
            local app_name=$(echo "$line" | sed 's/^Non-Steam shortcut: //i' | sed 's: ([0-9]*)$::')
            if [[ -n "$app_id" ]]; then
                app_ids+=("$app_id")
                app_names+=("$app_name")
                log "Found App ID: $app_id, Name: $app_name"
            fi
        done <<< "$protontricks_entries"

        echo ""
        display "Wabbajack-related Steam entries found. Please select which one you wish to configure:" "$RED"
        for i in "${!app_ids[@]}"; do
            echo "$((i + 1)). ${app_names[i]} (App ID: ${app_ids[i]})"
        done
        local extra_option=$(( ${#app_ids[@]} + 1 ))
        echo "$extra_option. List all Steam shortcuts"
        echo "Please select the entry you want to use (1-$extra_option):"
        read -r selection
        if [[ "$selection" == "$extra_option" ]]; then
            use_all_shortcuts=1
        elif [[ "$selection" =~ ^[0-9]+$ ]] && ((selection >= 1 && selection <= ${#app_ids[@]})); then
            APPID="${app_ids[$((selection - 1))]}"
            log "Selected App ID: $APPID, Name: ${app_names[$((selection - 1))]}"
        else
            use_all_shortcuts=1
        fi
    else
        use_all_shortcuts=1
    fi

    # If requested, list all Non-Steam shortcuts
    if [[ $use_all_shortcuts -eq 1 ]]; then
        local all_entries=$(run_protontricks -l | grep -i 'Non-Steam shortcut')
        if [[ -z "$all_entries" ]]; then
            error_exit "No Non-Steam shortcuts found via protontricks. Please ensure you've added your entry as a non-Steam game and run it once via Steam."
        fi
        while IFS= read -r line; do
            local app_id=$(echo "$line" | awk '{print $NF}' | sed 's:^.\(.*\).$:\1:')
            local app_name=$(echo "$line" | sed 's/^Non-Steam shortcut: //i' | sed 's: ([0-9]*)$::')
            if [[ -n "$app_id" ]]; then
                all_app_ids+=("$app_id")
                all_app_names+=("$app_name")
                log "Found App ID: $app_id, Name: $app_name (all shortcuts)"
            fi
        done <<< "$all_entries"
        echo ""
        display "All Steam shortcuts detected. Please select which one you wish to configure:" "$RED"
        for i in "${!all_app_ids[@]}"; do
            echo "$((i + 1)). ${all_app_names[i]} (App ID: ${all_app_ids[i]})"
        done
        echo "Please select the entry you want to use (1-${#all_app_ids[@]}):"
        read -r selection
        if ! [[ "$selection" =~ ^[0-9]+$ ]] || ((selection < 1 || selection > ${#all_app_ids[@]})); then
            error_exit "Invalid selection"
        fi
        APPID="${all_app_ids[$((selection - 1))]}"
        log "Selected App ID: $APPID, Name: ${all_app_names[$((selection - 1))]}"
        echo ""
        echo "If you don't see your Wabbajack entry in the list, please make sure you have added it to Steam, set the Proton version, and run it once (then closed Wabbajack)."
    fi

    # Now that we have the App ID, try to find the executable path in shortcuts.vdf
    verbose_log "Attempting to find executable path for App ID: $APPID"
    local steam_userdata_paths=(
        "$HOME/.steam/steam/userdata"
        "$HOME/.local/share/Steam/userdata"
        "$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/userdata"
    )
    local wabbajack_entries=()
    for path in "${steam_userdata_paths[@]}"; do
        if [[ -d "$path" ]]; then
            verbose_log "Checking directory: $path"
            local vdf_files=$(find "$path" -name "shortcuts.vdf" 2>/dev/null)
            for vdf_file in $vdf_files; do
                if [[ "$vdf_file" == *"12345678"* ]]; then
                    verbose_log "Skipping test directory shortcuts.vdf: $vdf_file"
                    continue
                fi
                verbose_log "Checking shortcuts.vdf: $vdf_file"
                while IFS= read -r line; do
                    if [[ "$line" == */Wabbajack.exe* ]]; then
                        local path=$(echo "$line" | sed -E 's/.*"([^"*Wabbajack\\.exe[^"]*)".*$/\1/')
                        if [[ -n "$path" ]]; then
                            if [[ "$path" != *".wabbajack_test"* ]]; then
                                verbose_log "Found Wabbajack.exe path: $path"
                                wabbajack_entries+=("$path")
                            else
                                verbose_log "Skipping test directory entry: $path"
                            fi
                        fi
                    fi
                done < <(strings "$vdf_file" | grep -i "/Wabbajack.exe")
            done
        fi
    done
    readarray -t unique_entries < <(printf '%s\n' "${wabbajack_entries[@]}" | sort -u)
    wabbajack_entries=("${unique_entries[@]}")
    # Sort alphabetically for user-friendly order
    IFS=$'\n' wabbajack_entries=($(sort <<<"${wabbajack_entries[*]}"))
    unset IFS

    # Build a mapping from App ID to Wabbajack.exe path
    declare -A appid_to_path
    for path in "${wabbajack_entries[@]}"; do
        # Try to extract the App ID from the path's parent directory name (assumes unique per shortcut)
        for i in "${!all_app_ids[@]}"; do
            if [[ "$path" == *"${all_app_names[$i]}"* ]]; then
                appid_to_path["${all_app_ids[$i]}"]="$path"
            fi
        done
    done
    # If we have a sorted app_ids array, display the paths in that order
    ordered_paths=()
    for id in "${app_ids[@]}"; do
        if [[ -n "${appid_to_path[$id]}" ]]; then
            ordered_paths+=("${appid_to_path[$id]}")
        fi
    done
    # Only use ordered_paths if it matches the number of app_ids
    if [[ ${#ordered_paths[@]} -eq ${#app_ids[@]} ]]; then
        wabbajack_entries=("${ordered_paths[@]}")
    fi
    local entry_count=${#wabbajack_entries[@]}
    verbose_log "Found $entry_count unique Wabbajack.exe entries (ordered by shortcut name)"
    if [[ "$entry_count" -eq 0 ]]; then
        error_exit "No Wabbajack.exe entries found in shortcuts.vdf. Please ensure you've added Wabbajack.exe as a non-Steam game and run it once via Steam."
    elif [[ "$entry_count" -gt 1 ]]; then
        echo ""
        display "Multiple Wabbajack.exe paths found, please select which one you wish to configure:" "$RED"
        local i=1
        for path in "${wabbajack_entries[@]}"; do
            echo "$i) $path"
            ((i++))
        done
        local selected_entry=""
        while [[ ! "$selected_entry" =~ ^[0-9]+$ || "$selected_entry" -lt 1 || "$selected_entry" -gt "$entry_count" ]]; do
            read -p "Enter the number of the desired entry (1-$entry_count): " selected_entry
            if [[ ! "$selected_entry" =~ ^[0-9]+$ || "$selected_entry" -lt 1 || "$selected_entry" -gt "$entry_count" ]]; then
                display "Invalid selection. Please enter a number between 1 and $entry_count" "$RED"
            fi
        done
        wabbajack_path="${wabbajack_entries[$((selected_entry - 1))]}"
        log "Selected Wabbajack path: $wabbajack_path"
        echo ""
    else
        wabbajack_path="${wabbajack_entries[0]}"
        log "Single Wabbajack path found: $wabbajack_path"
    fi
    if [[ -n "$wabbajack_path" ]]; then
        log "Using Wabbajack path: $wabbajack_path"
        APPLICATION_DIRECTORY=$(dirname "$wabbajack_path")
        # Sanitize: remove any stray quotes and trim whitespace/newlines
        APPLICATION_DIRECTORY=$(echo "$APPLICATION_DIRECTORY" | tr -d '"' | xargs)
        log "Application Directory: $APPLICATION_DIRECTORY"
        return 0
    else
        error_exit "Failed to determine Wabbajack path"
    fi
}

detect_compatdata_path() {
    set_current_task "Detecting compatdata path"
    # Check common Steam library locations first
    local steam_paths=(
        "$HOME/.local/share/Steam/steamapps/compatdata"
        "$HOME/.steam/steam/steamapps/compatdata"
        "$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/compatdata"
    )
    
    for path in "${steam_paths[@]}"; do
        if [[ -d "$path/$APPID" ]]; then
            COMPAT_DATA_PATH="$path/$APPID"
            log "compatdata Path detected: $COMPAT_DATA_PATH"
            return 0
        fi
    done
    
    # If not found in common locations, use find command with specific paths
    local found=0
    for base_path in "${steam_paths[@]}"; do
        if [[ -d "$base_path" ]]; then
            if [[ -d "$base_path/$APPID" ]]; then
                COMPAT_DATA_PATH="$base_path/$APPID"
                log "compatdata Path detected: $COMPAT_DATA_PATH"
                found=1
                break
            fi
        fi
    done
    
    if [[ $found -eq 0 ]]; then
        error_exit "Directory named '$APPID' not found in any compatdata directories. Please ensure you have started the Steam entry for Wabbajack at least once."
    fi
}

set_protontricks_perms() {
    set_current_task "Setting Protontricks permissions"
    if [ "$WHICH_PROTONTRICKS" = "flatpak" ]; then
        # Only log to file, don't display to user
        log "Setting Protontricks permissions..."
        
        # Always set Flatpak override for the application directory, suppressing error output
        flatpak override --user com.github.Matoking.protontricks --filesystem="$APPLICATION_DIRECTORY" 2>>"$LOGFILE"
        
        if [[ "$STEAMDECK" = 1 ]]; then
            log "Checking for SDCard and setting permissions appropriately..."
            # Set protontricks SDCard permissions early to suppress warning
            sdcard_path=$(df -h | grep "/run/media" | awk '{print $NF}')
            log "SD Card path: $sdcard_path"
            if [[ -n "$sdcard_path" ]]; then
                flatpak override --user --filesystem="$sdcard_path" com.github.Matoking.protontricks 2>>"$LOGFILE"
                log "SD Card permission set"
            fi
        fi
    else
        log "Using Native protontricks, skip setting permissions"
    fi
}

webview_installer() {
    set_current_task "Downloading WebView installer"
    log "Setting up WebView..."
    local installer_path="$APPLICATION_DIRECTORY/MicrosoftEdgeWebView2RuntimeInstallerX64-WabbajackProton.exe"
    # Download if not present
    if [ ! -f "$installer_path" ]; then
        download_file "$WEBVIEW_INSTALLER_URL" "$installer_path" "WebView Installer"
    else
        log "WebView Installer already exists, skipping download"
    fi
    # Check installer exists before running
    if [ ! -f "$installer_path" ]; then
        log "ERROR: WebView installer not found at $installer_path"
        error_exit "WebView installer missing"
    fi
    # Always run the installer in the correct prefix using run_protontricks, capturing output
    set_current_task "Installing WebView runtime (this may take a while)..."
    log "Installing WebView..."
    local webview_tmp_log
    webview_tmp_log="$(mktemp)"
    if ! run_protontricks -c "wine \"$installer_path\" /silent /install" "$APPID" > "$webview_tmp_log" 2>&1; then
        log "ERROR: Failed to install WebView. See $LOGFILE for details."
        echo "--- WebView Installer Output ---" >> "$LOGFILE"
        cat "$webview_tmp_log" >> "$LOGFILE"
        echo "--- End WebView Installer Output ---" >> "$LOGFILE"
        rm -f "$webview_tmp_log"
        display "Failed to install WebView. See $LOGFILE for details.\nYou may need to install the WebView2 runtime manually inside the Proton prefix." "$RED"
        error_exit "Failed to install WebView. See $LOGFILE for details."
    fi
    rm -f "$webview_tmp_log"
}

detect_link_steam_library() {
    local steam_library_paths=()
    local libraryfolders_vdf=""
    
    # Only log to file, don't display to user
    log "Discovering Steam libraries..."
    
    # Find libraryfolders.vdf and extract library paths
    local vdf_paths=(
        "$HOME/.steam/steam/steamapps/libraryfolders.vdf"
        "$HOME/.local/share/Steam/steamapps/libraryfolders.vdf"
        "$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/libraryfolders.vdf"
    )
    
    for vdf_path in "${vdf_paths[@]}"; do
        if [[ -f "$vdf_path" ]]; then
            if [[ ! -r "$vdf_path" ]]; then
                log "Found libraryfolders.vdf at $vdf_path but it's not readable"
                continue
            fi
            libraryfolders_vdf="$vdf_path"
            log "Found readable libraryfolders.vdf at $vdf_path"
            break
        fi
    done
    
    if [[ -z "$libraryfolders_vdf" ]]; then
        display "Steam libraryfolders.vdf not found. Manual input required." "$RED"
        read -e -p "Enter the path to your main Steam directory: " steam_library_path
        
        while true; do
            if [[ ! -d "$steam_library_path" ]]; then
                display "Invalid path. Please enter a valid directory." "$RED"
            elif [[ ! -f "$steam_library_path/steamapps/libraryfolders.vdf" ]]; then
                display "The specified path does not appear to be a Steam directory. Do not enter a secondary Steam Library path, only the main Steam install path." "$RED"
            elif [[ ! -r "$steam_library_path/steamapps/libraryfolders.vdf" ]]; then
                display "The libraryfolders.vdf file exists but is not readable. Please check permissions." "$RED"
            else
                read -p "Confirm using '$steam_library_path' as the Steam directory path? (y/n): " -r choice
                if [[ "$choice" =~ ^[Yy]$ ]]; then
                    libraryfolders_vdf="$steam_library_path/steamapps/libraryfolders.vdf"
                    CHOSEN_LIBRARY="$steam_library_path"
                    break
                fi
            fi
            read -e -p "Enter the path to your Steam library: " steam_library_path
        done
    fi
    
    if [[ -n "$libraryfolders_vdf" ]]; then
        # Parse libraryfolders.vdf
        while IFS= read -r line; do
            if [[ "$line" =~ \"path\" ]]; then
                local path=$(echo "$line" | sed 's/.*"\(.*\)".*/\1/')
                if [[ -d "$path" && -r "$path" ]]; then
                    steam_library_paths+=("$path")
                    log "Found valid Steam library at: $path"
                else
                    log "Found Steam library path but it's not accessible: $path"
                fi
            fi
        done < <(grep "\"path\"" "$libraryfolders_vdf")
        
        if [[ ${#steam_library_paths[@]} -gt 0 ]]; then
            # Use the first library path found as the chosen library
            CHOSEN_LIBRARY="${steam_library_paths[0]}"
            log "Selected Steam library: $CHOSEN_LIBRARY"
        else
            error_exit "No accessible Steam library paths found in libraryfolders.vdf"
        fi
    else
        error_exit "Steam library not found"
    fi
}

configure_steam_libraries() {
    set_current_task "Configuring Steam libraries"
    # Only log to file, don't display to user
    log "Configuring Steam libraries..."
    
    # Make directories
    local steam_config_directory="$CHOSEN_LIBRARY/steamapps/compatdata/$APPID/pfx/drive_c/Program Files (x86)/Steam/config"
    log "Creating directory $steam_config_directory"
    
    mkdir -p "$steam_config_directory" || error_exit "Failed to create directory $steam_config_directory"
    
    # Copy or symlink libraryfolders.vdf to config directory
    if [[ "$CHOSEN_LIBRARY" == "$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam" ]]; then
        STEAM_IS_FLATPAK=1
        # For Flatpak Steam, adjust the paths accordingly
        log "Symlinking libraryfolders.vdf to config directory for Flatpak Steam"
        ln -sf "$CHOSEN_LIBRARY/config/libraryfolders.vdf" "$steam_config_directory/libraryfolders.vdf" || 
            log "Failed to symlink libraryfolders.vdf (Flatpak Steam)"
    else
        log "Symlinking libraryfolders.vdf to config directory"
        ln -sf "$CHOSEN_LIBRARY/config/libraryfolders.vdf" "$steam_config_directory/libraryfolders.vdf" || 
            log "Failed to symlink libraryfolders.vdf"
    fi
    
    # Backup existing libraryfolders.vdf if it exists
    local pfx_libraryfolders="$CHOSEN_LIBRARY/steamapps/compatdata/$APPID/pfx/drive_c/Program Files (x86)/Steam/steamapps/libraryfolders.vdf"
    if [[ -f "$pfx_libraryfolders" ]]; then
        mv "$pfx_libraryfolders" "${pfx_libraryfolders}.bak" || log "Failed to backup libraryfolders.vdf"
    fi
}

create_dotnet_cache_dir() {
    set_current_task "Setting up .NET cache directory"
    # Only log to file, don't display to user
    log "Setting up .NET cache directory..."
    
    local user_name=$(whoami)
    local cache_dir="$APPLICATION_DIRECTORY/home/$user_name/.cache/dotnet_bundle_extract"
    
    # Check if the directory already exists
    if [ -d "$cache_dir" ]; then
        log "Directory already exists: $cache_dir, skipping..."
        return 0
    fi
    
    # Create the directory
    mkdir -p "$cache_dir" || error_exit "Failed to create directory: $cache_dir"
    log "Directory successfully created: $cache_dir"
}

cleanup_wine_procs() {
    # Only log to file, don't display to user
    log "Cleaning up any hanging Wine processes..."
    
    # Find and kill processes
    local processes=$(pgrep -f "WabbajackProton.exe|renderer=vulkan|win7|win10|ShowDotFiles|MicrosoftEdgeWebView2RuntimeInstallerX64-WabbajackProton.exe")
    if [[ -n "$processes" ]]; then
        echo "$processes" | xargs -r kill -9
        log "Processes killed successfully"
    else
        log "No matching wine processes found"
    fi
}

# Show detection summary and ask for confirmation
show_detection_summary() {
    echo ""
    echo "───────────────────────────────────────────────────────────────────"
    echo -e "\e[1mDetection Summary:\e[0m" | tee -a "$LOGFILE"
    echo -e "===================" | tee -a "$LOGFILE"
    echo -e "Wabbajack Path: \e[32m\"$APPLICATION_DIRECTORY\"\e[0m" | tee -a "$LOGFILE"
    echo -e "Steam App ID: \e[32m$APPID\e[0m" | tee -a "$LOGFILE"
    echo -e "Compatdata Path: \e[32m$COMPAT_DATA_PATH\e[0m" | tee -a "$LOGFILE"
    echo -e "Steam Library: \e[32m$CHOSEN_LIBRARY\e[0m" | tee -a "$LOGFILE"
    echo -e "Protontricks: \e[32m$WHICH_PROTONTRICKS\e[0m" | tee -a "$LOGFILE"
    
    # Show Steam Deck status if detected
    if [[ $STEAMDECK -eq 1 ]]; then
        echo -e "Running on: \e[32mSteam Deck\e[0m" | tee -a "$LOGFILE"
    fi
    
    # Show SD Card status if detected
    if [[ "$CHOSEN_LIBRARY" == "/run/media"* ]] || [[ "$APPLICATION_DIRECTORY" == "/run/media"* ]]; then
        echo -e "SD Card: \e[32mDetected\e[0m" | tee -a "$LOGFILE"
    fi
    echo "───────────────────────────────────────────────────────────────────"
    
    # Show confirmation with retry loop
    while true; do
        read -rp $'\e[32mDo you want to proceed with the installation? (y/N)\e[0m ' proceed
        
        if [[ $proceed =~ ^[Yy]$ ]]; then
            break
        elif [[ $proceed =~ ^[Nn]$ ]] || [[ -z $proceed ]]; then
            log "Installation cancelled by user"
            display "Installation cancelled." "$YELLOW"
            cleanup_wine_procs
            exit 0
        fi
        
        display "Please enter 'y' for yes or 'n' for no." "$YELLOW"
    done
    
    # Add padding after user confirmation
    echo ""
}

# --- Discovery Phase ---
discovery_phase() {
    # All detection, user input, and variable gathering
    display_banner
    log_section "Initial Setup"
    cleanup_wine_procs
    CURRENT_TASK_NUM=0
    IN_MODIFICATION_PHASE=0
    log_section "Environment Detection"
    detect_steamdeck
    detect_protontricks
    setup_protontricks_alias
    check_protontricks_version
    log_section "Path Detection"
    get_wabbajack_path
    detect_compatdata_path
    detect_link_steam_library
    show_detection_summary
}

# --- Configuration Phase ---
configuration_phase() {
    # All actions that change the system, using only variables set above
    IN_MODIFICATION_PHASE=1
    CURRENT_TASK_NUM=0
    log_section "Environment Configuration"
    set_protontricks_perms
    set_current_task "Applying initial system.reg (phase 1)"
    download_file "https://raw.githubusercontent.com/Omni-guides/Wabbajack-Modlist-Linux/main/files/system.reg.wj.win7" "$COMPAT_DATA_PATH/pfx/system.reg" "Phase 1 system.reg"
    webview_installer
    set_current_task "Applying final system.reg and user.reg"
    download_file "https://raw.githubusercontent.com/Omni-guides/Wabbajack-Modlist-Linux/main/files/system.reg.wj" "$COMPAT_DATA_PATH/pfx/system.reg" "Final system.reg"
    download_file "https://raw.githubusercontent.com/Omni-guides/Wabbajack-Modlist-Linux/main/files/user.reg.wj" "$COMPAT_DATA_PATH/pfx/user.reg" "Final user.reg"
    configure_steam_libraries
    create_dotnet_cache_dir
    log_section "Final Cleanup"
    cleanup_wine_procs
    set_current_task "Complete"
    echo -e "\n"
    echo "───────────────────────────────────────────────────────────────────"
    log_section "Setup Complete"
    display "✓ Installation completed successfully!" "$GREEN"
    echo -e "\n📝 Next Steps:"
    echo "  • Launch Wabbajack through Steam"
    echo "  • When Wabbajack opens, verify you can log in to Nexus from the Settings option"
    echo "  • Begin downloading and installing your modlist"
    echo -e "\n💡 If you encounter any issues:"
    echo "  • Check the log file at: $LOGFILE"
    echo "  • Join the #unofficial-linux-support channel on the Wabbajack Discord"
    echo "  • Ensure you've followed all modlist-specific requirements"
    echo "───────────────────────────────────────────────────────────────────"
    echo -e "\n"
    if [[ $STEAM_IS_FLATPAK -eq 1 ]]; then
        display "Flatpak Steam is in use. You may need to add a permissions override so that Wabbajack can access the directories." "$YELLOW"
        display "For example, if you wanted to install a modlist to /home/user/Games/Skyrim/Modlistname, you would need to run:" "$YELLOW"
        display "flatpak override --user com.valvesoftware.Steam --filesystem=\"/home/user/Games\"" "$YELLOW"
    fi
    echo -e "\n${YELLOW}IMPORTANT: For best compatibility, add the following line to the Launch Options of your Wabbajack Steam entry:${RESET}"
    echo -e "\n${GREEN}PROTON_USE_WINED3D=1 %command%${RESET}\n"
    echo -e "This can help resolve certain graphics issues with Wabbajack running under Proton."
    exit 0
}

# --- Main Execution ---
main() {
    log_section "Script version $SCRIPT_VERSION started at: $(date +'%Y-%m-%d %H:%M:%S')"
    if [[ $VERBOSE -eq 1 ]]; then
        display "Verbose mode enabled" "$YELLOW"
    fi
    # Discovery Phase
    discovery_phase
    # Configuration Phase
    configuration_phase
}

# Run the main function
main 
