View Raw
# CCLS Games CLI Tool v2.0
# Complete Version with Setup, Search, Get functionality, and Logging

# Configuration
$baseUrl = "https://games.ccls.icu"
$cliApiUrl = "$baseUrl/CLI/api/2.0"
$settingsFolder = ".\settings"
$credentialsFile = "$settingsFolder\credentials.dat"
$settingsFile = "$settingsFolder\settings.json" # Using JSON instead of INI for simplicity
$logsFolder = ".\logs" # Logs folder path

# Script-level variables for progress display, logging, and credentials
$script:logFile = $null
$script:sessionStartTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$script:cachedCredentials = $null
$script:oversightEnabled = $false
$script:oversightData = $null
$script:userLoggingEnabled = $false
$script:userLoggingPath = $null
$script:userLoggingUserId = $null
$script:userLoggingSessionFile = $null
$script:dependenciesChecked = $false
$script:dependenciesSatisfied = $false
$script:libraryCache = $null
$script:libJsonPath = $null

# Ensure settings and logs directories exist
if (-not (Test-Path $settingsFolder)) {
    New-Item -Path $settingsFolder -ItemType Directory | Out-Null
}

if (-not (Test-Path $logsFolder)) {
    New-Item -Path $logsFolder -ItemType Directory | Out-Null
}

# Initialize log file for the current session
$script:logFile = Join-Path -Path $logsFolder -ChildPath "ccls_session_$($script:sessionStartTime).log"
"CCLS Games CLI Session started at $($script:sessionStartTime)" | Out-File -FilePath $script:logFile

# Background check to ensure script is named CLI.ps1 for update functionality
function Test-ScriptNaming {
    try {
        # Get the current script file information
        $currentScriptPath = $null
        
        # Try to get the script path using different methods
        if ($PSCommandPath) {
            $currentScriptPath = $PSCommandPath
        } elseif ($MyInvocation.MyCommand.Path) {
            $currentScriptPath = $MyInvocation.MyCommand.Path
        } elseif ($script:MyInvocation.MyCommand.Path) {
            $currentScriptPath = $script:MyInvocation.MyCommand.Path
        }
        
        if ($currentScriptPath) {
            $currentFileName = Split-Path -Path $currentScriptPath -Leaf
            $currentDirectory = Split-Path -Path $currentScriptPath -Parent
            $expectedFileName = "CLI.ps1"
            $expectedFilePath = Join-Path -Path $currentDirectory -ChildPath $expectedFileName
            
            "Script naming check initiated" | Out-File -FilePath $script:logFile -Append
            "Current script path: $currentScriptPath" | Out-File -FilePath $script:logFile -Append
            "Current file name: $currentFileName" | Out-File -FilePath $script:logFile -Append
            "Expected file name: $expectedFileName" | Out-File -FilePath $script:logFile -Append
            
            if ($currentFileName -ne $expectedFileName) {
                "Script name mismatch detected - renaming required" | Out-File -FilePath $script:logFile -Append
                
                # Check if CLI.ps1 already exists in the directory
                if (Test-Path $expectedFilePath) {
                    "Warning: CLI.ps1 already exists in directory" | Out-File -FilePath $script:logFile -Append
                    # Create a backup of the existing CLI.ps1
                    $backupName = "CLI_backup_$(Get-Date -Format 'yyyy-MM-dd_HH-mm-ss').ps1"
                    $backupPath = Join-Path -Path $currentDirectory -ChildPath $backupName
                    try {
                        Copy-Item -Path $expectedFilePath -Destination $backupPath -Force
                        "Created backup of existing CLI.ps1: $backupPath" | Out-File -FilePath $script:logFile -Append
                    } catch {
                        "Failed to create backup of existing CLI.ps1: $($_.Exception.Message)" | Out-File -FilePath $script:logFile -Append
                    }
                }
                
                # Rename the current script to CLI.ps1
                try {
                    Copy-Item -Path $currentScriptPath -Destination $expectedFilePath -Force
                    "Successfully copied current script to CLI.ps1" | Out-File -FilePath $script:logFile -Append
                    
                    # Remove the old file if it has a different name
                    if ($currentScriptPath -ne $expectedFilePath) {
                        Remove-Item -Path $currentScriptPath -Force
                        "Successfully removed old script file: $currentScriptPath" | Out-File -FilePath $script:logFile -Append
                    }
                    
                    "Script renaming completed successfully" | Out-File -FilePath $script:logFile -Append
                } catch {
                    "Failed to rename script file: $($_.Exception.Message)" | Out-File -FilePath $script:logFile -Append
                    "Update functionality may not work properly with current filename" | Out-File -FilePath $script:logFile -Append
                }
            } else {
                "Script name is correct (CLI.ps1) - no action needed" | Out-File -FilePath $script:logFile -Append
            }
        } else {
            "Could not determine current script path - skipping rename check" | Out-File -FilePath $script:logFile -Append
            "Update functionality may be affected if script is not named CLI.ps1" | Out-File -FilePath $script:logFile -Append
        }
    } catch {
        "Error during script naming check: $($_.Exception.Message)" | Out-File -FilePath $script:logFile -Append
    }
}

# Run the script naming check
Test-ScriptNaming

function Write-CCLSHost {
    param (
        [Parameter(Position = 0)]
        [string]$Message = "",
        
        [Parameter()]
        [System.ConsoleColor]$ForegroundColor = [System.ConsoleColor]::White,
        
        [Parameter()]
        [System.ConsoleColor]$BackgroundColor = [System.ConsoleColor]::Black,
        
        [Parameter()]
        [switch]$NoNewline,
        
        [Parameter()]
        [switch]$Log,
        
        [Parameter()]
        [switch]$NoConsole
    )
    
    # Check if the message is marked for removal
    if ($Message.StartsWith('#')) {
        # Don't show in console, but log it if needed
        if ($Log) {
            $cleanMessage = $Message.Substring(1).Trim()
            if (-not [string]::IsNullOrWhiteSpace($cleanMessage)) {
                $cleanMessage | Out-File -FilePath $script:logFile -Append
                
                # Send to server logging if enabled
                if ($script:userLoggingEnabled) {
                    Send-LogToServer -LogEntry $cleanMessage
                }
            }
        }
        return
    }
    
    if ($Message.StartsWith('/')) {
        # Skip completely - don't log or display
        return
    }
    
    # Handle empty lines
    if ([string]::IsNullOrWhiteSpace($Message)) {
        # Display in console if not suppressed
        if (-not $NoConsole) {
            Write-Host "" -NoNewline:$NoNewline
        }
        # But don't log empty lines
        return
    }
    
    # Display in console if not suppressed
    if (-not $NoConsole) {
        Write-Host $Message -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor -NoNewline:$NoNewline
    }
    
    # Log if requested
    if ($Log) {
        $plainMessage = $Message
        $plainMessage | Out-File -FilePath $script:logFile -Append
        
        # Send to server logging if enabled
        if ($script:userLoggingEnabled) {
            Send-LogToServer -LogEntry $plainMessage
        }
    }
}

function Initialize-Settings {
    # Get version information using existing function (but don't show alerts here)
    try {
        $currentVersion = "2.1.5"  # Static version, no need to call Test-VersionUpdate here
    } catch {
        # If version check fails, use a default version
        $currentVersion = "2.1.5"
        Write-CCLSHost "#Error getting version info, using default: $($_.Exception.Message)" -Log -NoConsole
    }
    
    if (-not (Test-Path $settingsFile)) {
        # Create default settings file
        $defaultSettings = @{
            RememberLogin = $false
            DownloadPath = ".\downloads"
            TempDownloadPath = ".\tmp"
            HasCompletedSetup = $false
            Version = $currentVersion
            DevMode = $false  # Add DevMode parameter with default false
        }
        
        try {
            $defaultSettings | ConvertTo-Json | Set-Content -Path $settingsFile
            Write-CCLSHost "#Created new settings file with DevMode parameter" -Log -NoConsole
        } catch {
            Write-CCLSHost "#Error creating settings file: $($_.Exception.Message)" -Log -NoConsole
        }
        
        # Return settings without version change flag
        return $defaultSettings
    }

    Initialize-StartupMessageDirectories
    
    # Load settings
    try {
        $settingsContent = Get-Content -Path $settingsFile -Raw
        $settings = $settingsContent | ConvertFrom-Json
    } catch {
        Write-CCLSHost "#Error loading settings file: $($_.Exception.Message)" -Log -NoConsole
        # Return default settings if loading fails
        return @{
            RememberLogin = $false
            DownloadPath = ".\downloads"
            TempDownloadPath = ".\tmp"
            HasCompletedSetup = $false
            Version = $currentVersion
            DevMode = $false
        }
    }
    
    # Check if Version property exists, add it if not
    if (-not (Get-Member -InputObject $settings -Name "Version" -MemberType Properties)) {
        $settings | Add-Member -MemberType NoteProperty -Name "Version" -Value $currentVersion
        try {
            $settings | ConvertTo-Json | Set-Content -Path $settingsFile
            Write-CCLSHost "#Added Version parameter to settings" -Log -NoConsole
        } catch {
            Write-CCLSHost "#Error updating settings with Version: $($_.Exception.Message)" -Log -NoConsole
        }
    }
    
    # Check if DevMode property exists, add it if not
    if (-not (Get-Member -InputObject $settings -Name "DevMode" -MemberType Properties)) {
        $settings | Add-Member -MemberType NoteProperty -Name "DevMode" -Value $false
        try {
            $settings | ConvertTo-Json | Set-Content -Path $settingsFile
            Write-CCLSHost "#Added DevMode parameter to existing settings" -Log -NoConsole
        } catch {
            Write-CCLSHost "#Error updating settings with DevMode: $($_.Exception.Message)" -Log -NoConsole
        }
    }
    
    # Check if version has changed and update if needed
    if ($settings.Version -ne $currentVersion) {
        Write-CCLSHost "#Detected version change from $($settings.Version) to $currentVersion" -Log -NoConsole
        # Store the old version
        $oldVersion = $settings.Version
        
        # Update to new version
        $settings.Version = $currentVersion
        try {
            $settings | ConvertTo-Json | Set-Content -Path $settingsFile
        } catch {
            Write-CCLSHost "#Error updating version in settings: $($_.Exception.Message)" -Log -NoConsole
        }
        
        # Download latest Python downloader when CLI version changes
        try {
            $scriptLocation = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
            $pythonScript = Join-Path -Path $scriptLocation -ChildPath "ccls_downloader.py"
            $downloadUrl = "https://games.ccls.icu/CLI/api/main/ccls_downloader/1.2.0/ccls_downloader.py"
            
            Write-CCLSHost "#Downloading updated Python downloader..." -Log -NoConsole
            $webClient = New-Object System.Net.WebClient
            $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
            $webClient.DownloadFile($downloadUrl, $pythonScript)
            Write-CCLSHost "#Python downloader updated successfully" -Log -NoConsole
        } catch {
            Write-CCLSHost "#Error downloading Python downloader: $($_.Exception.Message)" -Log -NoConsole
        }
        
        # Keep track that version has changed for later notification
        $script:versionChanged = $true
        $script:previousVersion = $oldVersion
    }
    
    return $settings
}

function Test-SystemRequirementsSilent {
    $results = @{
        PythonInstalled = $false
        PythonVersion = $null
        RequestsInstalled = $false
        RequestsVersion = $null
        SevenZipInstalled = $false
        SevenZipVersion = $null
        MissingDependencies = @()
    }
    
    # Check for Python
    try {
        $pythonResult = python --version 2>&1
        if ($pythonResult -match "Python (\d+\.\d+\.\d+)") {
            $results.PythonInstalled = $true
            $results.PythonVersion = $matches[1]
        }
    } catch {
        # Python not installed
    }
    
    # Check for Python requests library (only if Python is installed)
    if ($results.PythonInstalled) {
        try {
            $requestsCheck = python -c "import requests; print('Installed (v{0})'.format(requests.__version__))" 2>&1
            if ($requestsCheck -match "Installed \(v([\d\.]+)\)") {
                $results.RequestsInstalled = $true
                $results.RequestsVersion = $matches[1]
            }
        } catch {
            # Requests not installed
        }
    }
    
    # Check for 7-Zip
    $systemPaths = @(
        "C:\Program Files\7-Zip\7z.exe",
        "${env:ProgramFiles(x86)}\7-Zip\7z.exe"
    )
    
    $scriptLocation = if ($PSScriptRoot) {
        $PSScriptRoot
    } else {
        (Get-Location).Path
    }
    $localPath = Join-Path -Path $scriptLocation -ChildPath "7zip\7z.exe"
    
    $allPaths = $systemPaths + $localPath
    
    foreach ($path in $allPaths) {
        if (Test-Path -Path $path) {
            $results.SevenZipInstalled = $true
            try {
                $versionInfo = Get-Item $path | Select-Object -ExpandProperty VersionInfo
                $results.SevenZipVersion = $versionInfo.ProductVersion
            } catch {
                $results.SevenZipVersion = "Unknown"
            }
            break
        }
    }
    
    # Determine missing dependencies
    if (-not $results.PythonInstalled) {
        $results.MissingDependencies += "install python"
    }
    
    if (-not $results.RequestsInstalled) {
        if ($results.PythonInstalled) {
            $results.MissingDependencies += "install requests"
        }
        # Note: if Python is not installed, we don't add requests to missing dependencies
        # because the user will get an error when trying to install requests without Python
    }
    
    if (-not $results.SevenZipInstalled) {
        $results.MissingDependencies += "install 7zip"
    }
    
    return $results
}

# Function to check dependencies and block CLI usage if missing
function Test-RequiredDependencies {
    if ($script:dependenciesChecked) {
        return $script:dependenciesSatisfied
    }
    
    $script:dependenciesChecked = $true
    $dependencyResults = Test-SystemRequirementsSilent
    
    if ($dependencyResults.MissingDependencies.Count -eq 0) {
        $script:dependenciesSatisfied = $true
        Write-CCLSHost "#All required dependencies are satisfied" -Log -NoConsole
        return $true
    } else {
        $script:dependenciesSatisfied = $false
        Write-CCLSHost "CLI Tool is missing critical dependencies, run 'check' for more info" -ForegroundColor Red -Log
        Write-CCLSHost "The script will remain in a broken state until dependency requirements are met" -ForegroundColor Red -Log
        
        return $false
    }
}

# Function to enforce dependency requirements for most commands
function Assert-DependenciesRequired {
    param (
        [string]$CommandName = "this command"
    )
    
    if (-not (Test-RequiredDependencies)) {
        Write-CCLSHost "'$CommandName' is missing critical dependencies, run 'check' for more info" -ForegroundColor Red -Log
        Write-CCLSHost "The script will remain in a broken state until dependency requirements are met" -ForegroundColor Red -Log
        return $false
    }
    return $true
}

function Initialize-LibraryCache {
    # Set the lib.json path
    $script:libJsonPath = Join-Path -Path $settingsFolder -ChildPath "lib.json"
    
    Write-CCLSHost "#Initializing library cache system..." -Log -NoConsole
    
    # Check if lib.json exists
    if (-not (Test-Path $script:libJsonPath)) {
        Write-CCLSHost "#lib.json not found, creating initial cache..." -Log -NoConsole
        Update-LibraryCache -Force
    } else {
        # Load existing cache and validate it
        $script:libraryCache = Get-LibraryCache
        
        if ($script:libraryCache -and (Test-LibraryCacheValid)) {
            Write-CCLSHost "#Library cache loaded and validated successfully" -Log -NoConsole
        } else {
            Write-CCLSHost "#Library cache invalid or corrupted, rebuilding..." -Log -NoConsole
            Update-LibraryCache -Force
        }
    }
}

# Load library cache from file
function Get-LibraryCache {
    try {
        if (Test-Path $script:libJsonPath) {
            $cacheContent = Get-Content -Path $script:libJsonPath -Raw | ConvertFrom-Json
            return $cacheContent
        }
    } catch {
        Write-CCLSHost "#Error loading library cache: $($_.Exception.Message)" -Log -NoConsole
    }
    return $null
}

# Validate library cache against current file system
function Test-LibraryCacheValid {
    if (-not $script:libraryCache) {
        return $false
    }
    
    $settings = Initialize-Settings
    $downloadPath = $settings.DownloadPath
    
    # Check if download path exists
    if (-not (Test-Path $downloadPath)) {
        Write-CCLSHost "#Download path doesn't exist, cache invalid" -Log -NoConsole
        return $false
    }
    
    # Get current folders in download directory
    $currentFolders = Get-ChildItem -Path $downloadPath -Directory -ErrorAction SilentlyContinue
    
    # Check if all cached games still exist
    foreach ($cachedGame in $script:libraryCache.games) {
        $gamePath = Join-Path -Path $downloadPath -ChildPath $cachedGame.folderName
        
        if (-not (Test-Path $gamePath)) {
            Write-CCLSHost "#Cached game '$($cachedGame.folderName)' no longer exists" -Log -NoConsole
            return $false
        }
        
        # Check if JSON metadata files have been modified
        if ($cachedGame.hasMetadata -and $cachedGame.gameId) {
            $jsonPath = Join-Path -Path $gamePath -ChildPath "$($cachedGame.gameId).json"
            
            if (Test-Path $jsonPath) {
                $currentModified = (Get-Item $jsonPath).LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
                
                if ($cachedGame.jsonLastModified -ne $currentModified) {
                    Write-CCLSHost "#JSON metadata for '$($cachedGame.folderName)' has been modified" -Log -NoConsole
                    return $false
                }
            }
        }
    }
    
    # Check if there are new folders not in cache
    $cachedFolderNames = $script:libraryCache.games | ForEach-Object { $_.folderName }
    
    foreach ($folder in $currentFolders) {
        if ($folder.Name -notin $cachedFolderNames) {
            Write-CCLSHost "#New folder '$($folder.Name)' found, not in cache" -Log -NoConsole
            return $false
        }
    }
    
    Write-CCLSHost "#Library cache validation successful" -Log -NoConsole
    return $true
}

# Update library cache
function Update-LibraryCache {
    param (
        [switch]$Force
    )
    
    $settings = Initialize-Settings
    $downloadPath = $settings.DownloadPath
    
    Write-CCLSHost "#Updating library cache..." -Log -NoConsole
    
    # Initialize cache structure
    $cacheData = @{
        lastUpdated = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
        totalGames = 0
        totalSize = 0
        totalSizeFormatted = "0 B"
        games = @()
    }
    
    # Check if download path exists
    if (-not (Test-Path $downloadPath)) {
        Write-CCLSHost "#Download path doesn't exist, creating empty cache" -Log -NoConsole
        $script:libraryCache = $cacheData
        Save-LibraryCache
        return
    }
    
    # Get all folders in download directory
    $gameFolders = Get-ChildItem -Path $downloadPath -Directory -ErrorAction SilentlyContinue
    $totalSize = 0
    
    Write-CCLSHost "#Scanning $($gameFolders.Count) game folders..." -Log -NoConsole
    
    foreach ($folder in $gameFolders) {
        Write-CCLSHost "#Processing folder: $($folder.Name)" -Log -NoConsole
        
        $gameEntry = @{
            folderName = $folder.Name
            gameName = $folder.Name  # Default to folder name
            gameId = "Unknown"
            localVersion = "Unknown"
            localSize = 0
            localSizeFormatted = "0 B"
            localPath = $folder.FullName
            hasMetadata = $false
            isOutdated = $false
            onlineVersion = "Unknown"
            jsonLastModified = $null
        }
        
        # Calculate folder size
        try {
            $folderSize = Get-FolderSize -Path $folder.FullName
            $gameEntry.localSize = $folderSize
            $gameEntry.localSizeFormatted = Format-Size -Size $folderSize
            $totalSize += $folderSize
        } catch {
            Write-CCLSHost "#Error calculating size for $($folder.Name): $($_.Exception.Message)" -Log -NoConsole
            $gameEntry.localSizeFormatted = "Unknown"
        }
        
        # Look for JSON metadata files
        $jsonFiles = Get-ChildItem -Path $folder.FullName -Filter "*.json" -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "^c[gb]\d{4}\.json$" }
        
        if ($jsonFiles.Count -gt 0) {
            $jsonFile = $jsonFiles[0]
            $gameEntry.gameId = [System.IO.Path]::GetFileNameWithoutExtension($jsonFile.Name)
            $gameEntry.hasMetadata = $true
            $gameEntry.jsonLastModified = $jsonFile.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
            
            # Read game info from JSON
            try {
                $localGameInfo = Get-Content -Path $jsonFile.FullName -Raw | ConvertFrom-Json
                
                if ($localGameInfo.name -and -not [string]::IsNullOrWhiteSpace($localGameInfo.name)) {
                    $gameEntry.gameName = $localGameInfo.name
                }
                
                if ($localGameInfo.version -and -not [string]::IsNullOrWhiteSpace($localGameInfo.version)) {
                    $gameEntry.localVersion = $localGameInfo.version
                }
            } catch {
                Write-CCLSHost "#Error reading JSON metadata for $($gameEntry.gameId): $($_.Exception.Message)" -Log -NoConsole
            }
        }
        
        # Add to cache
        $cacheData.games += $gameEntry
    }
    
    # Update totals
    $cacheData.totalGames = $cacheData.games.Count
    $cacheData.totalSize = $totalSize
    $cacheData.totalSizeFormatted = Format-Size -Size $totalSize
    
    # Save cache
    $script:libraryCache = $cacheData
    Save-LibraryCache
    
    Write-CCLSHost "#Library cache updated successfully. Total: $($cacheData.totalGames) games, $($cacheData.totalSizeFormatted)" -Log -NoConsole
}

# Save library cache to file
function Save-LibraryCache {
    try {
        $jsonContent = $script:libraryCache | ConvertTo-Json -Depth 10
        Set-Content -Path $script:libJsonPath -Value $jsonContent -Encoding UTF8 -Force
        Write-CCLSHost "#Library cache saved to: $script:libJsonPath" -Log -NoConsole
    } catch {
        Write-CCLSHost "#Error saving library cache: $($_.Exception.Message)" -Log -NoConsole
    }
}

# Get game from cache by various identifiers
function Get-GameFromCache {
    param (
        [string]$Identifier,
        [string]$SearchType = "folderName"
    )
    
    if (-not $script:libraryCache -or -not $script:libraryCache.games) {
        return $null
    }
    
    switch ($SearchType.ToLower()) {
        "id" {
            return $script:libraryCache.games | Where-Object { $_.gameId -eq $Identifier }
        }
        "gamename" {
            # Case-insensitive name search
            return $script:libraryCache.games | Where-Object { $_.gameName.ToLower() -eq $Identifier.ToLower() }
        }
        "foldername" {
            # Case-insensitive folder name search
            return $script:libraryCache.games | Where-Object { $_.folderName.ToLower() -eq $Identifier.ToLower() }
        }
        default {
            return $script:libraryCache.games | Where-Object { $_.folderName.ToLower() -eq $Identifier.ToLower() }
        }
    }
}

# Function to handle cache errors gracefully
function Handle-CacheError {
    param (
        [string]$Operation,
        [System.Exception]$Exception
    )
    
    Write-CCLSHost "#Cache error during $Operation`: $($Exception.Message)" -Log -NoConsole
    
    # If cache is corrupted, try to recreate it
    if ($Operation -eq "load" -or $Operation -eq "validate") {
        Write-CCLSHost "#Attempting to recreate corrupted cache..." -Log -NoConsole
        try {
            Update-LibraryCache -Force
        } catch {
            Write-CCLSHost "#Failed to recreate cache: $($_.Exception.Message)" -Log -NoConsole
        }
    }
}

# 6. Cache validation improvements - Add additional validation checks:

function Test-LibraryCacheIntegrity {
    if (-not $script:libraryCache) {
        return $false
    }
    
    # Check if cache structure is valid
    $requiredProperties = @('lastUpdated', 'totalGames', 'totalSize', 'totalSizeFormatted', 'games')
    
    foreach ($prop in $requiredProperties) {
        if (-not (Get-Member -InputObject $script:libraryCache -Name $prop -MemberType Properties)) {
            Write-CCLSHost "#Cache missing required property: $prop" -Log -NoConsole
            return $false
        }
    }
    
    # Check if games array is valid
    if ($script:libraryCache.games -isnot [array] -and $script:libraryCache.totalGames -gt 0) {
        Write-CCLSHost "#Cache games property is not an array but totalGames > 0" -Log -NoConsole
        return $false
    }
    
    return $true
}

# 7. Performance optimization - Add size calculation caching:

function Get-CachedFolderSize {
    param (
        [string]$Path,
        [string]$FolderName
    )
    
    # First try to get from cache
    if ($script:libraryCache) {
        $cachedGame = Get-GameFromCache -Identifier $FolderName -SearchType "foldername"
        if ($cachedGame) {
            return $cachedGame.localSize
        }
    }
    
    # If not in cache, calculate and return
    return Get-FolderSize -Path $Path
}

# 8. Debug and maintenance functions:

function Show-LibraryCacheStatus {
    Write-CCLSHost "`nLibrary Cache Status" -ForegroundColor Green -Log
    Write-CCLSHost "===================" -ForegroundColor Green -Log
    
    if (-not $script:libraryCache) {
        Write-CCLSHost "Cache Status: Not loaded" -ForegroundColor Red -Log
        return
    }
    
    Write-CCLSHost "Cache Status: Loaded" -ForegroundColor Green -Log
    Write-CCLSHost "Cache File: $script:libJsonPath" -Log
    Write-CCLSHost "Last Updated: $($script:libraryCache.lastUpdated)" -Log
    Write-CCLSHost "Total Games: $($script:libraryCache.totalGames)" -Log
    Write-CCLSHost "Total Size: $($script:libraryCache.totalSizeFormatted)" -Log
    
    if (Test-Path $script:libJsonPath) {
        $cacheFileInfo = Get-Item $script:libJsonPath
        $cacheFileSize = Format-Size -Size $cacheFileInfo.Length
        Write-CCLSHost "Cache File Size: $cacheFileSize" -Log
        Write-CCLSHost "Cache File Modified: $($cacheFileInfo.LastWriteTime)" -Log
    }
    
    # Validate cache
    $isValid = Test-LibraryCacheValid
    $isIntegrity = Test-LibraryCacheIntegrity
    
    Write-CCLSHost "Cache Valid: $(if ($isValid) { 'Yes' } else { 'No' })" -ForegroundColor $(if ($isValid) { 'Green' } else { 'Red' }) -Log
    Write-CCLSHost "Cache Integrity: $(if ($isIntegrity) { 'Good' } else { 'Corrupted' })" -ForegroundColor $(if ($isIntegrity) { 'Green' } else { 'Red' }) -Log
}


function Toggle-DevMode {
    $settings = Initialize-Settings
    
    if ($settings.DevMode) {
        # Currently in DevMode, turn it off
        $settings.DevMode = $false
        Save-Settings -settings $settings
        
        # Clear any stored or cached credentials
        if (Test-Path $credentialsFile) {
            Remove-Item -Path $credentialsFile -Force
            Write-CCLSHost "#Removed stored credentials" -Log -NoConsole
        }
        
        # Clear cached credentials
        $script:cachedCredentials = $null
        
        # Clear console and show exit message
        Clear-Host
        Write-CCLSHost "Exited devmode" -ForegroundColor Green -Log
        
        # Show the normal login interface
        Write-CCLSHost "Hello and welcome to the CCLS Games CLI Tool" -ForegroundColor Green -Log
        Write-CCLSHost "Before proceeding to using this software you will need to sign in." -Log
        Write-CCLSHost "If you do not have an account already please go to $baseUrl/login.php?signup to register a new account." -Log
        
        # Try auto-login if remember login is enabled
        $loginResult = @{ Success = $false; DevMode = $false }
        if ($settings.RememberLogin) {
            $loginResult = Start-AutoLogin
        }
        
        # If auto-login failed or is disabled, do manual login
        if (-not $loginResult.Success) {
            $loginResult = Start-ManualLogin
        }
        
        # If login succeeded, show main interface
        if ($loginResult.Success) {
            # Normal login - show welcome message
            Show-StartupMessage
            Write-CCLSHost "Welcome to CCLS Games CLI Tool, $($loginResult.Username)!" -ForegroundColor Green -Log
            
            # Check dependencies after successful login
            Test-RequiredDependencies | Out-Null
            
            # Check if version has changed and show notification
            if ($script:versionChanged) {
                $versionInfo = Test-VersionUpdate
                $currentVersion = $versionInfo.CurrentVersion
                Write-CCLSHost "Welcome to $currentVersion! Type 'changelog latest' to view the changes made." -ForegroundColor Green -Log
            }
            
            # Show appropriate message based on setup status
            if ($settings.HasCompletedSetup) {
                Write-CCLSHost "Type 'help' for a list of available commands." -ForegroundColor Cyan -Log
            }
            else {
                Write-CCLSHost "ALERT, type command 'setup' to set critical values before downloading." -ForegroundColor Red -Log
            }
            
            Start-CommandInterface -username $loginResult.Username
        }
        else {
            Write-CCLSHost "Login failed. Press any key to exit..." -ForegroundColor Red -Log
            $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
            Exit
        }
        
    } else {
        # Currently in normal mode, turn on DevMode
        $settings.DevMode = $true
        Save-Settings -settings $settings
        
        # Clear any stored or cached credentials
        if (Test-Path $credentialsFile) {
            Remove-Item -Path $credentialsFile -Force
            Write-CCLSHost "#Removed stored credentials" -Log -NoConsole
        }
        
        # Clear cached credentials
        $script:cachedCredentials = $null
        
        Write-CCLSHost "You are now in developer mode. 'get', 'search' and any other command that calls external API's will not work." -ForegroundColor Red -Log
    }
}

function Read-UsernameWithDevModeDetection {
    $devModeActivated = $false
    
    Write-CCLSHost "Username: " -ForegroundColor Cyan -NoNewline -Log
    
    # Use a simpler approach - check for Ctrl+Q using a different method
    $username = ""
    $ctrlQPressed = $false
    
    try {
        # Try to use ReadKey if available, otherwise fall back to Read-Host
        if ($Host.UI.RawUI -and $Host.UI.RawUI.KeyAvailable -ne $null) {
            # Custom input handling to detect Ctrl+Q
            while ($true) {
                if ([Console]::KeyAvailable) {
                    $keyInfo = [Console]::ReadKey($true)
                    
                    # Check for Ctrl+Q
                    if (($keyInfo.Modifiers -band [ConsoleModifiers]::Control) -and 
                        ($keyInfo.Key -eq [ConsoleKey]::Q)) {
                        $ctrlQPressed = $true
                        # Don't show anything when Ctrl+Q is pressed
                        continue
                    }
                    
                    # Handle Enter key
                    if ($keyInfo.Key -eq [ConsoleKey]::Enter) {
                        Write-Host ""  # New line
                        break
                    }
                    
                    # Handle Backspace
                    if ($keyInfo.Key -eq [ConsoleKey]::Backspace) {
                        if ($username.Length -gt 0) {
                            $username = $username.Substring(0, $username.Length - 1)
                            Write-Host "`b `b" -NoNewline
                        }
                        continue
                    }
                    
                    # Handle regular characters
                    if ($keyInfo.KeyChar -match '[a-zA-Z0-9\s]' -and $keyInfo.KeyChar -ne "`0") {
                        $username += $keyInfo.KeyChar
                        Write-Host $keyInfo.KeyChar -NoNewline
                    }
                } else {
                    Start-Sleep -Milliseconds 50
                }
            }
            
            # Check if Ctrl+Q was pressed and username is "devmode"
            if ($ctrlQPressed -and $username.ToLower().Trim() -eq "devmode") {
                $devModeActivated = $true
            }
        } else {
            # Fallback to simple Read-Host for environments that don't support advanced key handling
            Write-CCLSHost "#Using fallback input method" -Log -NoConsole
            $tempInput = Read-Host
            
            # Check for special devmode activation pattern
            # Allow users to type "ctrl+q devmode" as an alternative
            if ($tempInput.ToLower().Trim() -eq "ctrl+q devmode" -or $tempInput.ToLower().Trim() -eq "devmode ctrl+q") {
                $devModeActivated = $true
                $username = "devmode"
            } else {
                $username = $tempInput
            }
        }
    } catch {
        Write-CCLSHost "#Error in key detection, falling back to Read-Host: $($_.Exception.Message)" -Log -NoConsole
        # Ultimate fallback
        $tempInput = Read-Host
        if ($tempInput.ToLower().Trim() -eq "ctrl+q devmode" -or $tempInput.ToLower().Trim() -eq "devmode ctrl+q") {
            $devModeActivated = $true
            $username = "devmode"
        } else {
            $username = $tempInput
        }
    }
    
    Write-CCLSHost "$username" -NoConsole -Log
    
    return @{
        Username = $username
        DevModeActivated = $devModeActivated
    }
}

# Save settings
function Save-Settings($settings) {
    $settings | ConvertTo-Json | Set-Content -Path $settingsFile
}

# Store credentials securely
function Save-Credentials($username, $password) {
    $credentials = @{
        Username = $username
        Password = $password
    } | ConvertTo-Json
    
    # Simple encryption (replace with more secure method if needed)
    $securePassword = ConvertTo-SecureString -String $credentials -AsPlainText -Force
    $encryptedText = ConvertFrom-SecureString -SecureString $securePassword
    
    # Save to file
    $encryptedText | Set-Content -Path $credentialsFile
}

# Load stored credentials
function Get-StoredCredentials {
    if (Test-Path $credentialsFile) {
        try {
            $encryptedText = Get-Content -Path $credentialsFile
            $securePassword = ConvertTo-SecureString -String $encryptedText
            $credentials = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
                [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword)
            )
            return $credentials | ConvertFrom-Json
        }
        catch {
            Write-CCLSHost "Error reading credentials: $($_.Exception.Message)" -ForegroundColor Red -Log
            return $null
        }
    }
    return $null
}

# Run setup process
function Start-Setup {
    Write-CCLSHost "`n`nCCLS Games CLI Setup" -ForegroundColor Green -Log
    Write-CCLSHost "=====================" -ForegroundColor Green -Log
    Write-CCLSHost "Please configure the following settings:`n" -ForegroundColor Cyan -Log
    
    $settings = Initialize-Settings
    
    # Get game installation directory
    $validPath = $false
    while (-not $validPath) {
        Write-CCLSHost "Set your games default installation directory: " -ForegroundColor Yellow -NoNewline -Log
        $downloadPath = Read-Host
        Write-CCLSHost "$downloadPath" -NoConsole -Log
        
        if ([string]::IsNullOrWhiteSpace($downloadPath)) {
            Write-CCLSHost "Please enter a valid directory path." -ForegroundColor Red -Log
        }
        else {
            # Create directory if it doesn't exist
            if (-not (Test-Path $downloadPath)) {
                try {
                    New-Item -ItemType Directory -Path $downloadPath -Force | Out-Null
                    $validPath = $true
                }
                catch {
                    Write-CCLSHost "Error creating directory: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
            }
            else {
                $validPath = $true
            }
        }
    }
    
    # Get temporary download directory
    $validTempPath = $false
    while (-not $validTempPath) {
        Write-CCLSHost "Set the temporary directory of downloading files before they have finished downloading: " -ForegroundColor Yellow -NoNewline -Log
        $tempDownloadPath = Read-Host
        Write-CCLSHost "$tempDownloadPath" -NoConsole -Log
        
        if ([string]::IsNullOrWhiteSpace($tempDownloadPath)) {
            Write-CCLSHost "Please enter a valid directory path." -ForegroundColor Red -Log
        }
        else {
            # Create directory if it doesn't exist
            if (-not (Test-Path $tempDownloadPath)) {
                try {
                    New-Item -ItemType Directory -Path $tempDownloadPath -Force | Out-Null
                    $validTempPath = $true
                }
                catch {
                    Write-CCLSHost "Error creating directory: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
            }
            else {
                $validTempPath = $true
            }
        }
    }
    
    # Update settings
    $settings.DownloadPath = $downloadPath
    $settings.TempDownloadPath = $tempDownloadPath
    $settings.HasCompletedSetup = $true
    Save-Settings -settings $settings
    
    Write-CCLSHost "`nGreat, you have now completed the setup. Type 'help' for a list of commands to get you started." -ForegroundColor Green -Log
}

# Validate username against server
function Test-Username($username) {
    $params = @{
        Uri = "$cliApiUrl/username_check.php"
        Method = "POST"
        Headers = @{
            "User-Agent" = "CCLS-CLI/2.0"
        }
        Body = @{
            username = $username
        }
    }
    
    try {
        $response = Invoke-RestMethod @params
        return $response.exists
    }
    catch {
        Write-CCLSHost "Error connecting to the server: $($_.Exception.Message)" -ForegroundColor Red -Log
        return $false
    }
}

# Validate password against server
function Test-Password($username, $password) {
    $params = @{
        Uri = "$cliApiUrl/password_check.php"
        Method = "POST"
        Headers = @{
            "User-Agent" = "CCLS-CLI/2.0"
        }
        Body = @{
            username = $username
            password = $password
        }
    }
    
    try {
        $response = Invoke-RestMethod @params
        return $response.success
    }
    catch {
        Write-CCLSHost "Error connecting to the server: $($_.Exception.Message)" -ForegroundColor Red -Log
        return $false
    }
}

function Start-AutoLogin {
    $credentials = Get-StoredCredentials
    if ($credentials -ne $null) {
        Write-CCLSHost "#Attempting to login with stored credentials..." -Log
        
        if (Test-Password -username $credentials.Username -password $credentials.Password) {
            Write-CCLSHost "#Auto-login successful!" -Log
            
            # Cache the credentials for the session
            $script:cachedCredentials = @{
                Username = $credentials.Username
                Password = $credentials.Password
            }
            
            # Initialize oversight system after successful auto-login (THIS WAS MISSING!)
            $versionInfo = Test-VersionUpdate
            $currentVersion = $versionInfo.CurrentVersion
            $script:oversightData = Get-OversightData -Username $credentials.Username -CurrentVersion $currentVersion
            if ($script:oversightData) {
                $script:oversightEnabled = $true
                if ($script:oversightData.user_logging) {
                    $script:userLoggingEnabled = $true
                    Initialize-UserLogging -Username $credentials.Username
                }
            }

            Test-RequiredDependencies | Out-Null
            
            return @{
                Success = $true
                Username = $credentials.Username
            }
        }
        else {
            Write-CCLSHost "Stored credentials are no longer valid." -ForegroundColor Yellow -Log
            # Remove invalid credentials
            if (Test-Path $credentialsFile) {
                Remove-Item -Path $credentialsFile -Force
            }
        }
    }
    
    return @{
        Success = $false
    }
}

function Start-ManualLogin {
    $maxAttempts = 3
    $attempts = 0
    
    while ($attempts -lt $maxAttempts) {
        # Use the new function to detect Ctrl+Q + devmode
        $usernameResult = Read-UsernameWithDevModeDetection
        $username = $usernameResult.Username
        $devModeActivated = $usernameResult.DevModeActivated
        
        # Check if DevMode was activated and username is "devmode"
        if ($devModeActivated -and $username.ToLower() -eq "devmode") {
            Write-CCLSHost "#DevMode activation detected via Ctrl+Q + devmode" -Log -NoConsole
            
            # Enable DevMode
            $settings = Initialize-Settings
            $settings.DevMode = $true
            Save-Settings -settings $settings
            
            # Clear any stored or cached credentials
            if (Test-Path $credentialsFile) {
                Remove-Item -Path $credentialsFile -Force
                Write-CCLSHost "#Removed stored credentials for DevMode" -Log -NoConsole
            }
            
            # Clear cached credentials
            $script:cachedCredentials = $null
            
            Write-CCLSHost "You are in developer mode. 'get', 'search' and any other command that calls external API's will not work." -ForegroundColor Red -Log
            
            return @{
                Success = $true
                Username = "Developer"
                DevMode = $true
            }
        }
        
        # Check if username exists (normal login flow)
        Write-CCLSHost "#Checking username..." -Log
        if (Test-Username -username $username) {
            Write-CCLSHost "#Username found!" -Log
            
            Write-CCLSHost "Password: " -ForegroundColor Cyan -NoNewline -Log
            $password = Read-Host -AsSecureString
            $passwordPlain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
                [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
            )
            Write-CCLSHost "********" -NoConsole -Log
            
            Write-CCLSHost "#Validating password..." -Log
            if (Test-Password -username $username -password $passwordPlain) {
                Write-CCLSHost "#Login successful!" -Log
                
                # Cache the credentials for the session
                $script:cachedCredentials = @{
                    Username = $username
                    Password = $passwordPlain
                }
                
                # Initialize oversight system after successful login
                $versionInfo = Test-VersionUpdate
                $currentVersion = $versionInfo.CurrentVersion
                $script:oversightData = Get-OversightData -Username $username -CurrentVersion $currentVersion
                if ($script:oversightData) {
                    $script:oversightEnabled = $true
                    if ($script:oversightData.user_logging) {
                        $script:userLoggingEnabled = $true
                        Initialize-UserLogging -Username $username
                    }
                }
                
                # Ask if user wants to save credentials - no newline before this
                Write-CCLSHost "Do you want to remember your login info for next time? (Y/N)" -ForegroundColor Yellow -Log
                $rememberLogin = Read-Host
                Write-CCLSHost "$rememberLogin" -NoConsole -Log
                
                if ($rememberLogin.ToLower() -eq "y") {
                    Save-Credentials -username $username -password $passwordPlain
                    $settings = Initialize-Settings
                    $settings.RememberLogin = $true
                    Save-Settings -settings $settings
                    Write-CCLSHost "#Login information saved." -Log
                }
                
                return @{
                    Success = $true
                    Username = $username
                    DevMode = $false
                }
            }
            else {
                Write-CCLSHost "Incorrect password, please try again." -ForegroundColor Red -Log
                $attempts++
            }
        }
        else {
            Write-CCLSHost "Username not found, please try again." -ForegroundColor Red -Log
            $attempts++
        }
    }
    
    Write-CCLSHost "Too many failed login attempts. Please try again later." -ForegroundColor Red -Log
    return @{
        Success = $false
        DevMode = $false
    }
}

# Startup Message System Functions
# Add these functions to your CLI.ps1 script

# Initialize startup message directories
function Initialize-StartupMessageDirectories {
    $startMessageFolder = Join-Path -Path $settingsFolder -ChildPath "start-message"
    $defaultMessageFolder = Join-Path -Path $startMessageFolder -ChildPath "default"
    
    if (-not (Test-Path $startMessageFolder)) {
        New-Item -Path $startMessageFolder -ItemType Directory -Force | Out-Null
        Write-CCLSHost "#Created start-message directory" -Log -NoConsole
    }
    
    if (-not (Test-Path $defaultMessageFolder)) {
        New-Item -Path $defaultMessageFolder -ItemType Directory -Force | Out-Null
        Write-CCLSHost "#Created start-message/default directory" -Log -NoConsole
    }
}

# Display startup message if enabled
function Show-StartupMessage {
    $startMessageFolder = Join-Path -Path $settingsFolder -ChildPath "start-message"
    $defaultMessageFolder = Join-Path -Path $startMessageFolder -ChildPath "default"
    $enabledMessageFile = Join-Path -Path $defaultMessageFolder -ChildPath "template.json"
    
    if (Test-Path $enabledMessageFile) {
        try {
            $templateContent = Get-Content -Path $enabledMessageFile -Raw | ConvertFrom-Json
            Invoke-StartupMessageTemplate -Template $templateContent
        }
        catch {
            Write-CCLSHost "#Error loading startup message template: $($_.Exception.Message)" -Log -NoConsole
        }
    }
}

# Execute startup message template
function Invoke-StartupMessageTemplate {
    param (
        [object]$Template
    )
    
    if ($Template.template) {
        # Check if this is a dynamic template that needs data processing
        if ($Template.template.type) {
            switch ($Template.template.type) {
                "installed_games" {
                    Show-InstalledGamesStartupMessage -Template $Template
                    return
                }
                "library_stats" {
                    Show-LibraryStatsStartupMessage -Template $Template
                    return
                }
            }
        }
        
        # Handle regular static templates
        if ($Template.template.messages) {
            foreach ($message in $Template.template.messages) {
                $text = if ($message.text) { $message.text } else { "" }
                $color = if ($message.color) { $message.color } else { "White" }
                $newline = if ($message.newline -eq $false) { $false } else { $true }
                
                try {
                    # Validate color name exists
                    $validColors = @("Black", "DarkBlue", "DarkGreen", "DarkCyan", "DarkRed", "DarkMagenta", "DarkYellow", "Gray", "DarkGray", "Blue", "Green", "Cyan", "Red", "Magenta", "Yellow", "White")
                    
                    if ($validColors -contains $color) {
                        $consoleColor = [System.ConsoleColor]::$color
                    } else {
                        $consoleColor = [System.ConsoleColor]::White
                    }
                    
                    if ($newline) {
                        Write-Host $text -ForegroundColor $consoleColor
                        # Also log it
                        Write-CCLSHost "#StartupMsg: $text" -Log -NoConsole
                    } else {
                        Write-Host $text -ForegroundColor $consoleColor -NoNewline
                        # Also log it
                        Write-CCLSHost "#StartupMsg: $text" -Log -NoConsole
                    }
                }
                catch {
                    # Fallback to simple Write-Host if there are any issues
                    if ($newline) {
                        Write-Host $text -ForegroundColor White
                    } else {
                        Write-Host $text -ForegroundColor White -NoNewline
                    }
                }
            }
        }
    }
}

function Show-InstalledGamesStartupMessage {
    param (
        [object]$Template
    )
    
    # Show header from template
    if ($Template.template.messages) {
        foreach ($message in $Template.template.messages) {
            $text = if ($message.text) { $message.text } else { "" }
            $color = if ($message.color) { $message.color } else { "White" }
            
            Write-Host $text -ForegroundColor $color
            Write-CCLSHost "#StartupMsg: $text" -Log -NoConsole
        }
    }
    
    # Ensure cache is initialized
    if (-not $script:libraryCache) {
        Initialize-LibraryCache
    }
    
    try {
        # Check if we have games in cache
        if (-not $script:libraryCache.games -or $script:libraryCache.totalGames -eq 0) {
            Write-Host "No games are currently installed." -ForegroundColor Yellow
            Write-CCLSHost "#StartupMsg: No games are currently installed." -Log -NoConsole
            Write-Host "" -ForegroundColor White
            return
        }
        
        # Process games from cache
        $installedGames = @()
        
        foreach ($cachedGame in $script:libraryCache.games) {
            $gameEntry = @{
                Name = $cachedGame.gameName
                Id = $cachedGame.gameId
                LocalVersion = $cachedGame.localVersion
                LocalSize = $cachedGame.localSizeFormatted
                HasMetadata = $cachedGame.hasMetadata
                IsOutdated = $false
            }
            
            $installedGames += $gameEntry
        }
        
        # Sort games: metadata first, then by name
        if ($installedGames.Count -eq 1) {
            $sortedGames = $installedGames
        } else {
            $sortedGames = $installedGames | Sort-Object @{Expression={-($_.HasMetadata -as [int])}}, Name
        }
        
        if ($sortedGames -isnot [array]) {
            $sortedGames = @($sortedGames)
        }
        
        # Calculate column widths
        $maxNameLength = 30
        $maxIdLength = 15
        $maxSizeLength = 12
        $maxVersionLength = 15
        
        if ($sortedGames.Count -gt 0) {
            foreach ($game in $sortedGames) {
                if ($game.Name.Length -gt $maxNameLength) { $maxNameLength = $game.Name.Length }
                if (("ID: " + $game.Id).Length -gt $maxIdLength) { $maxIdLength = ("ID: " + $game.Id).Length }
                if (("Size: " + $game.LocalSize).Length -gt $maxSizeLength) { $maxSizeLength = ("Size: " + $game.LocalSize).Length }
                if (("Ver: " + $game.LocalVersion).Length -gt $maxVersionLength) { $maxVersionLength = ("Ver: " + $game.LocalVersion).Length }
            }
        }
        
        $nameWidth = $maxNameLength + 2
        $idWidth = $maxIdLength + 2
        $sizeWidth = $maxSizeLength + 2
        $versionWidth = $maxVersionLength + 2
        
        # Display header
        $headerLine = "Game Name".PadRight($nameWidth) + "ID".PadRight($idWidth) + "Size".PadRight($sizeWidth) + "Version"
        Write-Host $headerLine -ForegroundColor Cyan
        Write-CCLSHost "#StartupMsg: $headerLine" -Log -NoConsole
        
        $separatorLine = ("-" * ($nameWidth - 1)) + " " + ("-" * ($idWidth - 1)) + " " + ("-" * ($sizeWidth - 1)) + " " + ("-" * ($versionWidth - 1))
        Write-Host $separatorLine -ForegroundColor Cyan
        Write-CCLSHost "#StartupMsg: $separatorLine" -Log -NoConsole
        
        # Display games (limit to first 10 for startup)
        $displayCount = [Math]::Min(10, $sortedGames.Count)
        
        for ($i = 0; $i -lt $displayCount; $i++) {
            $game = $sortedGames[$i]
            
            $gameColor = if ($game.HasMetadata) { "White" } else { "Gray" }
            
            $gameName = $game.Name.PadRight($nameWidth)
            $gameId = ("ID: " + $game.Id).PadRight($idWidth)
            $gameSize = ("Size: " + $game.LocalSize).PadRight($sizeWidth)
            $gameVersion = "Ver: " + $game.LocalVersion
            
            $gameLine = "$gameName$gameId$gameSize$gameVersion"
            Write-Host $gameLine -ForegroundColor $gameColor
            Write-CCLSHost "#StartupMsg: $gameLine" -Log -NoConsole
        }
        
        # Show summary
        if ($sortedGames.Count -gt 10) {
            $remainingCount = $sortedGames.Count - 10
            $summaryLine = "`n... and $remainingCount more games. Use 'browse' to see all installed games."
            Write-Host $summaryLine -ForegroundColor Yellow
            Write-CCLSHost "#StartupMsg: $summaryLine" -Log -NoConsole
        } else {
            $summaryLine = "`nTotal: $($sortedGames.Count) games installed. Use 'browse' for detailed management."
            Write-Host $summaryLine -ForegroundColor Green
            Write-CCLSHost "#StartupMsg: $summaryLine" -Log -NoConsole
        }
        
        Write-Host "" -ForegroundColor White
        
    } catch {
        Write-Host "Error loading installed games information from cache." -ForegroundColor Red
        Write-CCLSHost "#StartupMsg: Error loading installed games from cache: $($_.Exception.Message)" -Log -NoConsole
        Write-Host "" -ForegroundColor White
    }
}

function Show-LibraryStatsStartupMessage {
    param (
        [object]$Template
    )
    
    # Show header from template
    if ($Template.template.messages) {
        foreach ($message in $Template.template.messages) {
            $text = if ($message.text) { $message.text } else { "" }
            $color = if ($message.color) { $message.color } else { "White" }
            
            Write-Host $text -ForegroundColor $color
            Write-CCLSHost "#StartupMsg: $text" -Log -NoConsole
        }
    }
    
    # Ensure cache is initialized
    if (-not $script:libraryCache) {
        Initialize-LibraryCache
    }
    
    # Get local statistics from cache
    $installedCount = 0
    $totalLocalSize = 0
    $formattedLocalSize = "0 B"
    
    if ($script:libraryCache) {
        $installedCount = $script:libraryCache.totalGames
        $totalLocalSize = $script:libraryCache.totalSize
        $formattedLocalSize = $script:libraryCache.totalSizeFormatted
    }
    
    # Get online statistics (only if logged in and not in DevMode)
    $onlineGamesCount = "N/A"
    $onlineBundlesCount = "N/A"
    $totalOnlineCount = "N/A"
    
    $settings = Initialize-Settings
    if ($null -ne $script:cachedCredentials -and 
        $null -ne $script:cachedCredentials.Username -and 
        $null -ne $script:cachedCredentials.Password -and
        -not $settings.DevMode) {
        
        try {
            $params = @{
                Uri = "$cliApiUrl/list.php"
                Method = "POST"
                Headers = @{
                    "User-Agent" = "CCLS-CLI/2.0"
                }
                Body = @{
                    username = $script:cachedCredentials.Username
                    password = $script:cachedCredentials.Password
                }
            }
            
            $response = Invoke-RestMethod @params -TimeoutSec 5
            
            if ($response.success) {
                $onlineGamesCount = $response.count
                $onlineBundlesCount = $response.bundle_count
                $totalOnlineCount = $onlineGamesCount + $onlineBundlesCount
            }
        } catch {
            Write-CCLSHost "#StartupMsg: Could not fetch online statistics: $($_.Exception.Message)" -Log -NoConsole
            # Keep N/A values
        }
    }
    
    # Display statistics
    Write-Host "" -ForegroundColor White
    
    # Local Statistics
    $localStatsLine = "Installed Games: $installedCount games ($formattedLocalSize total)"
    Write-Host $localStatsLine -ForegroundColor Green
    Write-CCLSHost "#StartupMsg: $localStatsLine" -Log -NoConsole
    
    # Online Statistics
    if ($totalOnlineCount -ne "N/A") {
        $onlineStatsLine = "Available Online: $onlineGamesCount games, $onlineBundlesCount bundles ($totalOnlineCount total)"
        Write-Host $onlineStatsLine -ForegroundColor Cyan
        Write-CCLSHost "#StartupMsg: $onlineStatsLine" -Log -NoConsole
        
        # Progress indicator
        if ($installedCount -gt 0 -and $onlineGamesCount -ne "N/A") {
            $percentage = [Math]::Round(($installedCount / $onlineGamesCount) * 100, 1)
            $progressLine = "Library Progress: $percentage% of available games installed"
            Write-Host $progressLine -ForegroundColor Yellow
            Write-CCLSHost "#StartupMsg: $progressLine" -Log -NoConsole
        }
    } else {
        $offlineNoteLine = "Online Statistics: Not available (offline mode or connection issue)"
        Write-Host $offlineNoteLine -ForegroundColor Gray
        Write-CCLSHost "#StartupMsg: $offlineNoteLine" -Log -NoConsole
    }
    
    Write-Host "" -ForegroundColor White
    
    # Quick tips
    if ($installedCount -eq 0) {
        $tipLine = "Quick tip: Use 'search library' to browse available games"
        Write-Host $tipLine -ForegroundColor Yellow
        Write-CCLSHost "#StartupMsg: $tipLine" -Log -NoConsole
    } else {
        $tipLine = "Quick tip: Use 'browse' to manage your games or 'search library' to find new ones"
        Write-Host $tipLine -ForegroundColor Yellow
        Write-CCLSHost "#StartupMsg: $tipLine" -Log -NoConsole
    }
    
    Write-Host "" -ForegroundColor White
}

# Main startup message management function
function Manage-StartupMessage {
    param (
        [string]$Action,
        [string]$TemplateName = ""
    )
    
    # Initialize directories if they don't exist
    Initialize-StartupMessageDirectories
    
    $startMessageFolder = Join-Path -Path $settingsFolder -ChildPath "start-message"
    $defaultMessageFolder = Join-Path -Path $startMessageFolder -ChildPath "default"
    $templatesUrl = "$baseUrl/CLI/api/main/startup_message/templates"
    $listApiUrl = "$baseUrl/CLI/api/main/startup_message/list.php"
    
    switch ($Action.ToLower()) {
        "list" {
            try {
                Write-CCLSHost "Fetching available startup message templates..." -ForegroundColor Cyan -Log
                
                $params = @{
                    Uri = $listApiUrl
                    Method = "GET"
                    Headers = @{
                        "User-Agent" = "CCLS-CLI/2.0"
                    }
                }
                
                $response = Invoke-RestMethod @params
                
                if ($response.success) {
                    Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
                    Write-CCLSHost "Available Startup Message Templates - $($response.count) found" -ForegroundColor Green -Log
                    Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
                    
                    if ($response.count -eq 0) {
                        Write-CCLSHost "No templates available on the server." -ForegroundColor Yellow -Log
                    } else {
                        # Calculate column widths safely
                        $maxNameLength = 20  # Default minimum
                        if ($response.templates.Count -gt 0) {
                            try {
                                $nameLengths = @()
                                foreach ($template in $response.templates) {
                                    $nameLengths += ("'$($template.name)'").Length
                                }
                                if ($nameLengths.Count -gt 0) {
                                    $maxCalc = ($nameLengths | Measure-Object -Maximum).Maximum
                                    if ($maxCalc -gt $maxNameLength) {
                                        $maxNameLength = $maxCalc
                                    }
                                }
                            }
                            catch {
                                # Use default if calculation fails
                                $maxNameLength = 20
                            }
                        }
                        
                        $nameWidth = $maxNameLength + 2
                        
                        # Display header
                        $headerLine = "Template Name".PadRight($nameWidth) + "Author".PadRight(15) + "Version".PadRight(10) + "Description"
                        Write-CCLSHost $headerLine -ForegroundColor Cyan -Log
                        
                        $separatorLine = ("-" * ($nameWidth - 1)) + " " + ("-" * 14) + " " + ("-" * 9) + " " + ("-" * 20)
                        Write-CCLSHost $separatorLine -ForegroundColor Cyan -Log
                        
                        # Display each template
                        foreach ($template in $response.templates) {
                            $templateName = ("'$($template.name)'").PadRight($nameWidth)
                            $author = $template.author.PadRight(15)
                            $version = $template.version.PadRight(10)
                            $description = $template.description
                            
                            $templateLine = "$templateName$author$version$description"
                            Write-CCLSHost $templateLine -ForegroundColor White -Log
                        }
                        
                        Write-CCLSHost "`nUse 'sys start-message get [template-name]' to download a template" -ForegroundColor Yellow -Log
                        Write-CCLSHost "Note: Use the template filename (e.g., 'gradient', 'minimal') not the display name" -ForegroundColor Gray -Log
                    }
                } else {
                    Write-CCLSHost "Error fetching templates: $($response.error)" -ForegroundColor Red -Log
                }
            }
            catch {
                Write-CCLSHost "Error connecting to template server: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
        
        "get" {
            if ([string]::IsNullOrWhiteSpace($TemplateName)) {
                Write-CCLSHost "Template name is required. Use: sys start-message get [template-name]" -ForegroundColor Red -Log
                return
            }
            
            try {
                Write-CCLSHost "Downloading template '$TemplateName'..." -ForegroundColor Cyan -Log
                
                $templateUrl = "$templatesUrl/$TemplateName.json"
                $localPath = Join-Path -Path $startMessageFolder -ChildPath "$TemplateName.json"
                
                $webClient = New-Object System.Net.WebClient
                $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
                $webClient.DownloadFile($templateUrl, $localPath)
                
                if (Test-Path $localPath) {
                    Write-CCLSHost "Template '$TemplateName' downloaded successfully!" -ForegroundColor Green -Log
                } else {
                    Write-CCLSHost "Failed to download template '$TemplateName'" -ForegroundColor Red -Log
                }
            }
            catch {
                Write-CCLSHost "Error downloading template: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
        
        "enable" {
            if ([string]::IsNullOrWhiteSpace($TemplateName)) {
                Write-CCLSHost "Template name is required. Use: sys start-message enable [template-name]" -ForegroundColor Red -Log
                return
            }
            
            $templatePath = Join-Path -Path $startMessageFolder -ChildPath "$TemplateName.json"
            
            if (-not (Test-Path $templatePath)) {
                Write-CCLSHost "Template '$TemplateName' not found. Download it first with: sys start-message get $TemplateName" -ForegroundColor Red -Log
                return
            }
            
            try {
                # Move current default template back to main folder if it exists
                $currentDefaultPath = Join-Path -Path $defaultMessageFolder -ChildPath "template.json"
                $currentDefaultInfoPath = Join-Path -Path $defaultMessageFolder -ChildPath "info.txt"
                
                if (Test-Path $currentDefaultPath) {
                    if (Test-Path $currentDefaultInfoPath) {
                        $currentTemplateName = (Get-Content -Path $currentDefaultInfoPath -Raw).Trim()
                        if (-not [string]::IsNullOrWhiteSpace($currentTemplateName)) {
                            $backupPath = Join-Path -Path $startMessageFolder -ChildPath "$currentTemplateName.json"
                            
                            if (Test-Path $backupPath) {
                                Remove-Item -Path $backupPath -Force
                            }
                            
                            Move-Item -Path $currentDefaultPath -Destination $backupPath -Force
                        } else {
                            Remove-Item -Path $currentDefaultPath -Force
                        }
                        Remove-Item -Path $currentDefaultInfoPath -Force
                    } else {
                        Remove-Item -Path $currentDefaultPath -Force
                    }
                }
                
                # Copy new template to default folder
                $newDefaultPath = Join-Path -Path $defaultMessageFolder -ChildPath "template.json"
                $newInfoPath = Join-Path -Path $defaultMessageFolder -ChildPath "info.txt"
                
                Copy-Item -Path $templatePath -Destination $newDefaultPath -Force
                Set-Content -Path $newInfoPath -Value $TemplateName.Trim() -NoNewline -Force
                
                Write-CCLSHost "Template '$TemplateName' enabled successfully!" -ForegroundColor Green -Log
                Write-CCLSHost "The startup message will appear on your next login." -ForegroundColor Cyan -Log
            }
            catch {
                Write-CCLSHost "Error enabling template: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
        
        "get,enable" {
            if ([string]::IsNullOrWhiteSpace($TemplateName)) {
                Write-CCLSHost "Template name is required. Use: sys start-message get,enable [template-name]" -ForegroundColor Red -Log
                return
            }
            
            # Download first
            Manage-StartupMessage -Action "get" -TemplateName $TemplateName
            
            # Then enable if download was successful
            $templatePath = Join-Path -Path $startMessageFolder -ChildPath "$TemplateName.json"
            if (Test-Path $templatePath) {
                Manage-StartupMessage -Action "enable" -TemplateName $TemplateName
            }
        }
        
        "try" {
            if ([string]::IsNullOrWhiteSpace($TemplateName)) {
                Write-CCLSHost "Template name is required. Use: sys start-message try [template-name]" -ForegroundColor Red -Log
                return
            }
            
            $templatePath = Join-Path -Path $startMessageFolder -ChildPath "$TemplateName.json"
            
            if (-not (Test-Path $templatePath)) {
                Write-CCLSHost "Template '$TemplateName' not found. Download it first with: sys start-message get $TemplateName" -ForegroundColor Red -Log
                return
            }
            
            try {
                Write-CCLSHost "`nPreviewing template '$TemplateName':" -ForegroundColor Yellow -Log
                $separatorLine = "=" * 50
                Write-CCLSHost $separatorLine -ForegroundColor DarkGray -Log
                
                $templateContent = Get-Content -Path $templatePath -Raw | ConvertFrom-Json
                Invoke-StartupMessageTemplate -Template $templateContent
                
                Write-CCLSHost $separatorLine -ForegroundColor DarkGray -Log
                Write-CCLSHost "Preview complete. Use 'sys start-message enable $TemplateName' to set as active." -ForegroundColor Yellow -Log
            }
            catch {
                Write-CCLSHost "Error previewing template: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
        
        "view" {
            $currentDefaultPath = Join-Path -Path $defaultMessageFolder -ChildPath "template.json"
            $currentDefaultInfoPath = Join-Path -Path $defaultMessageFolder -ChildPath "info.txt"
            
            if (Test-Path $currentDefaultPath) {
                try {
                    $templateName = if (Test-Path $currentDefaultInfoPath) { 
                        (Get-Content -Path $currentDefaultInfoPath -Raw).Trim() 
                    } else { 
                        "Unknown" 
                    }
                    
                    Write-CCLSHost "`nCurrent startup message (Template: $templateName):" -ForegroundColor Yellow -Log
                    $separatorLine = "=" * 50
                    Write-CCLSHost $separatorLine -ForegroundColor DarkGray -Log
                    
                    $templateContent = Get-Content -Path $currentDefaultPath -Raw | ConvertFrom-Json
                    Invoke-StartupMessageTemplate -Template $templateContent
                    
                    Write-CCLSHost $separatorLine -ForegroundColor DarkGray -Log
                }
                catch {
                    Write-CCLSHost "Error displaying current template: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
            } else {
                Write-CCLSHost "No startup message is currently enabled." -ForegroundColor Yellow -Log
                Write-CCLSHost "Use 'sys start-message list' to see available templates." -ForegroundColor Cyan -Log
            }
        }
        
        "default" {
            $currentDefaultPath = Join-Path -Path $defaultMessageFolder -ChildPath "template.json"
            $currentDefaultInfoPath = Join-Path -Path $defaultMessageFolder -ChildPath "info.txt"
            
            if (Test-Path $currentDefaultPath) {
                try {
                    # Move current template back to main folder
                    if (Test-Path $currentDefaultInfoPath) {
                        $currentTemplateName = (Get-Content -Path $currentDefaultInfoPath -Raw).Trim()
                        if (-not [string]::IsNullOrWhiteSpace($currentTemplateName)) {
                            $backupPath = Join-Path -Path $startMessageFolder -ChildPath "$currentTemplateName.json"
                            
                            if (Test-Path $backupPath) {
                                Remove-Item -Path $backupPath -Force
                            }
                            
                            Move-Item -Path $currentDefaultPath -Destination $backupPath -Force
                        } else {
                            Remove-Item -Path $currentDefaultPath -Force
                        }
                        Remove-Item -Path $currentDefaultInfoPath -Force
                    } else {
                        Remove-Item -Path $currentDefaultPath -Force
                    }
                    
                    Write-CCLSHost "Startup message disabled. Default system messages will be shown." -ForegroundColor Green -Log
                }
                catch {
                    Write-CCLSHost "Error disabling startup message: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
            } else {
                Write-CCLSHost "No startup message is currently enabled." -ForegroundColor Yellow -Log
            }
        }
        
        "del" {
            if ([string]::IsNullOrWhiteSpace($TemplateName)) {
                Write-CCLSHost "Template name is required. Use: sys start-message del [template-name]" -ForegroundColor Red -Log
                return
            }
            
            $templatePath = Join-Path -Path $startMessageFolder -ChildPath "$TemplateName.json"
            
            if (Test-Path $templatePath) {
                try {
                    # Check if this is the currently enabled template
                    $currentDefaultInfoPath = Join-Path -Path $defaultMessageFolder -ChildPath "info.txt"
                    $currentlyEnabled = $false
                    
                    if (Test-Path $currentDefaultInfoPath) {
                        $currentTemplateName = (Get-Content -Path $currentDefaultInfoPath -Raw).Trim()
                        if ($currentTemplateName -eq $TemplateName) {
                            $currentlyEnabled = $true
                        }
                    }
                    
                    if ($currentlyEnabled) {
                        Write-CCLSHost "Cannot delete '$TemplateName' - it is currently enabled." -ForegroundColor Red -Log
                        Write-CCLSHost "Use 'sys start-message default' to disable it first, then try deleting again." -ForegroundColor Yellow -Log
                        return
                    }
                    
                    Remove-Item -Path $templatePath -Force
                    Write-CCLSHost "Template '$TemplateName' deleted successfully!" -ForegroundColor Green -Log
                }
                catch {
                    Write-CCLSHost "Error deleting template: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
            } else {
                Write-CCLSHost "Template '$TemplateName' not found." -ForegroundColor Red -Log
            }
        }
        
        "wipe" {
            try {
                Write-CCLSHost "WARNING: This will delete ALL downloaded startup message templates!" -ForegroundColor Red -Log
                Write-CCLSHost "Are you sure you want to continue? (Y/N)" -ForegroundColor Yellow -Log
                
                $confirmation = Read-Host
                Write-CCLSHost "$confirmation" -NoConsole -Log
                
                if ($confirmation.ToLower() -eq "y") {
                    # Disable current template first
                    Manage-StartupMessage -Action "default"
                    
                    # Remove all template files
                    $templateFiles = Get-ChildItem -Path $startMessageFolder -Filter "*.json" -ErrorAction SilentlyContinue
                    
                    foreach ($file in $templateFiles) {
                        Remove-Item -Path $file.FullName -Force
                    }
                    
                    Write-CCLSHost "All startup message templates have been deleted!" -ForegroundColor Green -Log
                } else {
                    Write-CCLSHost "Operation cancelled." -ForegroundColor Yellow -Log
                }
            }
            catch {
                Write-CCLSHost "Error wiping templates: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
        
        default {
            Write-CCLSHost "Unknown action. Available actions:" -ForegroundColor Red -Log
            Write-CCLSHost "  list              - List available templates" -ForegroundColor Cyan -Log
            Write-CCLSHost "  get [name]        - Download a template" -ForegroundColor Cyan -Log
            Write-CCLSHost "  enable [name]     - Enable a downloaded template" -ForegroundColor Cyan -Log
            Write-CCLSHost "  get,enable [name] - Download and enable a template" -ForegroundColor Cyan -Log
            Write-CCLSHost "  try [name]        - Preview a template" -ForegroundColor Cyan -Log
            Write-CCLSHost "  view              - View current startup message" -ForegroundColor Cyan -Log
            Write-CCLSHost "  default           - Disable startup message" -ForegroundColor Cyan -Log
            Write-CCLSHost "  del [name]        - Delete a template" -ForegroundColor Cyan -Log
            Write-CCLSHost "  wipe              - Delete all templates" -ForegroundColor Cyan -Log
        }
    }
}

# Updated Install-Utility function
function Install-Utility {
    param (
        [string]$UtilityName
    )
    
    # Handle different utilities
    switch ($UtilityName.ToLower()) {
        "7zip" {
            Install7Zip
        }
        "requests" {
            InstallPythonRequests
        }
        "python" {
            Install-Python
        }
        default {
            Write-CCLSHost "Unsupported utility: $UtilityName" -ForegroundColor Red -Log
            Write-CCLSHost "Currently supported utilities: 7zip, requests, python" -ForegroundColor Green -Log
        }
    }
}

# Function to install 7-Zip (internal function for Install-Utility)
function Install7Zip {
    # Determine the current script directory
    $scriptLocation = if ($PSScriptRoot) {
        # If running from a script, use its location
        $PSScriptRoot
    } else {
        # If running in console, use current directory
        (Get-Location).Path
    }
    
    # Target directory is the script location
    $targetDir = $scriptLocation
    
    # URLs for download - Updated for v2.0 API structure
    $zipUrl = "$baseUrl/CLI/api/2.0/utilities/7zip/7zip.zip"
    $zipPath = Join-Path -Path $targetDir -ChildPath "7zip.zip"
    
    Write-CCLSHost "Starting 7-Zip installation..." -ForegroundColor Cyan -Log
    
    try {
        # Download the zip file
        Write-CCLSHost "Downloading 7-Zip package from $zipUrl" -ForegroundColor Yellow -Log
        
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
        $webClient.DownloadFile($zipUrl, $zipPath)
        
        if (-not (Test-Path $zipPath)) {
            Write-CCLSHost "Failed to download 7-Zip package." -ForegroundColor Red -Log
            return
        }
        
        Write-CCLSHost "Download completed successfully." -ForegroundColor Green -Log
        
        # Create temporary extraction directory
        $tempExtractPath = Join-Path -Path $targetDir -ChildPath "7zip_temp"
        if (Test-Path $tempExtractPath) {
            Remove-Item -Path $tempExtractPath -Recurse -Force
        }
        New-Item -ItemType Directory -Path $tempExtractPath -Force | Out-Null
        
        # Final 7zip directory
        $finalPath = Join-Path -Path $targetDir -ChildPath "7zip"
        if (Test-Path $finalPath) {
            Remove-Item -Path $finalPath -Recurse -Force
        }
        
        # Extract the zip file to temp location
        Write-CCLSHost "Extracting 7-Zip package..." -ForegroundColor Yellow -Log
        
        $extractionSuccess = $false
        
        try {
            # Try to use built-in Expand-Archive
            Expand-Archive -Path $zipPath -DestinationPath $tempExtractPath -Force
            $extractionSuccess = $true
        }
        catch {
            Write-CCLSHost "#Built-in extraction failed, trying alternate method: $($_.Exception.Message)" -ForegroundColor Yellow -Log -NoConsole
            
            try {
                # Alternative extraction method using .NET
                Add-Type -AssemblyName System.IO.Compression.FileSystem
                [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $tempExtractPath)
                $extractionSuccess = $true
            }
            catch {
                Write-CCLSHost "Extraction failed: $($_.Exception.Message)" -ForegroundColor Red -Log
                $extractionSuccess = $false
            }
        }
        
        # Fix nested folder issue if extraction was successful
        if ($extractionSuccess) {
            # Check if we have a nested 7zip folder
            $nestedFolder = Join-Path -Path $tempExtractPath -ChildPath "7zip"
            if (Test-Path $nestedFolder) {
                # Move the contents from nested folder to final location
                Write-CCLSHost "#Fixing folder structure..." -Log -NoConsole
                Move-Item -Path $nestedFolder -Destination $targetDir -Force
                $extractionSuccess = $true
            } else {
                # If no nested folder, just rename temp folder to final name
                Rename-Item -Path $tempExtractPath -NewName "7zip"
                $extractionSuccess = $true
            }
        }
        
        # Clean up the downloaded zip file
        if (Test-Path $zipPath) {
            Remove-Item -Path $zipPath -Force
            Write-CCLSHost "#Removed temporary download file." -ForegroundColor Gray -Log -NoConsole
        }
        
        # Clean up temp folder if it still exists
        if (Test-Path $tempExtractPath) {
            Remove-Item -Path $tempExtractPath -Recurse -Force
            Write-CCLSHost "#Removed temporary extraction folder." -ForegroundColor Gray -Log -NoConsole
        }
        
        # Verify installation
        $exePath = Join-Path -Path $finalPath -ChildPath "7z.exe"
        if ($extractionSuccess -and (Test-Path $exePath)) {
            Write-CCLSHost "7-Zip has been successfully installed to $finalPath" -ForegroundColor Green -Log
            Write-CCLSHost "You can now use 7-Zip for file extraction." -ForegroundColor Green -Log
        }
        else {
            Write-CCLSHost "7-Zip installation was not completed successfully." -ForegroundColor Red -Log
            Write-CCLSHost "Please try again or manually install 7-Zip." -ForegroundColor Yellow -Log
        }
    }
    catch {
        Write-CCLSHost "Error during installation: $($_.Exception.Message)" -ForegroundColor Red -Log
        Write-CCLSHost "7-Zip installation failed." -ForegroundColor Red -Log
    }
}

# Function to install Python requests library (internal function for Install-Utility)
function InstallPythonRequests {
    Write-CCLSHost "Checking for Python installation..." -ForegroundColor Cyan -Log
    
    # First check if Python is installed
    try {
        $pythonResult = python --version 2>&1
        if ($pythonResult -match "Python (\d+\.\d+\.\d+)") {
            $pythonVersion = $matches[1]
            Write-CCLSHost "Python detected (v$pythonVersion)" -ForegroundColor Green -Log
        } else {
            Write-CCLSHost "Python not detected" -ForegroundColor Red -Log
            Write-CCLSHost "Please install Python first before installing the requests library." -ForegroundColor Yellow -Log
            Write-CCLSHost "Download Python with 'install python' command or" -ForegroundColor Yellow -Log
            Write-CCLSHost "Download Python from: https://www.python.org/downloads/ manually" -ForegroundColor Yellow -Log
            return
        }
    } catch {
        Write-CCLSHost "Python is not installed or not in the system PATH." -ForegroundColor Red -Log
        Write-CCLSHost "Please install Python first before installing the requests library." -ForegroundColor Yellow -Log
        Write-CCLSHost "Download Python with 'install python' command or" -ForegroundColor Yellow -Log
        Write-CCLSHost "Download Python from: https://www.python.org/downloads/ manually" -ForegroundColor Yellow -Log
        return
    }
    
    # Check if requests is already installed
    Write-CCLSHost "Checking if requests library is already installed..." -ForegroundColor Cyan -Log
    
    try {
        $requestsCheck = python -c "import requests; print('Installed (v{0})'.format(requests.__version__))" 2>&1
        if ($requestsCheck -match "Installed \(v([\d\.]+)\)") {
            $requestsVersion = $matches[1]
            Write-CCLSHost "The requests library is already installed (v$requestsVersion)" -ForegroundColor Green -Log
            
            # Ask if user wants to upgrade
            Write-CCLSHost "Do you want to upgrade to the latest version? (Y/N)" -ForegroundColor Yellow -Log
            $upgradeConfirmation = Read-Host
            Write-CCLSHost "$upgradeConfirmation" -NoConsole -Log
            
            if ($upgradeConfirmation.ToLower() -ne "y") {
                Write-CCLSHost "Installation skipped." -ForegroundColor Yellow -Log
                return
            }
            
            # If yes, set upgrade flag
            $upgradeFlag = "--upgrade"
        } else {
            # Not installed
            $upgradeFlag = ""
        }
    } catch {
        # Not installed or error checking
        Write-CCLSHost "The requests library is not installed." -ForegroundColor Yellow -Log
        $upgradeFlag = ""
    }
    
    Write-CCLSHost "Installing Python requests library..." -ForegroundColor Cyan -Log
    
    try {
        # Use Start-Process with -Wait to run pip in the background
        $pipCommand = "pip"
        $pipArgs = "install $upgradeFlag requests"
        
        # Temporary files for output and error
        $tempOutputFile = [System.IO.Path]::GetTempFileName()
        $tempErrorFile = [System.IO.Path]::GetTempFileName()
        
        Write-CCLSHost "#Running: $pipCommand $pipArgs" -Log -NoConsole
        
        # Show progress indicator
        Write-CCLSHost "Installing..." -NoNewline -ForegroundColor Yellow -Log
        
        # Run pip in background and redirect output to temp files
        $process = Start-Process -FilePath $pipCommand -ArgumentList $pipArgs -NoNewWindow -PassThru -RedirectStandardOutput $tempOutputFile -RedirectStandardError $tempErrorFile -Wait
        
        # Read output and error from temp files
        $output = Get-Content -Path $tempOutputFile -Raw
        $error = Get-Content -Path $tempErrorFile -Raw
        
        # Clean up temp files
        Remove-Item -Path $tempOutputFile -Force -ErrorAction SilentlyContinue
        Remove-Item -Path $tempErrorFile -Force -ErrorAction SilentlyContinue
        
        Write-CCLSHost "" -Log  # Newline after progress indicator
        
        # Verify installation regardless of process exit code
        # This is more reliable than checking process exit code
        $installSuccess = $false
        try {
            $verifyResult = python -c "import requests; print('Installed (v{0})'.format(requests.__version__))" 2>&1
            if ($verifyResult -match "Installed \(v([\d\.]+)\)") {
                $installSuccess = $true
                $newVersion = $matches[1]
            }
        } catch {
            $installSuccess = $false
        }
        
        if ($installSuccess) {
            # Check if output contains "Successfully installed" as additional confirmation
            if (-not [string]::IsNullOrWhiteSpace($output) -and 
                ($output -match "Successfully installed" -or $output -match "Requirement already satisfied")) {
                Write-CCLSHost "Python requests library v$newVersion installed successfully!" -ForegroundColor Green -Log
                
                # Show summary of what happened
                if ($output -match "Requirement already satisfied") {
                    Write-CCLSHost "All requirements were already satisfied." -ForegroundColor Green -Log
                } else {
                    Write-CCLSHost "Installation completed successfully." -ForegroundColor Green -Log
                }
            } else {
                Write-CCLSHost "Python requests library appears to be installed (v$newVersion)" -ForegroundColor Green -Log
                Write-CCLSHost "But the installation process reported unusual output." -ForegroundColor Yellow -Log
            }
        } else {
            Write-CCLSHost "Failed to install Python requests library." -ForegroundColor Red -Log
            if (-not [string]::IsNullOrWhiteSpace($error)) {
                Write-CCLSHost "Error details:" -ForegroundColor Red -Log
                Write-CCLSHost $error -ForegroundColor Red -Log
            }
            if (-not [string]::IsNullOrWhiteSpace($output)) {
                Write-CCLSHost "Output details:" -ForegroundColor Yellow -Log
                Write-CCLSHost $output -ForegroundColor Yellow -Log
            }
        }
    } catch {
        Write-CCLSHost "Error during installation: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# Function to install Python
function Install-Python {
    Write-CCLSHost "Starting Python installation process..." -ForegroundColor Cyan -Log
    
    # Create a temporary directory for the download
    $tempDir = [System.IO.Path]::GetTempPath()
    $tempDownloadPath = Join-Path -Path $tempDir -ChildPath "python_installer.exe"
    
    # Determine if system is 64-bit or 32-bit
    $is64Bit = [Environment]::Is64BitOperatingSystem
    
    # Get Python version info from our server
    try {
        Write-CCLSHost "Retrieving Python version information..." -ForegroundColor Yellow -Log
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
        
        # Use the CCLS API endpoint to get Python version info - Updated for v2.0 API structure
        $pythonInfoJson = $webClient.DownloadString("$cliApiUrl/install_python.php")
        $pythonInfo = $pythonInfoJson | ConvertFrom-Json
        
        # Use the appropriate URL based on system architecture
        if ($is64Bit) {
            $pythonUrl = $pythonInfo.windows_64bit_url
            Write-CCLSHost "Using 64-bit installer for Python $($pythonInfo.version)" -ForegroundColor Green -Log
        } else {
            $pythonUrl = $pythonInfo.windows_32bit_url
            Write-CCLSHost "Using 32-bit installer for Python $($pythonInfo.version)" -ForegroundColor Green -Log
        }
    } catch {
        Write-CCLSHost "Error retrieving Python information from server: $($_.Exception.Message)" -ForegroundColor Red -Log
        Write-CCLSHost "Installation cannot proceed. Please try again later." -ForegroundColor Red -Log
        return
    }
    
    # Download the Python installer
    try {
        Write-CCLSHost "Starting download from $pythonUrl" -ForegroundColor Yellow -Log
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
        
        Write-CCLSHost "Downloading Python installer to $tempDownloadPath..." -ForegroundColor Cyan -Log
        Write-CCLSHost "Download in progress, this may take a few minutes depending on your connection speed..." -ForegroundColor Yellow -Log
        
        # Use synchronous download with simple progress indication
        $sw = [System.Diagnostics.Stopwatch]::StartNew()
        $webClient.DownloadFile($pythonUrl, $tempDownloadPath)
        $sw.Stop()
        
        if (Test-Path $tempDownloadPath) {
            $fileSize = (Get-Item $tempDownloadPath).Length / 1MB
            Write-CCLSHost "Download completed successfully! Downloaded $([Math]::Round($fileSize, 2)) MB in $([Math]::Round($sw.Elapsed.TotalSeconds, 1)) seconds." -ForegroundColor Green -Log
        } else {
            Write-CCLSHost "Download failed - file not found at expected location." -ForegroundColor Red -Log
            return
        }
    } catch {
        Write-CCLSHost "Error downloading Python installer: $($_.Exception.Message)" -ForegroundColor Red -Log
        return
    }
    
    # Launch the installer
    try {
        Write-CCLSHost "Starting Python installer..." -ForegroundColor Green -Log
        Write-CCLSHost "Please follow the on-screen instructions to complete the installation." -ForegroundColor Yellow -Log
        Write-CCLSHost "Recommended options:" -ForegroundColor Yellow -Log
        Write-CCLSHost " - Check 'Add Python to PATH' (IMPORTANT)" -ForegroundColor Yellow -Log
        Write-CCLSHost " - Ensure 'pip' is selected in the optional features (IMPORTANT)" -ForegroundColor Yellow -Log
        
        # Start the installer
        $process = Start-Process -FilePath $tempDownloadPath -Wait -PassThru
        
        # Handle different exit codes
        if ($process.ExitCode -eq 0) {
            Write-CCLSHost "Python installation process completed successfully." -ForegroundColor Green -Log
        } elseif ($process.ExitCode -eq 1602) {
            Write-CCLSHost "Installation was cancelled by the user." -ForegroundColor Yellow -Log
        } else {
            Write-CCLSHost "Python installer exited with code: $($process.ExitCode)" -ForegroundColor Yellow -Log
        }
        
        Write-CCLSHost "For the script to recognize that Python was installed, you will need to close the script and run it again." -ForegroundColor Red -Log
        Write-CCLSHost "Then run the 'check' command to confirm the Python installation was successful." -ForegroundColor Red -Log
    } catch {
        Write-CCLSHost "Error launching Python installer: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
    
    # Clean up the downloaded file
    try {
        if (Test-Path $tempDownloadPath) {
            Remove-Item -Path $tempDownloadPath -Force
            Write-CCLSHost "Cleaned up temporary installer file." -ForegroundColor Gray -Log -NoConsole
        }
    } catch {
        Write-CCLSHost "Note: Could not remove temporary installer file: $($_.Exception.Message)" -ForegroundColor Yellow -Log -NoConsole
    }
}

# Enhanced Search-Game function with game name search capability (FIXED)
function Search-Game($id) {
    $settings = Initialize-Settings
    if ($settings.DevMode) {
        Write-CCLSHost "'search' is disabled while in Developer mode" -ForegroundColor Red -Log
        return
    }
    if (-not (Assert-DependenciesRequired -CommandName "search")) { return }
    # Check if this is a game name search request
    if ($id -eq "game" -and $args.Count -gt 0) {
        # This is actually a game name search, not an ID
        $searchTerm = $args -join " "
        Write-CCLSHost "#Attempting to search for games matching: '$searchTerm'" -Log -NoConsole
        
        # Perform the game name search
        $searchResult = Search-GameByName -SearchTerm $searchTerm
        
        if ($null -eq $searchResult) {
            # Search failed or was cancelled, error already displayed
            return
        }
        
        # Update the ID to the selected one and continue with normal processing
        $id = $searchResult
        Write-CCLSHost "#Selected game ID: $id, proceeding with search..." -Log -NoConsole
    }
    
    # Validate ID format - now supports both cg0000 and cb0000 formats
    if ($id -notmatch "^(cg|cb)\d{4}$") {
        Write-CCLSHost "Invalid ID format. Please use format 'cg0000' for games or 'cb0000' for bundles." -ForegroundColor Red -Log
        return
    }
    
    # Check if credentials are cached
    if ($null -eq $script:cachedCredentials) {
        Write-CCLSHost "Error: Not logged in. Please restart the application and log in." -ForegroundColor Red -Log
        return
    }
    
    # Determine if this is a game or bundle
    $isBundle = $id -match "^cb\d{4}$"
    $itemType = if ($isBundle) { "bundle" } else { "game" }
    
    try {
        # Set up request parameters with credentials
        $params = @{
            Uri = "$cliApiUrl/search.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
                id = $id
            }
        }
        
        Write-CCLSHost "#Searching for $itemType information..." -Log
        
        # Fetch data from server
        try {
            $response = Invoke-RestMethod @params
            
            # Check if the request was successful
            if (-not $response.success) {
                Write-CCLSHost "Error: $($response.message)" -ForegroundColor Red -Log
                return
            }
            
            $itemInfo = $response
        }
        catch {
            Write-CCLSHost "Error fetching $itemType information: $($_.Exception.Message)" -ForegroundColor Red -Log
            return
        }
        
        # Display item information in a formatted way
        Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
        Write-CCLSHost "$($itemType.ToUpper()) Information for $($itemInfo.name) ($($itemInfo.id))" -ForegroundColor Green -Log
        Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
        
        Write-CCLSHost "`nDescription:" -ForegroundColor Cyan -Log
        Write-CCLSHost $itemInfo.description -Log
        
        if ($itemInfo.safety_score -or $itemInfo.safety_level) {
            Write-CCLSHost "`nSafety:" -ForegroundColor Cyan -Log
            if ($itemInfo.safety_score) { Write-CCLSHost "Score: $($itemInfo.safety_score)" -Log }
            if ($itemInfo.safety_level) { Write-CCLSHost "Level: $($itemInfo.safety_level)" -Log }
        }
        
        Write-CCLSHost "`nDetails:" -ForegroundColor Cyan -Log
        
        # Handle different size properties for game vs bundle
        if ($isBundle) {
            if ($itemInfo.zipped_size) { Write-CCLSHost "Zipped Size: $($itemInfo.zipped_size)" -Log }
            if ($itemInfo.unzipped_size) { Write-CCLSHost "Unzipped Size: $($itemInfo.unzipped_size)" -Log }
            if ($itemInfo.games_included) { Write-CCLSHost "Games Included: $($itemInfo.games_included)" -Log }
        } else {
            if ($itemInfo.size) { Write-CCLSHost "Size: $($itemInfo.size)" -Log }
        }
        
        if ($itemInfo.version -and $itemInfo.version -ne "") { Write-CCLSHost "Version: $($itemInfo.version)" -Log }
        
        if (($itemInfo.online -and $itemInfo.online -ne "") -or 
            ($itemInfo.steam -and $itemInfo.steam -ne "") -or 
            ($itemInfo.epic -and $itemInfo.epic -ne "")) {
            Write-CCLSHost "`nAvailability:" -ForegroundColor Cyan -Log
            if ($itemInfo.online -and $itemInfo.online -ne "") { Write-CCLSHost "Online: $($itemInfo.online)" -Log }
            if ($itemInfo.steam -and $itemInfo.steam -ne "") { Write-CCLSHost "Steam: $($itemInfo.steam)" -Log }
            if ($itemInfo.epic -and $itemInfo.epic -ne "") { Write-CCLSHost "Epic: $($itemInfo.epic)" -Log }
        }
        
        if ($itemInfo.false_av -and $itemInfo.false_av -ne "") {
            Write-CCLSHost "`nNote: " -ForegroundColor Yellow -NoNewline -Log
            Write-CCLSHost "This $itemType may trigger false antivirus alerts: $($itemInfo.false_av)" -Log
        }
        
        # If it's a game, show system requirements
        if (-not $isBundle -and $itemInfo.system_requirements) {
            Write-CCLSHost "`nSystem Requirements:" -ForegroundColor Cyan -Log
            
            if ($itemInfo.system_requirements.minimum) {
                Write-CCLSHost "Minimum:" -ForegroundColor Yellow -Log
                foreach ($prop in $itemInfo.system_requirements.minimum.PSObject.Properties) {
                    Write-CCLSHost "  $($prop.Name): $($prop.Value)" -Log
                }
            }
            
            if ($itemInfo.system_requirements.recommended) {
                Write-CCLSHost "`nRecommended:" -ForegroundColor Yellow -Log
                foreach ($prop in $itemInfo.system_requirements.recommended.PSObject.Properties) {
                    Write-CCLSHost "  $($prop.Name): $($prop.Value)" -Log
                }
            }
        }
        
        # REMOVED: The "Press any key to return" prompt that was causing the extra keypress requirement
    }
    catch {
        Write-CCLSHost "An error occurred while processing $itemType information: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# Completely rewritten Search-GameByName function with simplified logic and "get {number}" support
function Search-GameByName {
    param (
        [string]$SearchTerm
    )
    
    # Check if credentials are cached
    if ($null -eq $script:cachedCredentials) {
        Write-CCLSHost "Error: Not logged in. Please restart the application and log in." -ForegroundColor Red -Log
        return $null
    }
    
    try {
        # Set up request parameters with credentials to get the game library
        $params = @{
            Uri = "$cliApiUrl/list.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
            }
        }
        
        Write-CCLSHost "#Fetching game library for search..." -Log -NoConsole
        
        # Fetch library from server
        $response = Invoke-RestMethod @params
        
        # Check if the request was successful
        if (-not $response.success) {
            Write-CCLSHost "Error fetching game library: $($response.message)" -ForegroundColor Red -Log
            return $null
        }
        
        # Create a simple list to hold all items
        $allItems = New-Object System.Collections.ArrayList
        
        # Add games to the list
        if ($response.games) {
            foreach ($game in $response.games) {
                $null = $allItems.Add(@{
                    Name = $game.name
                    Id = $game.id
                    Type = "Game"
                })
            }
        }
        
        # Add bundles to the list
        if ($response.bundles) {
            foreach ($bundle in $response.bundles) {
                $null = $allItems.Add(@{
                    Name = $bundle.name
                    Id = $bundle.id
                    Type = "Bundle"
                })
            }
        }
        
        Write-CCLSHost "#Debug: Total items loaded: $($allItems.Count)" -Log -NoConsole
        
        # Validate search term
        $searchTermLower = $SearchTerm.ToLower().Trim()
        if ($searchTermLower.Length -lt 2) {
            Write-CCLSHost "Search term too short. Please use at least 2 characters." -ForegroundColor Red -Log
            return $null
        }
        
        # Create results list
        $results = New-Object System.Collections.ArrayList
        
        # Search through all items
        foreach ($item in $allItems) {
            $itemNameLower = $item.Name.ToLower().Trim()
            $score = 0
            $matchType = ""
            
            # Simple scoring logic
            if ($itemNameLower -eq $searchTermLower) {
                # Exact match
                $score = 1000
                $matchType = "Exact Match"
            }
            elseif ($itemNameLower.StartsWith($searchTermLower)) {
                # Starts with search term
                $score = 900
                $matchType = "Starts With"
            }
            elseif ($itemNameLower.Contains($searchTermLower)) {
                # Contains search term
                $score = 800
                $matchType = "Contains Term"
            }
            else {
                # Check if all words in search term are present
                $searchWords = $searchTermLower -split '\s+' | Where-Object { $_.Length -gt 0 }
                if ($searchWords.Count -gt 1) {
                    $allWordsFound = $true
                    foreach ($word in $searchWords) {
                        if (-not $itemNameLower.Contains($word)) {
                            $allWordsFound = $false
                            break
                        }
                    }
                    if ($allWordsFound) {
                        $score = 700
                        $matchType = "All Words Match"
                    }
                }
            }
            
            # Add to results if we have a match
            if ($score -gt 0) {
                $null = $results.Add(@{
                    Name = $item.Name
                    Id = $item.Id
                    Type = $item.Type
                    Score = $score
                    MatchType = $matchType
                })
                
                # Debug output for VR HOT specifically
                if ($itemNameLower -eq "vr hot") {
                    Write-CCLSHost "#Debug: Added VR HOT with score $score and match type '$matchType'" -Log -NoConsole
                }
            }
        }
        
        Write-CCLSHost "#Debug: Total matches found: $($results.Count)" -Log -NoConsole
        
        # Check if we have any results
        if ($results.Count -eq 0) {
            Write-CCLSHost "No games or bundles found matching '$SearchTerm'." -ForegroundColor Red -Log
            Write-CCLSHost "Try using different search terms or use 'search library' to see all available items." -ForegroundColor Yellow -Log
            return $null
        }
        
        # Sort results by score (manual sort to avoid PowerShell pipeline issues)
        $sortedResults = New-Object System.Collections.ArrayList
        
        # Convert to array and sort manually
        $resultArray = $results.ToArray()
        for ($i = 0; $i -lt $resultArray.Length - 1; $i++) {
            for ($j = $i + 1; $j -lt $resultArray.Length; $j++) {
                if ($resultArray[$j].Score -gt $resultArray[$i].Score) {
                    $temp = $resultArray[$i]
                    $resultArray[$i] = $resultArray[$j]
                    $resultArray[$j] = $temp
                }
            }
        }
        
        # Take only the top 20 results
        $maxResults = [Math]::Min(20, $resultArray.Length)
        for ($i = 0; $i -lt $maxResults; $i++) {
            $null = $sortedResults.Add($resultArray[$i])
        }
        
        Write-CCLSHost "#Debug: Sorted results count: $($sortedResults.Count)" -Log -NoConsole
        
        # Display search results
        Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
        Write-CCLSHost "Search Results for '$SearchTerm' ($($sortedResults.Count) found)" -ForegroundColor Green -Log
        Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
        
        for ($i = 0; $i -lt $sortedResults.Count; $i++) {
            $result = $sortedResults[$i]
            $displayNumber = $i + 1
            
            # Color code by type
            $typeColor = if ($result.Type -eq "Game") { "White" } else { "Cyan" }
            
            Write-CCLSHost "[$displayNumber] " -ForegroundColor Yellow -NoNewline -Log
            Write-CCLSHost "$($result.Name) " -ForegroundColor $typeColor -NoNewline -Log
            Write-CCLSHost "($($result.Id)) " -ForegroundColor Gray -NoNewline -Log
            Write-CCLSHost "[$($result.Type)]" -ForegroundColor Green -Log
        }
        
        Write-CCLSHost "`nEnter the number to view info, or 'get [number]' to download (1-$($sortedResults.Count)), or press Enter to cancel:" -ForegroundColor Yellow -Log
        
        # Get user input
        while ($true) {
            Write-CCLSHost "Selection: " -ForegroundColor Cyan -NoNewline -Log
            $userInput = Read-Host
            Write-CCLSHost "$userInput" -NoConsole -Log
            
            # Check for empty input (cancel)
            if ([string]::IsNullOrWhiteSpace($userInput)) {
                Write-CCLSHost "Search cancelled." -ForegroundColor Yellow -Log
                return $null
            }
            
            # Check if input matches "get [number]" pattern
            if ($userInput.Trim() -match "^get\s+(\d+)$") {
                $selectedNumber = [int]$matches[1]
                
                # Validate number is in range
                if ($selectedNumber -ge 1 -and $selectedNumber -le $sortedResults.Count) {
                    $selectedItem = $sortedResults[$selectedNumber - 1]
                    Write-CCLSHost "#Calling Get-Game function to install: $($selectedItem.Name) ($($selectedItem.Id))" -NoConsole -Log
                    
                    # Call Get-Game function directly with the selected ID
                    Get-Game -id $selectedItem.Id
                    return $null  # Return null since we're not returning an ID for search
                } else {
                    Write-CCLSHost "Invalid selection. Please enter 'get [number]' where number is between 1 and $($sortedResults.Count)." -ForegroundColor Red -Log
                }
            }
            # Try to parse the input as a number (original behavior)
            else {
                $selectedNumber = 0
                if ([int]::TryParse($userInput.Trim(), [ref]$selectedNumber)) {
                    # Validate number is in range
                    if ($selectedNumber -ge 1 -and $selectedNumber -le $sortedResults.Count) {
                        $selectedItem = $sortedResults[$selectedNumber - 1]
                        Write-CCLSHost "Selected: $($selectedItem.Name) ($($selectedItem.Id))" -ForegroundColor Green -Log
                        return $selectedItem.Id
                    } else {
                        Write-CCLSHost "Invalid selection. Please enter a number between 1 and $($sortedResults.Count)." -ForegroundColor Red -Log
                    }
                } else {
                    Write-CCLSHost "Invalid input. Please enter a number, 'get [number]', or press Enter to cancel." -ForegroundColor Red -Log
                }
            }
        }
    }
    catch {
        Write-CCLSHost "Error during game search: $($_.Exception.Message)" -ForegroundColor Red -Log
        return $null
    }
}

function Resolve-GameNameToId {
    param (
        [string]$GameName
    )
    
    # Check if credentials are cached
    if ($null -eq $script:cachedCredentials) {
        Write-CCLSHost "Error: Not logged in. Please restart the application and log in." -ForegroundColor Red -Log
        return $null
    }
    
    try {
        # Set up request parameters with credentials to get the game library
        $params = @{
            Uri = "$cliApiUrl/list.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
            }
        }
        
        Write-CCLSHost "#Resolving game name '$GameName' to game ID..." -Log -NoConsole
        
        # Fetch library from server
        $response = Invoke-RestMethod @params
        
        # Check if the request was successful
        if (-not $response.success) {
            Write-CCLSHost "Error fetching game library: $($response.message)" -ForegroundColor Red -Log
            return $null
        }
        
        # Search for the game by name (case-insensitive)
        $matchedGame = $null
        $gameNameLower = $GameName.ToLower().Trim()
        
        # First try exact match
        foreach ($game in $response.games) {
            if ($game.name.ToLower().Trim() -eq $gameNameLower) {
                $matchedGame = $game
                break
            }
        }
        
        # If no exact match, try partial match
        if ($null -eq $matchedGame) {
            foreach ($game in $response.games) {
                if ($game.name.ToLower().Contains($gameNameLower)) {
                    if ($null -eq $matchedGame) {
                        $matchedGame = $game
                    } else {
                        # Multiple matches found
                        Write-CCLSHost "Multiple games found matching '$GameName':" -ForegroundColor Yellow -Log
                        
                        # Show all matches
                        $allMatches = @()
                        foreach ($g in $response.games) {
                            if ($g.name.ToLower().Contains($gameNameLower)) {
                                $allMatches += $g
                                Write-CCLSHost "  - $($g.name) ($($g.id))" -ForegroundColor Yellow -Log
                            }
                        }
                        
                        Write-CCLSHost "Please be more specific or use the game ID directly." -ForegroundColor Yellow -Log
                        return $null
                    }
                }
            }
        }
        
        if ($null -ne $matchedGame) {
            Write-CCLSHost "#Found game: '$($matchedGame.name)' with ID: $($matchedGame.id)" -Log -NoConsole
            return $matchedGame.id
        } else {
            Write-CCLSHost "Game '$GameName' not found in the library." -ForegroundColor Red -Log
            Write-CCLSHost "Use 'search library' to see all available games." -ForegroundColor Yellow -Log
            return $null
        }
    }
    catch {
        Write-CCLSHost "Error resolving game name: $($_.Exception.Message)" -ForegroundColor Red -Log
        return $null
    }
}

function Get-Game {
    param (
        [string]$id,
        [switch]$SkipConfirmation
    )

    $settings = Initialize-Settings
    if ($settings.DevMode) {
        Write-CCLSHost "'get' is disabled while in Developer mode" -ForegroundColor Red -Log
        return
    }
    
    if (-not (Assert-DependenciesRequired -CommandName "get")) { return }
    # Check if this is a game name resolution request
    if ($id -eq "game" -and $args.Count -gt 0) {
        # This is actually a game name, not an ID
        $gameName = $args -join " "
        Write-CCLSHost "#Attempting to resolve game name: '$gameName'" -Log -NoConsole
        
        # Resolve the game name to an ID
        $resolvedId = Resolve-GameNameToId -GameName $gameName
        
        if ($null -eq $resolvedId) {
            # Resolution failed, error already displayed
            return
        }
        
        # Update the ID to the resolved one and continue with normal processing
        $id = $resolvedId
        Write-CCLSHost "#Resolved to ID: $id, proceeding with download..." -Log -NoConsole
    }
    
    # Validate ID format - now supports both cg0000 and cb0000 formats
    if ($id -notmatch "^(cg|cb)\d{4}$") {
        Write-CCLSHost "Invalid ID format. Please use format 'cg0000' for games or 'cb0000' for bundles." -ForegroundColor Red -Log
        return
    }
    
    # Check if credentials are cached
    if ($script:cachedCredentials -ne $null -and ($null -eq $script:cachedCredentials.Username -or $null -eq $script:cachedCredentials.Password)) {
        Write-CCLSHost "Error: Not logged in. Please restart the application and log in." -ForegroundColor Red -Log
        return
    }
    
    # Determine if this is a game or bundle
    $isBundle = $id -match "^cb\d{4}$"
    $itemType = if ($isBundle) { "bundle" } else { "game" }
    
    # Check if setup has been completed
    $settings = Initialize-Settings
    if (-not $settings.HasCompletedSetup) {
        Write-CCLSHost "ALERT, you must run the 'setup' command before downloading." -ForegroundColor Red -Log
        return
    }
    
    # Ensure download directories exist
    if (-not (Test-Path $settings.DownloadPath)) {
        try {
            New-Item -ItemType Directory -Path $settings.DownloadPath -Force | Out-Null
        }
        catch {
            Write-CCLSHost "Error creating download directory: $($_.Exception.Message)" -ForegroundColor Red -Log
            return
        }
    }
    
    if (-not (Test-Path $settings.TempDownloadPath)) {
        try {
            New-Item -ItemType Directory -Path $settings.TempDownloadPath -Force | Out-Null
        }
        catch {
            Write-CCLSHost "Error creating temporary download directory: $($_.Exception.Message)" -ForegroundColor Red -Log
            return
        }
    }
    
    # Get game info and download information
    try {
        # First, fetch the detailed information about the game
        $infoParams = @{
            Uri = "$cliApiUrl/search.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
                id = $id
            }
        }
        
        Write-CCLSHost "#Fetching $itemType information..." -Log -NoConsole
        
        try {
            $itemInfo = Invoke-RestMethod @infoParams
            
            if (-not $itemInfo.success) {
                Write-CCLSHost "Error fetching $itemType information: $($itemInfo.message)" -ForegroundColor Red -Log
                return
            }
            
            Write-CCLSHost "#Successfully fetched $itemType information for later use" -Log -NoConsole
        }
        catch {
            Write-CCLSHost "Error fetching $itemType information: $($_.Exception.Message)" -ForegroundColor Red -Log
            return
        }
        
        # Now fetch download information
        $params = @{
            Uri = "$cliApiUrl/get.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
                id = $id
            }
        }
        
        Write-CCLSHost "#Fetching $itemType download information..." -Log -NoConsole
        
        $response = Invoke-RestMethod @params
        
        if (-not $response.success) {
            Write-CCLSHost "Error: $($response.message)" -ForegroundColor Red -Log
            return
        }
        
        $itemName = $response.name
        $itemId = $response.id
        $downloadUrl = $response.download_url
        $itemSize = $response.size
        
        # Create download file name from URL with better handling of complex URLs
        $fileName = $null
        try {
            # Try to extract filename from URL
            $uri = [System.Uri]::new($downloadUrl)
            
            # First try to get from the path
            $pathFileName = Split-Path -Path $uri.AbsolutePath -Leaf
            
            # Check if we have query parameters that might contain the filename
            if ($uri.Query) {
                $queryParams = [System.Web.HttpUtility]::ParseQueryString($uri.Query)
                if ($queryParams["file"]) {
                    $fileName = $queryParams["file"]
                }
            }
            
            # If no filename from query, use the path filename
            if ([string]::IsNullOrEmpty($fileName) -and -not [string]::IsNullOrEmpty($pathFileName)) {
                $fileName = $pathFileName
            }
            
            # If still no filename, generate one
            if ([string]::IsNullOrEmpty($fileName)) {
                $fileName = "$itemId.7z"
            }
            
            # Clean the filename of invalid characters
            $invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
            foreach ($char in $invalidChars) {
                $fileName = $fileName.Replace($char, '_')
            }
            
            # Ensure it has a .7z extension if no extension present
            if (-not [System.IO.Path]::HasExtension($fileName)) {
                $fileName += ".7z"
            }
        }
        catch {
            Write-CCLSHost "#Error parsing download URL for filename: $($_.Exception.Message)" -Log -NoConsole
            $fileName = "$itemId.7z"
        }

        Write-CCLSHost "#Using filename: $fileName" -Log -NoConsole
        
        $downloadPath = Join-Path -Path $settings.TempDownloadPath -ChildPath $fileName

        # === PHASE 1: Check for existing CG file (regardless of folder name) ===
        Write-CCLSHost "#Scanning all folders for existing $itemId.json file..." -Log -NoConsole

        $existingCgFolder = $null
        $allFolders = Get-ChildItem -Path $settings.DownloadPath -Directory -ErrorAction SilentlyContinue

        foreach ($folder in $allFolders) {
            $cgJsonPath = Join-Path -Path $folder.FullName -ChildPath "$itemId.json"
            if (Test-Path $cgJsonPath) {
                $existingCgFolder = $folder.FullName
                Write-CCLSHost "#Found existing $itemId.json in folder: $($folder.Name)" -Log -NoConsole
                break
            }
        }

        $replaceExistingInstallation = $false
        $cgFileBasedReplacement = $false

        if ($existingCgFolder) {
            # Found existing CG file - show warning and ask for replacement
            $folderSize = Get-FolderSize -Path $existingCgFolder
            $formattedSize = Format-Size -Size $folderSize
            $folderName = Split-Path -Path $existingCgFolder -Leaf
            
            Write-CCLSHost "WARNING: $itemType with ID $itemId already exists in installation directory:" -ForegroundColor Yellow -Log
            Write-CCLSHost "  - $existingCgFolder ($formattedSize)" -ForegroundColor Yellow -Log
            
            if (-not $SkipConfirmation) {
                Write-CCLSHost "DO YOU WISH TO REPLACE OLD $($itemType.ToUpper()) FILES WITH NEW ONES? (Y/N)" -ForegroundColor Yellow -Log
                $replaceConfirmation = Read-Host
                Write-CCLSHost "$replaceConfirmation" -NoConsole -Log
                
                if ($replaceConfirmation.ToLower() -ne "y") {
                    Write-CCLSHost "Download cancelled. Existing installation will not be modified." -ForegroundColor Cyan -Log
                    return
                }
                $replaceExistingInstallation = $true
                $cgFileBasedReplacement = $true
            } else {
                Write-CCLSHost "#SkipConfirmation enabled, will replace existing installation" -Log -NoConsole
                $replaceExistingInstallation = $true
                $cgFileBasedReplacement = $true
            }
        } else {
            Write-CCLSHost "#No existing CG file found for $itemId - proceeding with fresh download" -Log -NoConsole
        }

        # Confirm download with user (only if we're not replacing based on CG file)
        if (-not $cgFileBasedReplacement) {
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            Write-CCLSHost "$($itemType.ToUpper()) Download: $itemName ($itemId)" -ForegroundColor Green -Log
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            Write-CCLSHost "Size: $itemSize" -ForegroundColor Yellow -Log

            if (-not $SkipConfirmation) {
                Write-CCLSHost "Do you want to proceed with the download? (Y/N)" -ForegroundColor Yellow -Log
                
                $confirmation = Read-Host
                Write-CCLSHost "$confirmation" -NoConsole -Log
                
                if ($confirmation.ToLower() -ne "y") {
                    Write-CCLSHost "Download cancelled by user." -ForegroundColor Yellow -Log
                    return
                }
            } else {
                Write-CCLSHost "#Automatically proceeding with download (confirmation skipped)..." -ForegroundColor Green -Log -NoConsole
            }
        } else {
            # Show download info for replacement
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            Write-CCLSHost "$($itemType.ToUpper()) Download: $itemName ($itemId)" -ForegroundColor Green -Log
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            Write-CCLSHost "Size: $itemSize" -ForegroundColor Yellow -Log
        }

        # === PHASE 2: Remove existing CG-based installation if needed ===
        if ($cgFileBasedReplacement -and $existingCgFolder) {
            Write-CCLSHost "Removing existing installation before downloading..." -ForegroundColor Cyan -Log
            try {
                if (Test-Path -Path $existingCgFolder) {
                    Remove-Item -Path $existingCgFolder -Recurse -Force
                    Write-CCLSHost "  - Removed: $existingCgFolder" -ForegroundColor Green -Log
                } else {
                    Write-CCLSHost "  - Folder already removed: $existingCgFolder" -ForegroundColor Yellow -Log
                }
            } catch {
                Write-CCLSHost "  - Failed to remove: $existingCgFolder - $($_.Exception.Message)" -ForegroundColor Red -Log
                Write-CCLSHost "Download cancelled due to removal failure." -ForegroundColor Red -Log
                return
            }
        }
        
        # Flag to track if download was successfully completed
        $downloadSuccessful = $false
        
        try {
            # Try to invoke Python to check if it's available
            $pythonVersion = python --version 2>&1
            $pythonAvailable = $true
            Write-CCLSHost "#Python detected: $pythonVersion" -Log -NoConsole
            
            # Determine the actual location of the Python script
            $scriptLocation = if ($PSScriptRoot) {
                # If running from a script, use its location
                $PSScriptRoot
            } else {
                # If running in console, use current directory
                (Get-Location).Path
            }

            $pythonScript = Join-Path -Path $scriptLocation -ChildPath "ccls_downloader.py"

            # Debug the script path
            Write-CCLSHost "#Python script path: $pythonScript" -Log -NoConsole

            # Check if Python downloader exists, download if missing
            if (-not (Test-Path $pythonScript)) {
                try {
                    Write-CCLSHost "#Python downloader not found, downloading..." -Log -NoConsole
                    $downloadUrl = "https://games.ccls.icu/CLI/api/main/ccls_downloader/1.0.0/ccls_downloader.py"
                    $webClient = New-Object System.Net.WebClient
                    $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
                    $webClient.DownloadFile($downloadUrl, $pythonScript)
                    Write-CCLSHost "#Python downloader downloaded successfully" -Log -NoConsole
                } catch {
                    Write-CCLSHost "#Error downloading Python downloader: $($_.Exception.Message)" -Log -NoConsole
                    Write-CCLSHost "Python downloader not available. Please ensure all dependencies are properly installed." -ForegroundColor Red -Log
                    return
                }
            }

            # If we have Python and the downloader script, use it
            if ($pythonAvailable -and (Test-Path $pythonScript)) {
                Write-CCLSHost "#Using Python high-speed downloader" -Log -NoConsole
                
                # Convert the item size to bytes if possible (for progress calculation)
                $sizeInBytes = $null
                if ($itemSize -match "(\d+\.?\d*)\s*(GB|MB|KB|B)") {
                    $value = [double]$matches[1]
                    $unit = $matches[2]
                    
                    switch ($unit) {
                        "GB" { $sizeInBytes = [math]::Round($value * 1GB) }
                        "MB" { $sizeInBytes = [math]::Round($value * 1MB) }
                        "KB" { $sizeInBytes = [math]::Round($value * 1KB) }
                        "B"  { $sizeInBytes = [math]::Round($value) }
                    }
                }
                
                try {
                    # Build the command line with proper quoting
                    $argList = @()
                    $argList += "`"$pythonScript`""
                    $argList += "`"$downloadUrl`""
                    $argList += "`"$downloadPath`""
                    $argList += "`"$itemName`""
                    $argList += "`"$itemId`""
                    
                    if ($sizeInBytes) {
                        $argList += "$sizeInBytes"
                    }
                    
                    $commandLine = "python $($argList -join ' ')"
                    Write-CCLSHost "#Running command: $commandLine" -Log -NoConsole
                    
                    # Run Python as a normal process without redirecting output
                    # This allows it to directly handle console output
                    $process = Start-Process python -ArgumentList $argList -NoNewWindow -PassThru -Wait
                    
                    if ($process.ExitCode -ne 0) {
                        # Check if a partial file exists and delete it
                        if (Test-Path $downloadPath) {
                            Write-CCLSHost "Download was cancelled. Removing partial file..." -ForegroundColor Yellow -Log
                            try {
                                Remove-Item -Path $downloadPath -Force
                                Write-CCLSHost "Partial file removed successfully." -ForegroundColor Yellow -Log
                            } catch {
                                Write-CCLSHost "Note: Could not remove partial file: $($_.Exception.Message)" -ForegroundColor Yellow -Log
                            }
                        } else {
                            Write-CCLSHost "Download was cancelled." -ForegroundColor Yellow -Log
                        }
                        
                        # Return early without attempting extraction
                        return
                    }
                    
                    # If we got here, download was successful
                    $downloadSuccessful = $true
}
                catch {
                    Write-CCLSHost "Error running Python downloader: $($_.Exception.Message)" -ForegroundColor Red -Log
                    Write-CCLSHost "Download failed. Please ensure all dependencies are properly installed." -ForegroundColor Red -Log
                    return
                }
            }
            else {
                Write-CCLSHost "Python downloader not available. Please install required dependencies." -ForegroundColor Red -Log
                return
            }
        } 
        catch {
            Write-CCLSHost "Python not found. Please install required dependencies." -ForegroundColor Red -Log
            return
        }
        
        # === PHASE 3: Post-download extraction and JSON creation ===
        if ($downloadSuccessful) {
            Write-CCLSHost "#Download completed successfully, preparing for extraction..." -Log -NoConsole
            
            Write-CCLSHost "#Starting robust extraction process..." -Log -NoConsole
            
            try {
                # Call the robust extraction function with temporary extraction
                $extractionResult = Start-RobustExtraction -settings $settings -itemId $itemId -SkipConfirmation $SkipConfirmation
                
                # After extraction, save the game info JSON to the correct location
                if ($extractionResult.Success -and $extractionResult.FinalFolder) {
                    # Path for the info JSON file
                    $infoJsonPath = Join-Path -Path $extractionResult.FinalFolder -ChildPath "$itemId.json"
                    
                    # Save item info to JSON file
                    try {
                        # Ensure the directory exists
                        if (-not (Test-Path $extractionResult.FinalFolder)) {
                            New-Item -ItemType Directory -Path $extractionResult.FinalFolder -Force | Out-Null
                        }
                        
                        # Convert and save the JSON with proper formatting
                        $jsonContent = $itemInfo | ConvertTo-Json -Depth 10
                        Set-Content -Path $infoJsonPath -Value $jsonContent -Encoding UTF8 -Force
                        
                        # Verify the file was created successfully
                        if (Test-Path $infoJsonPath) {
                            $fileSize = (Get-Item $infoJsonPath).Length
                            Write-CCLSHost "Game information saved successfully to: $infoJsonPath (Size: $fileSize bytes)" -ForegroundColor Green -Log
                        } else {
                            Write-CCLSHost "Warning: JSON file creation verification failed" -ForegroundColor Yellow -Log
                        }
                        Write-CCLSHost "#Updating library cache after successful game installation..." -Log -NoConsole
                        Update-LibraryCache -Force
                    } catch {
                        Write-CCLSHost "Error saving game information: $($_.Exception.Message)" -ForegroundColor Red -Log
                        Write-CCLSHost "Attempted path: $infoJsonPath" -ForegroundColor Red -Log
                    }
                } else {
                    Write-CCLSHost "Warning: Could not determine final folder location for JSON file creation" -ForegroundColor Yellow -Log
                }
            }
            catch {
                Write-CCLSHost "An error occurred during extraction: $($_.Exception.Message)" -ForegroundColor Red -Log
            }
        }
    }
    catch {
        Write-CCLSHost "An error occurred: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# === ROBUST EXTRACTION FUNCTION WITH FIXED 7-ZIP PATH RESOLUTION ===
function Start-RobustExtraction {
    param (
        [object]$settings,
        [string]$itemId,
        [switch]$SkipConfirmation
    )
    
    $tempDownloadPath = $settings.TempDownloadPath
    $downloadPath = $settings.DownloadPath
    
    # Check if 7-Zip is installed with improved path resolution
    $7zipPath = $null
    $found = $false
    
    # Define all possible 7-Zip locations
    $7zipLocations = @(
        "C:\Program Files\7-Zip\7z.exe",
        "${env:ProgramFiles(x86)}\7-Zip\7z.exe"
    )
    
    # Add the local 7zip installation path with proper script location resolution
    $scriptLocation = if ($PSScriptRoot) {
        $PSScriptRoot
    } else {
        (Get-Location).Path
    }
    $local7zipPath = Join-Path -Path $scriptLocation -ChildPath "7zip\7z.exe"
    $7zipLocations += $local7zipPath
    
    # Check each location
    foreach ($path in $7zipLocations) {
        Write-CCLSHost "#Checking 7-Zip path: $path" -Log -NoConsole
        if (Test-Path -Path $path) {
            $7zipPath = $path
            $found = $true
            Write-CCLSHost "#Found 7-Zip at: $path" -Log -NoConsole
            break
        }
    }
    
    if (-not $found) {
        Write-CCLSHost "Error: 7-Zip is not installed at any expected location." -ForegroundColor Red -Log
        Write-CCLSHost "Checked locations:" -ForegroundColor Red -Log
        foreach ($path in $7zipLocations) {
            Write-CCLSHost "  - $path" -ForegroundColor Red -Log
        }
        Write-CCLSHost "Please install 7-Zip using the 'install 7zip' command." -ForegroundColor Yellow -Log
        Write-CCLSHost "Once you have installed 7zip run 'extract $itemId -y' to extract the game" -ForegroundColor Yellow -Log
        return @{ Success = $false; FinalFolder = $null }
    }
    
    # Get all .7z files in the temp download path
    $7zFiles = Get-ChildItem -Path $tempDownloadPath -Filter "*.7z" -ErrorAction SilentlyContinue
    
    if ($7zFiles.Count -eq 0) {
        Write-CCLSHost "No .7z files found in '$tempDownloadPath'." -ForegroundColor Yellow -Log
        return @{ Success = $false; FinalFolder = $null }
    }
    
    # Generate random 16-bit hash for temporary extraction folder
    $randomHash = -join ((0..15) | ForEach-Object { '{0:X}' -f (Get-Random -Maximum 16) })
    $tempExtractionPath = Join-Path -Path $downloadPath -ChildPath ".temp-$randomHash"
    
    Write-CCLSHost "#Creating temporary extraction directory: $tempExtractionPath" -Log -NoConsole
    Write-CCLSHost "#Using 7-Zip executable: $7zipPath" -Log -NoConsole
    
    try {
        # Create temporary extraction directory
        New-Item -ItemType Directory -Path $tempExtractionPath -Force | Out-Null
        
        $overallSuccess = $true
        $extractedFolders = @()
        
        # Process each .7z file
        foreach ($file in $7zFiles) {
            $filePath = $file.FullName
            
            # Extract the file to temporary directory
            Write-CCLSHost "Extracting: $filePath to temporary location" -ForegroundColor Cyan -Log
            Write-CCLSHost "#Running: `"$7zipPath`" x `"$filePath`" -o`"$tempExtractionPath`" -y" -Log -NoConsole
            
            # Capture and suppress 7-Zip output, only show errors if extraction fails
            try {
                $extractionOutput = & "$7zipPath" x "$filePath" -o"$tempExtractionPath" -y 2>&1
                $extractionSuccess = $?
                
                Write-CCLSHost "#7-Zip exit code: $LASTEXITCODE" -Log -NoConsole
                Write-CCLSHost "#7-Zip output: $($extractionOutput -join '; ')" -Log -NoConsole
                
                if ($extractionSuccess -and $LASTEXITCODE -eq 0) {
                    Write-CCLSHost "Extraction successful. Deleting original file: $filePath" -ForegroundColor Green -Log
                    Remove-Item -Path $filePath -Force
                } else {
                    Write-CCLSHost "Error extracting file. 7-Zip exit code: $LASTEXITCODE" -ForegroundColor Red -Log
                    if ($extractionOutput) {
                        Write-CCLSHost "7-Zip output: $($extractionOutput -join "`n")" -ForegroundColor Red -Log
                    }
                    Remove-Item -Path $filePath -Force
                    $overallSuccess = $false
                }
            } catch {
                Write-CCLSHost "Error running 7-Zip: $($_.Exception.Message)" -ForegroundColor Red -Log
                Write-CCLSHost "7-Zip path used: $7zipPath" -ForegroundColor Red -Log
                Remove-Item -Path $filePath -Force
                $overallSuccess = $false
            }
        }
        
        if (-not $overallSuccess) {
            # Clean up temp directory if extraction failed
            if (Test-Path $tempExtractionPath) {
                Remove-Item -Path $tempExtractionPath -Recurse -Force
            }
            return @{ Success = $false; FinalFolder = $null }
        }
        
        # Get the folders that were extracted to the temporary directory
        $extractedItems = Get-ChildItem -Path $tempExtractionPath -ErrorAction SilentlyContinue
        $extractedFolders = $extractedItems | Where-Object { $_.PSIsContainer }
        
        if ($extractedFolders.Count -eq 0) {
            Write-CCLSHost "No folders found in temporary extraction directory. Looking for files..." -ForegroundColor Yellow -Log
            # If no folders, maybe files were extracted directly
            $extractedFiles = $extractedItems | Where-Object { -not $_.PSIsContainer }
            if ($extractedFiles.Count -gt 0) {
                Write-CCLSHost "Files were extracted directly to temporary directory. Creating container folder..." -ForegroundColor Yellow -Log
                # Move all files to a subfolder named after the item
                $containerFolderName = "ExtractedGame"
                $containerFolderPath = Join-Path -Path $tempExtractionPath -ChildPath $containerFolderName
                New-Item -ItemType Directory -Path $containerFolderPath -Force | Out-Null
                
                foreach ($file in $extractedFiles) {
                    Move-Item -Path $file.FullName -Destination $containerFolderPath -Force
                }
                
                # Update the extracted folders list
                $extractedFolders = @(Get-Item $containerFolderPath)
            }
        }
        
        if ($extractedFolders.Count -eq 0) {
            Write-CCLSHost "No content found after extraction." -ForegroundColor Red -Log
            # Clean up temp directory
            if (Test-Path $tempExtractionPath) {
                Remove-Item -Path $tempExtractionPath -Recurse -Force
            }
            return @{ Success = $false; FinalFolder = $null }
        }
        
        Write-CCLSHost "#Found $($extractedFolders.Count) folder(s) in temporary extraction directory" -Log -NoConsole
        
        # Check for folder name conflicts in the main downloads directory
        $conflictingFolders = @()
        $existingFolders = Get-ChildItem -Path $downloadPath -Directory -ErrorAction SilentlyContinue
        
        foreach ($extractedFolder in $extractedFolders) {
            $extractedFolderName = $extractedFolder.Name
            Write-CCLSHost "#Checking for conflicts with extracted folder: $extractedFolderName" -Log -NoConsole
            
            # Check if a folder with the same name exists in the downloads directory
            $conflictingFolder = $existingFolders | Where-Object { $_.Name -eq $extractedFolderName }
            
            if ($conflictingFolder) {
                # Found a conflict - check if it contains the same CG file
                $conflictCgPath = Join-Path -Path $conflictingFolder.FullName -ChildPath "$itemId.json"
                
                if (-not (Test-Path $conflictCgPath)) {
                    # Conflict found and it doesn't contain our CG file
                    $conflictingFolders += @{
                        Name = $extractedFolderName
                        Path = $conflictingFolder.FullName
                        Size = Get-FolderSize -Path $conflictingFolder.FullName
                    }
                    Write-CCLSHost "#Found conflicting folder without matching CG file: $($conflictingFolder.FullName)" -Log -NoConsole
                } else {
                    Write-CCLSHost "#Found folder with same name but it contains our CG file - this should have been handled in Phase 1" -Log -NoConsole
                }
            }
        }
        
        # Handle conflicts if any were found
        if ($conflictingFolders.Count -gt 0) {
            Write-CCLSHost "Folder name conflict detected!" -ForegroundColor Yellow -Log
            
            foreach ($conflict in $conflictingFolders) {
                $formattedSize = Format-Size -Size $conflict.Size
                Write-CCLSHost "  - Folder '$($conflict.Name)' already exists ($formattedSize)" -ForegroundColor Yellow -Log
            }
            
            $shouldRemoveConflicts = $true
            
            if (-not $SkipConfirmation) {
                Write-CCLSHost "Do you wish to delete these conflicting folders and proceed with installation? (Y/N)" -ForegroundColor Yellow -Log
                $conflictConfirmation = Read-Host
                Write-CCLSHost "$conflictConfirmation" -NoConsole -Log
                
                if ($conflictConfirmation.ToLower() -ne "y") {
                    $shouldRemoveConflicts = $false
                }
            } else {
                Write-CCLSHost "#SkipConfirmation enabled, will remove conflicting folders automatically" -Log -NoConsole
            }
            
            if ($shouldRemoveConflicts) {
                # Remove conflicting folders
                foreach ($conflict in $conflictingFolders) {
                    try {
                        Remove-Item -Path $conflict.Path -Recurse -Force
                        Write-CCLSHost "  - Removed conflicting folder: $($conflict.Path)" -ForegroundColor Green -Log
                    } catch {
                        Write-CCLSHost "  - Failed to remove folder: $($conflict.Path) - $($_.Exception.Message)" -ForegroundColor Red -Log
                        # Clean up temp directory and return failure
                        if (Test-Path $tempExtractionPath) {
                            Remove-Item -Path $tempExtractionPath -Recurse -Force
                        }
                        return @{ Success = $false; FinalFolder = $null }
                    }
                }
            } else {
                Write-CCLSHost "Installation cancelled due to unresolved conflicts." -ForegroundColor Yellow -Log
                # Clean up temp directory
                if (Test-Path $tempExtractionPath) {
                    Remove-Item -Path $tempExtractionPath -Recurse -Force
                }
                return @{ Success = $false; FinalFolder = $null }
            }
        } else {
            Write-CCLSHost "#No folder name conflicts detected" -Log -NoConsole
        }
        
        # Move extracted folders from temporary directory to main downloads directory
        $finalFolder = $null
        foreach ($extractedFolder in $extractedFolders) {
            $sourcePath = $extractedFolder.FullName
            $destinationPath = Join-Path -Path $downloadPath -ChildPath $extractedFolder.Name
            
            try {
                Write-CCLSHost "Moving extracted folder from temporary location to: $destinationPath" -ForegroundColor Cyan -Log
                Move-Item -Path $sourcePath -Destination $destinationPath -Force
                
                # Set the final folder (use the first one if multiple)
                if (-not $finalFolder) {
                    $finalFolder = $destinationPath
                }
            } catch {
                Write-CCLSHost "Failed to move folder: $($_.Exception.Message)" -ForegroundColor Red -Log
                # Try to clean up
                if (Test-Path $tempExtractionPath) {
                    Remove-Item -Path $tempExtractionPath -Recurse -Force
                }
                return @{ Success = $false; FinalFolder = $null }
            }
        }
        
        # Clean up temporary extraction directory
        try {
            if (Test-Path $tempExtractionPath) {
                Remove-Item -Path $tempExtractionPath -Recurse -Force
                Write-CCLSHost "#Cleaned up temporary extraction directory" -Log -NoConsole
            }
        } catch {
            Write-CCLSHost "#Warning: Could not clean up temporary directory: $($_.Exception.Message)" -Log -NoConsole
        }
        
        Write-CCLSHost "#Robust extraction completed successfully." -Log -NoConsole
        
        return @{
            Success = $true
            FinalFolder = $finalFolder
        }
        
    } catch {
        Write-CCLSHost "Error during robust extraction: $($_.Exception.Message)" -ForegroundColor Red -Log
        
        # Clean up temp directory if it exists
        try {
            if (Test-Path $tempExtractionPath) {
                Remove-Item -Path $tempExtractionPath -Recurse -Force
            }
        } catch {
            Write-CCLSHost "#Warning: Could not clean up temporary directory after error" -Log -NoConsole
        }
        
        return @{ Success = $false; FinalFolder = $null }
    }
}

# Function to check system requirements
function Test-SystemRequirements {
    Write-CCLSHost "Checking system requirements:" -ForegroundColor Cyan -Log
    
    # Check for Python
    Write-CCLSHost "Python           : " -NoNewline -Log
    try {
        $pythonResult = python --version 2>&1
        if ($pythonResult -match "Python (\d+\.\d+\.\d+)") {
            $pythonVersion = $matches[1]
            Write-CCLSHost "Installed (v$pythonVersion)" -ForegroundColor Green -Log
            $pythonInstalled = $true
        } else {
            Write-CCLSHost "Not detected" -ForegroundColor Red -Log
            $pythonInstalled = $false
        }
    } catch {
        Write-CCLSHost "Not installed" -ForegroundColor Red -Log
        $pythonInstalled = $false
    }
    
    # Check for Python requests library (only if Python is installed)
    Write-CCLSHost "Python requests  : " -NoNewline -Log
    if ($pythonInstalled) {
        try {
            $requestsCheck = python -c "import requests; print('Installed (v{0})'.format(requests.__version__))" 2>&1
            if ($requestsCheck -match "Installed \(v([\d\.]+)\)") {
                $requestsVersion = $matches[1]
                Write-CCLSHost "Installed (v$requestsVersion)" -ForegroundColor Green -Log
            } else {
                Write-CCLSHost "Not installed" -ForegroundColor Red -Log
            }
        } catch {
            Write-CCLSHost "Not installed" -ForegroundColor Red -Log
        }
    } else {
        Write-CCLSHost "Not applicable (Python not installed)" -ForegroundColor Yellow -Log
    }
    
    # Check for 7-Zip
    Write-CCLSHost "7-Zip            : " -NoNewline -Log
    
    # Check system-wide 7-Zip installation
    $systemPaths = @(
        "C:\Program Files\7-Zip\7z.exe",
        "${env:ProgramFiles(x86)}\7-Zip\7z.exe"
    )
    
    # Check local 7-Zip installation
    $scriptLocation = if ($PSScriptRoot) {
        $PSScriptRoot
    } else {
        (Get-Location).Path
    }
    $localPath = Join-Path -Path $scriptLocation -ChildPath "7zip\7z.exe"
    
    # Combine all paths to check
    $allPaths = $systemPaths + $localPath
    
    $7zipInstalled = $false
    $7zipLocation = ""
    
    foreach ($path in $allPaths) {
        if (Test-Path -Path $path) {
            $7zipInstalled = $true
            $7zipLocation = $path
            break
        }
    }
    
    if ($7zipInstalled) {
        # Get 7-Zip version
        try {
            $versionInfo = Get-Item $7zipLocation | Select-Object -ExpandProperty VersionInfo
            $7zipVersion = $versionInfo.ProductVersion
            Write-CCLSHost "Installed (v$7zipVersion)" -ForegroundColor Green -Log
        } catch {
            Write-CCLSHost "Installed (unknown version)" -ForegroundColor Green -Log
        }
    } else {
        Write-CCLSHost "Not installed" -ForegroundColor Red -Log
    }
    
    # Summary of checks
    Write-CCLSHost "`nSystem Check Summary:" -ForegroundColor Cyan -Log
    if (-not $pythonInstalled) {
        Write-CCLSHost "  - Python is not installed. Install it with 'install python' command" -ForegroundColor Yellow -Log
        Write-CCLSHost "  - Or download it manually from https://www.python.org/downloads/" -ForegroundColor Yellow -Log
        Write-CCLSHost "    Ensure 'Add Python to PATH' is checked in the installer (IMPORTANT)" -ForegroundColor Yellow -Log
        Write-CCLSHost "    Ensure 'pip' is selected in the optional features in the installer (IMPORTANT)" -ForegroundColor Yellow -Log
    }
    
    if ($pythonInstalled -and $requestsCheck -notmatch "Installed") {
        Write-CCLSHost "  - Python 'requests' library is not installed." -ForegroundColor Yellow -Log
        Write-CCLSHost "    Install with: install requests" -ForegroundColor Yellow -Log
    }
    
    if (-not $7zipInstalled) {
        Write-CCLSHost "  - 7-Zip is not installed. 7-Zip is required for extracting downloaded games." -ForegroundColor Yellow -Log
        Write-CCLSHost "    Install with: install 7zip" -ForegroundColor Yellow -Log
    }
    
    if ($pythonInstalled -and $requestsCheck -match "Installed" -and $7zipInstalled) {
        Write-CCLSHost "All system requirements are met. Your system is ready to use all features." -ForegroundColor Green -Log
    }
}

# Get-GamesList function that uses the cached credentials
function Get-GamesList {
    $settings = Initialize-Settings
    if ($settings.DevMode) {
        Write-CCLSHost "'search library' is disabled while in Developer mode" -ForegroundColor Red -Log
        return
    }
    # Check if credentials are cached
    if ($null -eq $script:cachedCredentials) {
        Write-CCLSHost "Error: Not logged in. Please restart the application and log in." -ForegroundColor Red -Log
        return
    }

    if (-not (Assert-DependenciesRequired -CommandName "search library")) { return }
    
    try {
        # Set up request parameters with credentials
        $params = @{
            Uri = "$cliApiUrl/list.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                username = $script:cachedCredentials.Username
                password = $script:cachedCredentials.Password
            }
        }
        
        Write-CCLSHost "#Fetching game and bundle library..." -Log
        
        # Fetch library from server
        try {
            $response = Invoke-RestMethod @params
            
            # Check if the request was successful
            if (-not $response.success) {
                Write-CCLSHost "Error: $($response.message)" -ForegroundColor Red -Log
                return
            }
            
            # Display game list
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            Write-CCLSHost "Game Library - $($response.count) games available" -ForegroundColor Green -Log
            Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
            
            if ($response.count -eq 0) {
                Write-CCLSHost "No games found in the library." -ForegroundColor Yellow -Log
            }
            else {
                # Determine the maximum length for proper formatting
                $maxNameLength = ($response.games | ForEach-Object { $_.name.Length } | Measure-Object -Maximum).Maximum
                $maxIdLength = ($response.games | ForEach-Object { $_.id.Length } | Measure-Object -Maximum).Maximum
                
                # Ensure minimum column widths
                $nameColumnWidth = [Math]::Max($maxNameLength, 30)
                $idColumnWidth = [Math]::Max($maxIdLength, 8)
                
                # Create header
                Write-CCLSHost "$("Game Name".PadRight($nameColumnWidth)) => $("CG Number".PadRight($idColumnWidth))" -ForegroundColor Cyan -Log
                Write-CCLSHost "$("-" * $nameColumnWidth) => $("-" * $idColumnWidth)" -ForegroundColor Cyan -Log
                
                # Print each game with proper formatting
                foreach ($game in $response.games) {
                    Write-CCLSHost "$($game.name.PadRight($nameColumnWidth)) => $($game.id)" -ForegroundColor White -Log
                }
            }
            
            # Display bundle list if any bundles exist
            if ($response.bundle_count -gt 0) {
                Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
                Write-CCLSHost "Bundle Library - $($response.bundle_count) bundles available" -ForegroundColor Green -Log
                Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
                
                # Determine the maximum length for proper formatting
                $maxNameLength = ($response.bundles | ForEach-Object { $_.name.Length } | Measure-Object -Maximum).Maximum
                $maxIdLength = ($response.bundles | ForEach-Object { $_.id.Length } | Measure-Object -Maximum).Maximum
                
                # Ensure minimum column widths
                $nameColumnWidth = [Math]::Max($maxNameLength, 30)
                $idColumnWidth = [Math]::Max($maxIdLength, 8)
                
                # Create header
                Write-CCLSHost "$("Bundle Name".PadRight($nameColumnWidth)) => $("CB Number".PadRight($idColumnWidth))" -ForegroundColor Cyan -Log
                Write-CCLSHost "$("-" * $nameColumnWidth) => $("-" * $idColumnWidth)" -ForegroundColor Cyan -Log
                
                # Print each bundle with proper formatting
                foreach ($bundle in $response.bundles) {
                    Write-CCLSHost "$($bundle.name.PadRight($nameColumnWidth)) => $($bundle.id)" -ForegroundColor White -Log
                }
            }
            
            Write-CCLSHost "`nUse 'search [cgnumber/cbnumber]' to get detailed information about a specific game or bundle." -ForegroundColor Yellow -Log
        }
        catch {
            Write-CCLSHost "Error fetching library: $($_.Exception.Message)" -ForegroundColor Red -Log
        }
    }
    catch {
        Write-CCLSHost "An error occurred while processing library: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

function Clear-ConsoleScreen {
    # Log the clear command
    Write-CCLSHost "#User cleared the console screen" -Log -NoConsole

    # Use the PowerShell Clear-Host cmdlet to clear the console
    Clear-Host
}

# Function to get folder size including subfolders
function Get-FolderSize {
    param (
        [string]$Path
    )
    
    $totalSize = 0
    
    try {
        # Get all files in the folder and subfolders
        $files = Get-ChildItem -Path $Path -Recurse -File -ErrorAction SilentlyContinue
        foreach ($file in $files) {
            $totalSize += $file.Length
        }
    }
    catch {
        Write-CCLSHost "Error calculating folder size: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
    
    return $totalSize
}


# Modified Get-InstalledGames function to use cache
function Get-InstalledGames {
    param (
        [switch]$Detailed
    )
    
    # Ensure cache is initialized
    if (-not $script:libraryCache) {
        Initialize-LibraryCache
    }
    
    # Check if we have any games
    if (-not $script:libraryCache.games -or $script:libraryCache.totalGames -eq 0) {
        Write-CCLSHost "`nNo games found in the library." -ForegroundColor Yellow -Log
        return
    }
    
    # Header
    Write-CCLSHost "`nInstalled Games" -ForegroundColor Green -Log
    Write-CCLSHost "==============" -ForegroundColor Green -Log
    
    # List each game from cache
    foreach ($game in $script:libraryCache.games) {
        if ($Detailed) {
            $version = $game.localVersion
            $isOutdated = $false
            
            # Check for updates if we have credentials and metadata
            if ($null -ne $script:cachedCredentials -and 
                $null -ne $script:cachedCredentials.Username -and 
                $null -ne $script:cachedCredentials.Password -and
                $game.hasMetadata -and $game.gameId -ne "Unknown") {
                
                try {
                    Write-CCLSHost "#Checking for updates for $($game.gameId)..." -Log -NoConsole
                    
                    $params = @{
                        Uri = "$cliApiUrl/search.php"
                        Method = "POST"
                        Headers = @{
                            "User-Agent" = "CCLS-CLI/2.0"
                        }
                        Body = @{
                            username = $script:cachedCredentials.Username
                            password = $script:cachedCredentials.Password
                            id = $game.gameId
                        }
                    }
                    
                    $response = Invoke-RestMethod @params
                    
                    if ($response.success -and $response.version) {
                        $latestVersion = $response.version
                        
                        # Compare versions
                        if ($version -ne $latestVersion -and $version -ne "Unknown" -and $latestVersion -ne "") {
                            $isOutdated = $true
                            Write-CCLSHost "#Game $($game.folderName) is outdated. Local version: $version, Latest: $latestVersion" -Log -NoConsole
                        }
                    }
                } catch {
                    Write-CCLSHost "#Error checking updates for $($game.gameId): $($_.Exception.Message)" -Log -NoConsole
                }
            }
            
            # Display with size and version
            $displayText = "$($game.folderName) - $($game.localSizeFormatted)"
            
            if ($version -ne "Unknown") {
                $displayText += " - Version:$version"
                
                if ($isOutdated) {
                    Write-CCLSHost $displayText -NoNewline -Log
                    Write-CCLSHost " (OUTDATED)" -ForegroundColor Red -Log
                } else {
                    Write-CCLSHost $displayText -Log
                }
            } else {
                Write-CCLSHost $displayText -Log
            }
        } else {
            # Simple list of names
            Write-CCLSHost "$($game.folderName)" -Log
        }
    }
    
    # Show totals if detailed view
    if ($Detailed) {
        Write-CCLSHost "`nTotal size: $($script:libraryCache.totalSizeFormatted)" -ForegroundColor Cyan -Log
        Write-CCLSHost "Games count: $($script:libraryCache.totalGames)" -ForegroundColor Cyan -Log
    }
}

# Modified Get-GameInfoByIdentifier function to use cache
function Get-GameInfoByIdentifier {
    param (
        [string]$Identifier,
        [string]$SearchType = "foldername",
        [switch]$Detailed,
        [switch]$Tree
    )
    
    # Ensure cache is initialized
    if (-not $script:libraryCache) {
        Initialize-LibraryCache
    }
    
    # Find game in cache
    $cachedGame = Get-GameFromCache -Identifier $Identifier -SearchType $SearchType
    
    if (-not $cachedGame) {
        Write-CCLSHost "Could not locate game matching $Identifier" -ForegroundColor Red -Log
        return
    }
    
    # Use cached data
    $gamePath = $cachedGame.localPath
    $gameDisplayName = $cachedGame.folderName
    $size = $cachedGame.localSize
    $sizeFormatted = $cachedGame.localSizeFormatted
    $version = $cachedGame.localVersion
    $gameId = $cachedGame.gameId
    $gameInfo = $null
    $isOutdated = $false
    
    # Load JSON info if available
    if ($cachedGame.hasMetadata -and $gameId -ne "Unknown") {
        try {
            $jsonPath = Join-Path -Path $gamePath -ChildPath "$gameId.json"
            if (Test-Path $jsonPath) {
                $gameInfo = Get-Content -Path $jsonPath -Raw | ConvertFrom-Json
            }
            
            # Check for latest version from server if we have credentials
            if ($null -ne $script:cachedCredentials -and 
                $null -ne $script:cachedCredentials.Username -and 
                $null -ne $script:cachedCredentials.Password) {
                
                try {
                    $params = @{
                        Uri = "$cliApiUrl/search.php"
                        Method = "POST"
                        Headers = @{
                            "User-Agent" = "CCLS-CLI/2.0"
                        }
                        Body = @{
                            username = $script:cachedCredentials.Username
                            password = $script:cachedCredentials.Password
                            id = $gameId
                        }
                    }
                    
                    Write-CCLSHost "#Checking for updates for $gameId..." -Log -NoConsole
                    
                    $response = Invoke-RestMethod @params
                    
                    if ($response.success -and $response.version) {
                        $latestVersion = $response.version
                        
                        # Compare versions
                        if ($version -ne $latestVersion -and $version -ne "Unknown" -and $latestVersion -ne "") {
                            $isOutdated = $true
                            Write-CCLSHost "#Game $gameDisplayName is outdated. Local version: $version, Latest: $latestVersion" -Log -NoConsole
                        }
                    }
                } catch {
                    Write-CCLSHost "#Error checking updates: $($_.Exception.Message)" -Log -NoConsole
                }
            }
        } catch {
            Write-CCLSHost "#Error reading game info: $($_.Exception.Message)" -Log -NoConsole
        }
    }
    
    # Header
    Write-CCLSHost "`nGame Information: $gameDisplayName" -ForegroundColor Green -Log
    Write-CCLSHost "=======================" -ForegroundColor Green -Log
    
    # Always show basic information (using cached data)
    Write-CCLSHost "Size: $sizeFormatted" -Log
    
    if ($gameId -and $gameId -ne "Unknown") {
        Write-CCLSHost "ID: $gameId" -Log
    }
    
    # Display version with outdated tag if needed
    if ($version -ne "Unknown") {
        Write-CCLSHost "Version: $version" -NoNewline -Log
        if ($isOutdated) {
            Write-CCLSHost " (OUTDATED)" -ForegroundColor Red -Log
        } else {
            Write-CCLSHost "" -Log  # Just to add a newline
        }
    }
    
    # Show detailed information if -d switch is specified
    if ($Detailed -and $gameInfo) {
        # Show description if available
        if ($gameInfo.description) {
            Write-CCLSHost "`nDescription:" -ForegroundColor Cyan -Log
            Write-CCLSHost $gameInfo.description -Log
        }
        
        # Show safety info if available
        if ($gameInfo.safety_score -or $gameInfo.safety_level) {
            Write-CCLSHost "`nSafety:" -ForegroundColor Cyan -Log
            if ($gameInfo.safety_score) { Write-CCLSHost "Score: $($gameInfo.safety_score)" -Log }
            if ($gameInfo.safety_level) { Write-CCLSHost "Level: $($gameInfo.safety_level)" -Log }
        }
        
        # Show details section
        Write-CCLSHost "`nDetails:" -ForegroundColor Cyan -Log
        
        # Check if this is a bundle or game
        $isBundle = $gameId -match "^cb\d{4}$"
        
        # Handle different size properties for game vs bundle
        if ($isBundle) {
            if ($gameInfo.zipped_size) { Write-CCLSHost "Zipped Size: $($gameInfo.zipped_size)" -Log }
            if ($gameInfo.unzipped_size) { Write-CCLSHost "Unzipped Size: $($gameInfo.unzipped_size)" -Log }
            if ($gameInfo.games_included) { Write-CCLSHost "Games Included: $($gameInfo.games_included)" -Log }
        } else {
            if ($gameInfo.size) { Write-CCLSHost "Size: $($gameInfo.size)" -Log }
        }
        
        # Show availability info if any is available
        if (($gameInfo.online -and $gameInfo.online -ne "") -or 
            ($gameInfo.steam -and $gameInfo.steam -ne "") -or 
            ($gameInfo.epic -and $gameInfo.epic -ne "")) {
            Write-CCLSHost "`nAvailability:" -ForegroundColor Cyan -Log
            if ($gameInfo.online -and $gameInfo.online -ne "") { Write-CCLSHost "Online: $($gameInfo.online)" -Log }
            if ($gameInfo.steam -and $gameInfo.steam -ne "") { Write-CCLSHost "Steam: $($gameInfo.steam)" -Log }
            if ($gameInfo.epic -and $gameInfo.epic -ne "") { Write-CCLSHost "Epic: $($gameInfo.epic)" -Log }
        }
        
        # Show false antivirus information if available
        if ($gameInfo.false_av -and $gameInfo.false_av -ne "") {
            Write-CCLSHost "`nNote: " -ForegroundColor Yellow -NoNewline -Log
            Write-CCLSHost "This game may trigger false antivirus alerts: $($gameInfo.false_av)" -Log
        }
        
        # Show system requirements if available
        if ($gameInfo.system_requirements) {
            Write-CCLSHost "`nSystem Requirements:" -ForegroundColor Cyan -Log
            
            if ($gameInfo.system_requirements.minimum) {
                Write-CCLSHost "Minimum:" -ForegroundColor Yellow -Log
                foreach ($prop in $gameInfo.system_requirements.minimum.PSObject.Properties) {
                    Write-CCLSHost "  $($prop.Name): $($prop.Value)" -Log
                }
            }
            
            if ($gameInfo.system_requirements.recommended) {
                Write-CCLSHost "`nRecommended:" -ForegroundColor Yellow -Log
                foreach ($prop in $gameInfo.system_requirements.recommended.PSObject.Properties) {
                    Write-CCLSHost "  $($prop.Name): $($prop.Value)" -Log
                }
            }
        }
    }
    
    # If tree view is requested, show file tree (this still needs to scan the actual directory)
    if ($Tree) {
        Write-CCLSHost "`nFile Structure (full directory tree):" -ForegroundColor Cyan -Log
        $fileTree = Get-FullFileTree -Path $gamePath
        foreach ($line in $fileTree) {
            Write-CCLSHost $line -Log
        }
    }
}

# Modified Browse-Games function to use cache
function Browse-Games {
    $settings = Initialize-Settings
    if ($settings.DevMode) {
        Write-CCLSHost "'browse' is disabled while in Developer mode" -ForegroundColor Red -Log
        return
    }
    
    # Ensure cache is initialized
    if (-not $script:libraryCache) {
        Initialize-LibraryCache
    }
    
    # Check if we have any games
    if (-not $script:libraryCache.games -or $script:libraryCache.totalGames -eq 0) {
        Write-CCLSHost "No games are currently installed." -ForegroundColor Yellow -Log
        return
    }
    
    Write-CCLSHost "#Using library cache for browse display" -Log -NoConsole
    
    # Create sorted games list from cache
    $sortedGames = @()
    
    foreach ($cachedGame in $script:libraryCache.games) {
        $gameEntry = @{
            Name = $cachedGame.gameName
            Id = $cachedGame.gameId
            Type = if ($cachedGame.hasMetadata) { "Game" } else { "Unknown" }
            LocalVersion = $cachedGame.localVersion
            LocalSize = $cachedGame.localSizeFormatted
            HasMetadata = $cachedGame.hasMetadata
            IsOutdated = $false
            OnlineVersion = "Unknown"
            LocalPath = $cachedGame.localPath
        }
        
        # Check for updates if we have credentials and metadata
        if ($null -ne $script:cachedCredentials -and 
            $null -ne $script:cachedCredentials.Username -and 
            $null -ne $script:cachedCredentials.Password -and
            $cachedGame.hasMetadata -and $cachedGame.gameId -ne "Unknown") {
            
            try {
                Write-CCLSHost "#Checking online version for $($cachedGame.gameId)..." -Log -NoConsole
                
                $infoParams = @{
                    Uri = "$cliApiUrl/search.php"
                    Method = "POST"
                    Headers = @{
                        "User-Agent" = "CCLS-CLI/2.0"
                    }
                    Body = @{
                        username = $script:cachedCredentials.Username
                        password = $script:cachedCredentials.Password
                        id = $cachedGame.gameId
                    }
                }
                
                $onlineGameInfo = Invoke-RestMethod @infoParams
                if ($onlineGameInfo.success -and $onlineGameInfo.version) {
                    $gameEntry.OnlineVersion = $onlineGameInfo.version
                    
                    # Compare versions to determine if outdated
                    if ($gameEntry.LocalVersion -ne "Unknown" -and 
                        $gameEntry.OnlineVersion -ne "Unknown" -and
                        $gameEntry.OnlineVersion -ne "" -and
                        $gameEntry.LocalVersion -ne $gameEntry.OnlineVersion) {
                        $gameEntry.IsOutdated = $true
                        Write-CCLSHost "#Game $($gameEntry.Name) is outdated. Local: $($gameEntry.LocalVersion), Online: $($gameEntry.OnlineVersion)" -Log -NoConsole
                    }
                }
            } catch {
                Write-CCLSHost "#Error checking online version for $($cachedGame.gameId): $($_.Exception.Message)" -Log -NoConsole
            }
        }
        
        $sortedGames += $gameEntry
    }
    
    # Sort games: Games with metadata first, then by name
    if ($sortedGames.Count -eq 1) {
        $sortedGames = $sortedGames
    } else {
        $sortedGames = $sortedGames | Sort-Object @{Expression={-($_.HasMetadata -as [int])}}, Name
    }
    
    # Ensure we have an array even with one item
    if ($sortedGames -isnot [array]) {
        $sortedGames = @($sortedGames)
    }
    
    # Display the browse interface (rest of the function remains the same)
    Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
    Write-CCLSHost "Installed Games Browser - $($sortedGames.Count) games installed" -ForegroundColor Green -Log
    Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
    
    # [Rest of the Browse-Games function continues as before with the same display logic]
    # The display code remains identical, it just uses the cached data instead of scanning folders
    
    # Calculate column widths for formatting - handle single game case
    $maxNameLength = 30
    $maxIdLength = 15
    $maxLocalSizeLength = 15
    $maxLocalVersionLength = 20
    $maxTypeLength = 12
    
    # Only calculate max lengths if we have games
    if ($sortedGames.Count -gt 0) {
        $nameArray = @()
        $idArray = @()
        $sizeArray = @()
        $versionArray = @()
        $typeArray = @()
        
        foreach ($game in $sortedGames) {
            $nameArray += $game.Name.Length
            $idArray += ("ID: " + $game.Id).Length
            $sizeArray += ("Size: " + $game.LocalSize).Length
            $versionText = "Version: " + $game.LocalVersion
            if ($game.IsOutdated) {
                $versionText += " (OUTDATED)"
            }
            $versionArray += $versionText.Length
            
            if ($game.HasMetadata) {
                $gameType = "Official"
            } else {
                $gameType = "Unknown"
            }
            $typeArray += ("Type: " + $gameType).Length
        }
        
        if ($nameArray.Count -gt 0) {
            $maxNameLength = [Math]::Max(($nameArray | Measure-Object -Maximum).Maximum, 30)
            $maxIdLength = [Math]::Max(($idArray | Measure-Object -Maximum).Maximum, 15)
            $maxLocalSizeLength = [Math]::Max(($sizeArray | Measure-Object -Maximum).Maximum, 15)
            $maxLocalVersionLength = [Math]::Max(($versionArray | Measure-Object -Maximum).Maximum, 20)
            $maxTypeLength = [Math]::Max(($typeArray | Measure-Object -Maximum).Maximum, 12)
        }
    }
    
    # Ensure minimum widths
    $nameWidth = $maxNameLength
    $idWidth = $maxIdLength
    $localSizeWidth = $maxLocalSizeLength
    $localVersionWidth = $maxLocalVersionLength
    $typeWidth = $maxTypeLength
    
    # Display header
    Write-CCLSHost ("#".PadRight(3) + 
                  "Game Name".PadRight($nameWidth + 2) + 
                  "ID".PadRight($idWidth + 2) + 
                  "Size".PadRight($localSizeWidth + 2) + 
                  "Version".PadRight($localVersionWidth + 2) + 
                  "Type") -ForegroundColor Cyan -Log
    
    Write-CCLSHost ("-" * 3 + " " + 
                  "-" * ($nameWidth + 1) + " " + 
                  "-" * ($idWidth + 1) + " " + 
                  "-" * ($localSizeWidth + 1) + " " + 
                  "-" * ($localVersionWidth + 1) + " " + 
                  "-" * ($typeWidth)) -ForegroundColor Cyan -Log
    
    # Display each game
    for ($i = 0; $i -lt $sortedGames.Count; $i++) {
        $game = $sortedGames[$i]
        $displayNumber = $i + 1
        
        # Determine type and base color
        if ($game.HasMetadata) {
            $gameType = "Official"
            $gameColor = "Green"
        } else {
            $gameType = "Unknown"
            $gameColor = "Gray"
        }
        
        # Format the values with prefixes
        $gameName = if ($game.Name) { $game.Name } else { "Unknown" }
        $gameIdDisplay = if ($game.Id -and $game.Id -ne "Unknown") { "ID: " + $game.Id } else { "ID: Unknown" }
        $gameSizeDisplay = if ($game.LocalSize) { "Size: " + $game.LocalSize } else { "Size: Unknown" }
        $gameVersionDisplay = if ($game.LocalVersion) { "Version: " + $game.LocalVersion } else { "Version: Unknown" }
        $gameTypeDisplay = "Type: $gameType"
        
        # Start building the line
        $line = "$displayNumber".PadRight(3) + "$gameName".PadRight($nameWidth + 2)

        # Display game number, name, ID, and size normally
        Write-CCLSHost $line -ForegroundColor $gameColor -NoNewline -Log
        Write-CCLSHost $gameIdDisplay.PadRight($idWidth + 2) -ForegroundColor White -NoNewline -Log
        Write-CCLSHost $gameSizeDisplay.PadRight($localSizeWidth + 2) -ForegroundColor White -NoNewline -Log
        
        # Handle version with special coloring for outdated games
        if ($game.IsOutdated) {
            $outdatedVersionDisplay = $gameVersionDisplay + " (OUTDATED)"
            Write-CCLSHost $outdatedVersionDisplay.PadRight($localVersionWidth + 2) -ForegroundColor Red -NoNewline -Log
        } else {
            if ($game.LocalVersion -eq "Unknown") {
                Write-CCLSHost $gameVersionDisplay.PadRight($localVersionWidth + 2) -ForegroundColor Gray -NoNewline -Log
            } else {
                Write-CCLSHost $gameVersionDisplay.PadRight($localVersionWidth + 2) -ForegroundColor Green -NoNewline -Log
            }
        }
        
        # Display type
        Write-CCLSHost $gameTypeDisplay -ForegroundColor $gameColor -Log
    }
    
    # Show command help
    Write-CCLSHost "`nCommands:" -ForegroundColor Yellow -Log
    Write-CCLSHost "  view [number]     - View detailed information about a game" -ForegroundColor Cyan -Log
    Write-CCLSHost "  del [number]      - Delete an installed game" -ForegroundColor Cyan -Log
    Write-CCLSHost "  update [number]   - Check for updates and update if available" -ForegroundColor Cyan -Log
    Write-CCLSHost "  refresh [number]  - Refresh online info for a specific game" -ForegroundColor Cyan -Log
    Write-CCLSHost "  [number]          - Same as 'view [number]'" -ForegroundColor Cyan -Log
    Write-CCLSHost "  Press Enter to return to main menu" -ForegroundColor Cyan -Log
    
    # Command input loop (rest of Browse-Games remains the same)
    while ($true) {
        Write-CCLSHost "`nBrowse> " -ForegroundColor Yellow -NoNewline -Log
        $userInput = Read-Host
        Write-CCLSHost "$userInput" -NoConsole -Log
        
        # Check for empty input (exit)
        if ([string]::IsNullOrWhiteSpace($userInput)) {
            Write-CCLSHost "Returning to main menu..." -ForegroundColor Green -Log
            break
        }
        
        # Parse the command
        $inputParts = $userInput.Trim().Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)
        
        if ($inputParts.Count -eq 0) {
            continue
        }
        
        $command = $inputParts[0].ToLower()
        $gameNumber = $null
        
        # Handle different command formats
        if ($inputParts.Count -eq 1) {
            # Single input - could be just a number or a command
            if ([int]::TryParse($command, [ref]$gameNumber)) {
                # It's just a number, treat as 'view'
                $command = "view"
            } else {
                Write-CCLSHost "Invalid command. Please specify a game number (e.g., 'view 1', 'del 1', 'update 1')." -ForegroundColor Red -Log
                continue
            }
        }
        elseif ($inputParts.Count -eq 2) {
            # Command with number
            if (-not [int]::TryParse($inputParts[1], [ref]$gameNumber)) {
                Write-CCLSHost "Invalid game number. Please enter a valid number." -ForegroundColor Red -Log
                continue
            }
        }
        else {
            Write-CCLSHost "Invalid command format. Use: [command] [number]" -ForegroundColor Red -Log
            continue
        }
        
        # Validate game number
        if ($gameNumber -lt 1 -or $gameNumber -gt $sortedGames.Count) {
            Write-CCLSHost "Invalid game number. Please enter a number between 1 and $($sortedGames.Count)." -ForegroundColor Red -Log
            continue
        }
        
        # Get the selected game
        $selectedGame = $sortedGames[$gameNumber - 1]
        
        # Execute the command
        switch ($command) {
            "view" {
                Write-CCLSHost "`nViewing details for: $($selectedGame.Name)" -ForegroundColor Green -Log
                
                if ($selectedGame.HasMetadata) {
                    # Call the existing list function with detailed view using ID
                    Get-GameInfoByIdentifier -Identifier $selectedGame.Id -SearchType "id" -Detailed
                } else {
                    # Manual installation - show basic info using cache data
                    Write-CCLSHost "`nGame Information: $($selectedGame.Name)" -ForegroundColor Green -Log
                    Write-CCLSHost "=======================" -ForegroundColor Green -Log
                    Write-CCLSHost "Size: $($selectedGame.LocalSize)" -Log
                    Write-CCLSHost "Location: $($selectedGame.LocalPath)" -Log
                    Write-CCLSHost "Type: Unknown Installation (No game metadata found)" -Log
                    Write-CCLSHost "`nNote: This appears to be a manually installed game without CCLS metadata." -ForegroundColor Yellow -Log
                    Write-CCLSHost "You can view the file structure but cannot update or get detailed info." -ForegroundColor Yellow -Log
                }
            }
            
            "del" {
                Write-CCLSHost "`nDeleting: $($selectedGame.Name)" -ForegroundColor Red -Log
                
                if ($selectedGame.HasMetadata) {
                    # Use ID-based deletion for games with metadata
                    Remove-Game -Identifier $selectedGame.Id -SearchType "id"
                } else {
                    # Use folder-based deletion for manual installations
                    Remove-Game -Identifier $selectedGame.Name -SearchType "gamedir"
                }
                
                Write-CCLSHost "`nReturning to browse menu..." -ForegroundColor Cyan -Log
                break  # Exit the browse loop to refresh the list
            }
            
            "update" {
                if (-not $selectedGame.HasMetadata) {
                    Write-CCLSHost "Cannot update '$($selectedGame.Name)' - this appears to be an unknown installation." -ForegroundColor Yellow -Log
                    Write-CCLSHost "Unknown installations cannot be automatically updated." -ForegroundColor Yellow -Log
                    continue
                }
                
                # Check if credentials are available for online check
                if ($null -eq $script:cachedCredentials) {
                    Write-CCLSHost "Cannot check for updates - not logged in." -ForegroundColor Red -Log
                    continue
                }
                
                Write-CCLSHost "`nChecking for updates for: $($selectedGame.Name) ($($selectedGame.Id))" -ForegroundColor Cyan -Log
                
                # Use the existing search function to get online version
                try {
                    $infoParams = @{
                        Uri = "$cliApiUrl/search.php"
                        Method = "POST"
                        Headers = @{
                            "User-Agent" = "CCLS-CLI/2.0"
                        }
                        Body = @{
                            username = $script:cachedCredentials.Username
                            password = $script:cachedCredentials.Password
                            id = $selectedGame.Id
                        }
                    }
                    
                    $onlineGameInfo = Invoke-RestMethod @infoParams
                    if ($onlineGameInfo.success) {
                        $onlineVersion = if ($onlineGameInfo.version -and $onlineGameInfo.version -ne "") { $onlineGameInfo.version } else { "Unknown" }
                        
                        Write-CCLSHost "Local version: $($selectedGame.LocalVersion)" -ForegroundColor Yellow -Log
                        Write-CCLSHost "Online version: $onlineVersion" -ForegroundColor Yellow -Log
                        
                        if ($selectedGame.LocalVersion -ne "Unknown" -and $onlineVersion -ne "Unknown") {
                            if ($selectedGame.LocalVersion -eq $onlineVersion) {
                                Write-CCLSHost "Game is already up to date!" -ForegroundColor Green -Log
                            } else {
                                Write-CCLSHost "Update available! Starting download..." -ForegroundColor Cyan -Log
                                # Call the existing get function to update
                                Get-Game -id $selectedGame.Id
                            }
                        } else {
                            Write-CCLSHost "Cannot determine if update is needed due to unknown version information." -ForegroundColor Yellow -Log
                            Write-CCLSHost "Would you like to re-download anyway? (Y/N)" -ForegroundColor Yellow -Log
                            $confirmation = Read-Host
                            Write-CCLSHost "$confirmation" -NoConsole -Log
                            
                            if ($confirmation.ToLower() -eq "y") {
                                Get-Game -id $selectedGame.Id
                            }
                        }
                    } else {
                        Write-CCLSHost "Error checking for updates: $($onlineGameInfo.message)" -ForegroundColor Red -Log
                    }
                }
                catch {
                    Write-CCLSHost "Error checking for updates: $($_.Exception.Message)" -ForegroundColor Red -Log
                }
                
                Write-CCLSHost "`nReturning to browse menu..." -ForegroundColor Cyan -Log
            }
            
            "refresh" {
                if (-not $selectedGame.HasMetadata) {
                    Write-CCLSHost "Cannot refresh info for '$($selectedGame.Name)' - this is an unknown installation." -ForegroundColor Yellow -Log
                    continue
                }
                
                # Check if credentials are available
                if ($null -eq $script:cachedCredentials) {
                    Write-CCLSHost "Cannot refresh info - not logged in." -ForegroundColor Red -Log
                    continue
                }
                
                Write-CCLSHost "`nRefreshing info for: $($selectedGame.Name) ($($selectedGame.Id))" -ForegroundColor Cyan -Log
                
                # Call the existing search function to show current online info
                Search-Game -id $selectedGame.Id
            }
            
            default {
                Write-CCLSHost "Unknown command '$command'. Available commands: view, del, update, refresh" -ForegroundColor Red -Log
            }
        }
    }
}


function Get-FullFileTree {
    param (
        [string]$Path,
        [string]$Indent = ""
    )
    
    $output = @()
    
    try {
        # Get items in the current directory
        $items = Get-ChildItem -Path $Path -ErrorAction SilentlyContinue
        
        foreach ($item in $items) {
            if ($item.PSIsContainer) {
                # It's a directory
                $output += "$Indent|- $($item.Name) (folder)"
                
                # Recursively get all subdirectories with no depth limit
                $childOutput = Get-FullFileTree -Path $item.FullName -Indent "$Indent|   "
                if ($childOutput) {
                    $output += $childOutput
                }
            }
            else {
                # It's a file
                $sizeFormatted = Format-Size -Size $item.Length
                $output += "$Indent|- $($item.Name) ($sizeFormatted)"
            }
        }
    }
    catch {
        $output += "$Indent Error accessing path: $($_.Exception.Message)"
    }
    
    return $output
}

# Modified Remove-Game function to update cache after deletion
function Remove-Game {
    param (
        [string]$Identifier,
        [string]$SearchType = "gamedir",
        [switch]$Force
    )
    
    # Get settings to find download directory
    $settings = Initialize-Settings
    $downloadPath = $settings.DownloadPath
    
    $gamePath = $null
    $gameDisplayName = $null
    
    # Find the game based on search type
    switch ($SearchType.ToLower()) {
        "id" {
            # Search by game ID (e.g., cg0055)
            Write-CCLSHost "#Searching for game with ID: $Identifier" -Log -NoConsole
            
            # Validate ID format
            if ($Identifier -notmatch "^(cg|cb)\d{4}$") {
                Write-CCLSHost "Invalid ID format. Please use format 'cg0000' for games or 'cb0000' for bundles." -ForegroundColor Red -Log
                return
            }
            
            # Look for JSON file with this ID in any game folder
            $foundFolder = $null
            $allFolders = Get-ChildItem -Path $downloadPath -Directory -ErrorAction SilentlyContinue
            
            foreach ($folder in $allFolders) {
                $jsonFile = Join-Path -Path $folder.FullName -ChildPath "$Identifier.json"
                if (Test-Path $jsonFile) {
                    $foundFolder = $folder.FullName
                    $gameDisplayName = $folder.Name
                    break
                }
            }
            
            if ($null -eq $foundFolder) {
                Write-CCLSHost "Game '$Identifier' not found in library" -ForegroundColor Red -Log
                return
            }
            
            $gamePath = $foundFolder
        }
        
        "game" {
            # Search by game name using fuzzy matching (same as get game command)
            Write-CCLSHost "#Searching for game with name: $Identifier" -Log -NoConsole
            
            # Use the same game resolution logic as the get command
            $resolvedId = Resolve-GameNameToId -GameName $Identifier
            
            if ($null -eq $resolvedId) {
                Write-CCLSHost "Game '$Identifier' not found in library" -ForegroundColor Red -Log
                return
            }
            
            # Now find the folder containing this ID
            $allFolders = Get-ChildItem -Path $downloadPath -Directory -ErrorAction SilentlyContinue
            $foundFolder = $null
            
            foreach ($folder in $allFolders) {
                $jsonFile = Join-Path -Path $folder.FullName -ChildPath "$resolvedId.json"
                if (Test-Path $jsonFile) {
                    $foundFolder = $folder.FullName
                    $gameDisplayName = $folder.Name
                    break
                }
            }
            
            if ($null -eq $foundFolder) {
                Write-CCLSHost "Game '$Identifier' not found in library" -ForegroundColor Red -Log
                return
            }
            
            $gamePath = $foundFolder
        }
        
        "gamedir" {
            # Search by game folder name (original behavior)
            Write-CCLSHost "#Searching for game folder: $Identifier" -Log -NoConsole
            
            $gamePath = Join-Path -Path $downloadPath -ChildPath $Identifier
            $gameDisplayName = $Identifier
            
            # Check if game folder exists
            if (-not (Test-Path $gamePath)) {
                Write-CCLSHost "Game '$Identifier' not found in library" -ForegroundColor Red -Log
                return
            }
        }
        
        default {
            Write-CCLSHost "Invalid search type specified." -ForegroundColor Red -Log
            return
        }
    }
    
    # Get game size for informational purposes (from cache if available, otherwise calculate)
    $size = 0
    $sizeFormatted = "Unknown"
    
    if ($script:libraryCache) {
        $cachedGame = Get-GameFromCache -Identifier $gameDisplayName -SearchType "foldername"
        if ($cachedGame) {
            $size = $cachedGame.localSize
            $sizeFormatted = $cachedGame.localSizeFormatted
        }
    }
    
    if ($sizeFormatted -eq "Unknown") {
        $size = Get-FolderSize -Path $gamePath
        $sizeFormatted = Format-Size -Size $size
    }
    
    # Try to get additional game info from JSON file if available
    $gameInfo = $null
    $gameId = $null
    $gameName = $null
    
    try {
        # Look for any JSON file with game ID pattern
        $jsonFiles = Get-ChildItem -Path $gamePath -Filter "*.json" | Where-Object { $_.Name -match "^c[gb]\d{4}\.json$" }
        
        if ($jsonFiles.Count -gt 0) {
            $jsonFile = $jsonFiles[0]
            $gameId = [System.IO.Path]::GetFileNameWithoutExtension($jsonFile.Name)
            $gameInfo = Get-Content -Path $jsonFile.FullName -Raw | ConvertFrom-Json
            $gameName = $gameInfo.name
        }
    } catch {
        Write-CCLSHost "#Could not read game info from JSON file" -Log -NoConsole
    }
    
    # Provide information about what will be deleted
    Write-CCLSHost "`nGame Deletion Confirmation" -ForegroundColor Red -Log
    Write-CCLSHost "=========================" -ForegroundColor Red -Log
    
    if ($gameName -and $gameId) {
        Write-CCLSHost "Game: $gameName ($gameId)" -Log
    } else {
        Write-CCLSHost "Game: $gameDisplayName" -Log
    }
    
    Write-CCLSHost "Location: $gamePath" -Log
    Write-CCLSHost "Size: $sizeFormatted" -Log
    
    # Show additional game info if available
    if ($gameInfo) {
        if ($gameInfo.version -and $gameInfo.version -ne "") {
            Write-CCLSHost "Version: $($gameInfo.version)" -Log
        }
        if ($gameInfo.size -and $gameInfo.size -ne "") {
            Write-CCLSHost "Original Size: $($gameInfo.size)" -Log
        }
    }
    
    # If not forced, prompt for confirmation
    if (-not $Force) {
        Write-CCLSHost "`nWARNING: This will permanently delete the game and all its files!" -ForegroundColor Yellow -Log
        
        $displayName = if ($gameName) { $gameName } else { $gameDisplayName }
        Write-CCLSHost "Are you sure you want to delete '$displayName'? (Y/N)" -ForegroundColor Yellow -Log
        
        $confirmation = Read-Host
        Write-CCLSHost "$confirmation" -NoConsole -Log
        
        if ($confirmation.ToLower() -ne "y") {
            Write-CCLSHost "Deletion cancelled." -ForegroundColor Green -Log
            return
        }
    } else {
        Write-CCLSHost "#Force deletion enabled, skipping confirmation" -Log -NoConsole
    }
    
    # Proceed with deletion
    try {
        # Use Remove-Item with -Recurse to delete the game folder and all contents
        Remove-Item -Path $gamePath -Recurse -Force
        
        $displayName = if ($gameName) { $gameName } else { $gameDisplayName }
        Write-CCLSHost "`nGame '$displayName' has been successfully deleted." -ForegroundColor Green -Log
        Write-CCLSHost "Freed up $sizeFormatted of disk space." -ForegroundColor Green -Log
        
        # Update library cache after successful deletion
        Write-CCLSHost "#Updating library cache after game deletion..." -Log -NoConsole
        Update-LibraryCache -Force
        
    }
    catch {
        Write-CCLSHost "Error deleting game: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

function Test-VersionUpdate {
    # Current version - update this when releasing new versions
    $currentVersion = "2.1.5"  # Updated to match your current version
    
    # Check for oversight system override first
    if ($script:oversightData -and $script:oversightData.version_override) {
        Write-CCLSHost "#Oversight version override active" -Log -NoConsole
        $latestVersion = $script:oversightData.version_override.version
        
        # Create and return result
        $result = [PSCustomObject]@{
            CurrentVersion = $currentVersion
            LatestVersion = $latestVersion
            IsLatest = ($currentVersion -eq $latestVersion)
            OverrideDownloadUrl = $script:oversightData.version_override.download_link
            IsOverride = $true
        }
        
        return $result
    }
    
    try {
        # Get the latest version from the server - Updated for v2.0 API structure
        $params = @{
            Uri = "$baseUrl/CLI/api/2.0/latest/latest.txt"
            Method = "GET"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
        }
        
        Write-CCLSHost "#Checking for updates..." -Log -NoConsole
        $latestVersion = Invoke-RestMethod @params
        
        # Strip any whitespace or newlines
        $latestVersion = $latestVersion.Trim()
        
        # Create and return result without displaying it
        $result = [PSCustomObject]@{
            CurrentVersion = $currentVersion
            LatestVersion = $latestVersion
            IsLatest = ($currentVersion -eq $latestVersion)
            IsOverride = $false
        }
        
        # Use Write-Output to return without console display
        return $result
    }
    catch {
        Write-CCLSHost "#Error checking for updates: $($_.Exception.Message)" -Log -NoConsole
        
        # Create and return result without displaying it
        $result = [PSCustomObject]@{
            CurrentVersion = $currentVersion
            LatestVersion = $null
            IsLatest = $true  # Assume latest if can't check to avoid unnecessary alerts
            IsOverride = $false
        }
        
        return $result
    }
}

function Show-VersionWarningIfNeeded {
    param (
        [switch]$ForceCheck
    )
    
    # Don't show warnings if we're in DevMode
    $settings = Initialize-Settings
    if ($settings.DevMode) {
        return
    }
    
    # Only check version if oversight data is available or if forced
    if ($script:oversightData -or $ForceCheck) {
        $versionInfo = Test-VersionUpdate
        
        if (-not $versionInfo.IsLatest -and $versionInfo.LatestVersion) {
            Write-CCLSHost "ALERT, you are running $($versionInfo.CurrentVersion) run 'update' command to update to latest version $($versionInfo.LatestVersion)" -ForegroundColor Red -Log
        }
    }
}

function Get-OversightData {
    param (
        [string]$Username,
        [string]$CurrentVersion
    )
    
    try {
        # Set up request parameters for oversight API
        $params = @{
            Uri = "$baseUrl/CLI/api/oversight/oversight.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                action = "get_oversight_data"
                username = $Username
                current_version = $CurrentVersion
            }
        }
        
        Write-CCLSHost "#Checking oversight system..." -Log -NoConsole
        
        # Fetch oversight data from server
        $response = Invoke-RestMethod @params
        
        # Check if the request was successful
        if ($response.success) {
            Write-CCLSHost "#Oversight system data retrieved successfully" -Log -NoConsole
            return $response
        } else {
            Write-CCLSHost "#Oversight system returned error: $($response.error)" -Log -NoConsole
            return $null
        }
    }
    catch {
        Write-CCLSHost "#Oversight system not available or error occurred: $($_.Exception.Message)" -Log -NoConsole
        return $null
    }
}

function Convert-HexToConsoleColor {
    param (
        [string]$HexColor
    )
    
    # Remove # if present
    $HexColor = $HexColor.TrimStart('#')
    
    # Convert to RGB values
    try {
        $r = [Convert]::ToInt32($HexColor.Substring(0, 2), 16)
        $g = [Convert]::ToInt32($HexColor.Substring(2, 2), 16)
        $b = [Convert]::ToInt32($HexColor.Substring(4, 2), 16)
        
        # Map to closest console color (simplified mapping)
        if ($r -gt 200 -and $g -lt 100 -and $b -lt 100) { return "Red" }
        elseif ($r -lt 100 -and $g -gt 200 -and $b -lt 100) { return "Green" }
        elseif ($r -lt 100 -and $g -lt 100 -and $b -gt 200) { return "Blue" }
        elseif ($r -gt 200 -and $g -gt 200 -and $b -lt 100) { return "Yellow" }
        elseif ($r -gt 200 -and $g -lt 100 -and $b -gt 200) { return "Magenta" }
        elseif ($r -lt 100 -and $g -gt 200 -and $b -gt 200) { return "Cyan" }
        elseif ($r -gt 150 -and $g -gt 150 -and $b -gt 150) { return "White" }
        elseif ($r -lt 100 -and $g -lt 100 -and $b -lt 100) { return "DarkGray" }
        else { return "Gray" }
    }
    catch {
        return "White"  # Default fallback color
    }
}

function Initialize-UserLogging {
    param (
        [string]$Username
    )
    
    if ($script:userLoggingEnabled) {
        try {
            # Create the session filename
            $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
            $script:userLoggingSessionFile = "ccls_session_$timestamp.log"
            
            # Get user ID from oversight response
            if ($script:oversightData -and $script:oversightData.user_logging -and $script:oversightData.user_id) {
                $script:userLoggingUserId = $script:oversightData.user_id
                
                Write-CCLSHost "#User logging enabled for user: $Username (ID: $($script:userLoggingUserId))" -Log -NoConsole
                
                # Send initial log entry to server
                Send-LogToServer -LogEntry "CCLS Games CLI Session started at $(Get-Date) for user $Username (ID: $($script:userLoggingUserId))"
            } else {
                Write-CCLSHost "#User logging not available - no user ID received" -Log -NoConsole
                $script:userLoggingEnabled = $false
            }
        }
        catch {
            Write-CCLSHost "#Error setting up user logging: $($_.Exception.Message)" -Log -NoConsole
            $script:userLoggingEnabled = $false
        }
    }
}

function Send-LogToServer {
    param (
        [string]$LogEntry
    )
    
    if (-not $script:userLoggingEnabled -or -not $script:userLoggingUserId -or -not $script:userLoggingSessionFile) {
        return
    }
    
    try {
        $params = @{
            Uri = "$baseUrl/CLI/api/oversight/oversight.php"
            Method = "POST"
            Headers = @{
                "User-Agent" = "CCLS-CLI/2.0"
            }
            Body = @{
                action = "log_entry"
                user_id = $script:userLoggingUserId
                log_entry = $LogEntry
                session_file = $script:userLoggingSessionFile
            }
        }
        
        # Send asynchronously to avoid slowing down the CLI
        $null = Start-Job -ScriptBlock {
            param($requestParams)
            try {
                Invoke-RestMethod @requestParams
            } catch {
                # Silently fail to avoid disrupting the main application
            }
        } -ArgumentList $params
    }
    catch {
        # Silently fail to avoid disrupting the main application
    }
}

function Update-CliTool {
    Write-CCLSHost "Checking for updates..." -ForegroundColor Cyan -Log
    
    # Get version information and suppress automatic output
    $versionInfo = Test-VersionUpdate
    $currentVersion = $versionInfo.CurrentVersion
    $latestVersion = $versionInfo.LatestVersion
    
    # Make sure we have valid version information
    if ([string]::IsNullOrWhiteSpace($latestVersion)) {
        Write-CCLSHost "Error: Couldn't retrieve latest version information." -ForegroundColor Red -Log
        Write-CCLSHost "Please check your internet connection and try again later." -ForegroundColor Red -Log
        return
    }
    
    # Compare versions
    if ($versionInfo.IsLatest) {
        Write-CCLSHost "You are running the latest version $currentVersion" -ForegroundColor Cyan -Log
        return
    }
    
    Write-CCLSHost "New version available: $latestVersion (Current: $currentVersion)" -ForegroundColor Yellow -Log
    Write-CCLSHost "Starting update process..." -ForegroundColor Cyan -Log
    
    try {
        # Determine the current script directory
        $scriptLocation = if ($PSScriptRoot) {
            # If running from a script, use its location
            $PSScriptRoot
        } else {
            # If running in console, use current directory
            (Get-Location).Path
        }
        
        # Get the current script path
        $scriptPath = Join-Path -Path $scriptLocation -ChildPath "CLI.ps1"
        
        # Set the update path
        $updatePath = Join-Path -Path $scriptLocation -ChildPath "update.ps1"
        
        # Create backups directory if it doesn't exist
        $backupsFolder = Join-Path -Path $scriptLocation -ChildPath "backups"
        if (-not (Test-Path $backupsFolder)) {
            New-Item -Path $backupsFolder -ItemType Directory -Force | Out-Null
            Write-CCLSHost "#Created backups directory at $backupsFolder" -Log
        }
        
        # Check if oversight has a version override
        if ($versionInfo.OverrideDownloadUrl) {
            $cliDownloadUrl = $versionInfo.OverrideDownloadUrl
            Write-CCLSHost "#Using oversight override download URL" -Log -NoConsole
        } else {
            $cliDownloadUrl = "$baseUrl/CLI/api/2.0/latest/CLI.ps1"
        }
        
        Write-CCLSHost "Downloading update to $updatePath..." -ForegroundColor Cyan -Log
        
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
        $webClient.DownloadFile($cliDownloadUrl, $updatePath)
        
        Write-CCLSHost "Download completed." -ForegroundColor Green -Log
        
        # Ask for confirmation
        Write-CCLSHost "Are you sure you want to update to version $latestVersion? (Y/N)" -ForegroundColor Yellow -Log
        $confirmation = Read-Host
        Write-CCLSHost "$confirmation" -NoConsole -Log
        
        if ($confirmation.ToLower() -ne "y") {
            Write-CCLSHost "Update cancelled." -ForegroundColor Yellow -Log
            # Clean up downloaded file
            if (Test-Path $updatePath) {
                Remove-Item -Path $updatePath -Force
            }
            return
        }
        
        # Create a backup with timestamp in the backups folder
        $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
        $backupFileName = "CLI_v$($currentVersion)_$timestamp.ps1.bak"
        $backupPath = Join-Path -Path $backupsFolder -ChildPath $backupFileName
        
        Copy-Item -Path $scriptPath -Destination $backupPath -Force
        Write-CCLSHost "Created backup at $backupPath" -ForegroundColor Cyan -Log
        
        # Read the new CLI content
        $newContent = Get-Content -Path $updatePath -Raw
        
        # Replace the current script with the new content
        Set-Content -Path $scriptPath -Value $newContent -Force
        
        # Clean up the update file
        Remove-Item -Path $updatePath -Force
        
        Write-CCLSHost "Successfully downloaded version $latestVersion" -ForegroundColor Green -Log
        
        # Log the update completion
        if ($script:userLoggingEnabled) {
            Send-LogToServer -LogEntry "CLI Tool updated from version $currentVersion to $latestVersion"
        }
        
        Write-CCLSHost "Restart the program to apply update." -ForegroundColor Yellow -Log
        
        # Exit the tool to allow the user to restart with the new version
        Write-CCLSHost "Press any key to exit..." -ForegroundColor Cyan -Log
        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        Exit
    }
    catch {
        Write-CCLSHost "Error during update process: $($_.Exception.Message)" -ForegroundColor Red -Log
        Write-CCLSHost "Update failed. Please try again later." -ForegroundColor Red -Log
        
        # Log the update failure
        if ($script:userLoggingEnabled) {
            Send-LogToServer -LogEntry "CLI Tool update failed: $($_.Exception.Message)"
        }
    }
}

function Show-Version {
    # Get version information using the existing Test-VersionUpdate function
    $versionInfo = Test-VersionUpdate
    $currentVersion = $versionInfo.CurrentVersion
    $latestVersion = $versionInfo.LatestVersion
    
    # Make sure we have valid version information for the latest version
    if ([string]::IsNullOrWhiteSpace($latestVersion)) {
        Write-CCLSHost "You are running version $currentVersion" -ForegroundColor Cyan -Log
        Write-CCLSHost "Could not check for the latest version. Please check your internet connection." -ForegroundColor Yellow -Log
        return
    }
    
    # Compare versions
    if ($versionInfo.IsLatest) {
        # Running the latest version
        Write-CCLSHost "You are running the latest version $currentVersion" -ForegroundColor Cyan -Log
    } else {
        # Running an outdated version
        $overrideText = if ($versionInfo.IsOverride) { " (oversight override)" } else { "" }
        Write-CCLSHost "You are running version " -ForegroundColor Red -NoNewline -Log
        Write-CCLSHost "$currentVersion" -ForegroundColor Cyan -NoNewline -Log
        Write-CCLSHost ", latest version " -ForegroundColor Red -NoNewline -Log
        Write-CCLSHost "$latestVersion" -ForegroundColor Cyan -NoNewline -Log
        Write-CCLSHost "$overrideText run 'update' to install the latest version." -ForegroundColor Red -Log
    }
}

# Function to get all log files sorted by newest to oldest
function Get-LogFiles {
    param (
        [int]$Limit = -1  # -1 means no limit, show all
    )
    
    try {
        # Get all log files from the logs folder
        $logFiles = Get-ChildItem -Path $logsFolder -Filter "*.log" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending
        
        if ($logFiles.Count -eq 0) {
            return @()
        }
        
        # Apply limit if specified
        if ($Limit -gt 0 -and $Limit -lt $logFiles.Count) {
            $logFiles = $logFiles | Select-Object -First $Limit
        }
        
        return $logFiles
    }
    catch {
        Write-CCLSHost "Error retrieving log files: $($_.Exception.Message)" -ForegroundColor Red -Log
        return @()
    }
}

# Function to display log file contents
function Show-LogFile {
    param (
        [string]$LogFileName
    )
    
    $logPath = Join-Path -Path $logsFolder -ChildPath $LogFileName
    
    # Check if log file exists
    if (-not (Test-Path $logPath)) {
        Write-CCLSHost "Log file '$LogFileName' not found." -ForegroundColor Red -Log
        return
    }
    
    try {
        # Read file content line by line to avoid issues with large files
        $logContent = Get-Content -Path $logPath -ErrorAction Stop
        
        Write-CCLSHost "`nLog File Contents: $LogFileName" -ForegroundColor Green -Log
        Write-CCLSHost "================================" -ForegroundColor Green -Log
        
        # Display content line by line to avoid output issues
        foreach ($line in $logContent) {
            Write-CCLSHost $line -Log
        }
        
        Write-CCLSHost "`n[End of log file]" -ForegroundColor Gray -Log
    }
    catch {
        Write-CCLSHost "Error reading log file: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# Function to delete a log file
function Remove-LogFile {
    param (
        [string]$LogFileName,
        [switch]$Force
    )
    
    $logPath = Join-Path -Path $logsFolder -ChildPath $LogFileName
    
    # Check if log file exists
    if (-not (Test-Path $logPath)) {
        Write-CCLSHost "Log file '$LogFileName' not found." -ForegroundColor Red -Log
        return
    }
    
    # Get file info for confirmation
    $fileInfo = Get-Item $logPath
    $fileSize = Format-Size -Size $fileInfo.Length
    $lastModified = $fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
    
    Write-CCLSHost "`nLog File Deletion Confirmation" -ForegroundColor Red -Log
    Write-CCLSHost "=============================" -ForegroundColor Red -Log
    Write-CCLSHost "File: $LogFileName" -Log
    Write-CCLSHost "Size: $fileSize" -Log
    Write-CCLSHost "Last Modified: $lastModified" -Log
    
    if (-not $Force) {
        Write-CCLSHost "`nAre you sure you want to delete this log file? (Y/N)" -ForegroundColor Yellow -Log
        $confirmation = Read-Host
        Write-CCLSHost "$confirmation" -NoConsole -Log
        
        if ($confirmation.ToLower() -ne "y") {
            Write-CCLSHost "Deletion cancelled." -ForegroundColor Green -Log
            return
        }
    } else {
        Write-CCLSHost "#Force deletion enabled, skipping confirmation" -Log -NoConsole
    }
    
    try {
        Remove-Item -Path $logPath -Force
        Write-CCLSHost "`nLog file '$LogFileName' has been successfully deleted." -ForegroundColor Green -Log
    }
    catch {
        Write-CCLSHost "Error deleting log file: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# Function to open a log file with default system application
function Open-LogFile {
    param (
        [string]$LogFileName
    )
    
    $logPath = Join-Path -Path $logsFolder -ChildPath $LogFileName
    
    # Check if log file exists
    if (-not (Test-Path $logPath)) {
        Write-CCLSHost "Log file '$LogFileName' not found." -ForegroundColor Red -Log
        return
    }
    
    try {
        Write-CCLSHost "Opening log file '$LogFileName' with default application..." -ForegroundColor Cyan -Log
        Start-Process -FilePath $logPath
        Write-CCLSHost "Log file opened successfully." -ForegroundColor Green -Log
    }
    catch {
        Write-CCLSHost "Error opening log file: $($_.Exception.Message)" -ForegroundColor Red -Log
        Write-CCLSHost "The system may not have a default application associated with .log files." -ForegroundColor Yellow -Log
    }
}

# Main log list browser function
function Show-LogBrowser {
    param (
        [int]$Limit = -1
    )
    
    # Get log files
    $logFiles = Get-LogFiles -Limit $Limit
    
    if ($logFiles.Count -eq 0) {
        Write-CCLSHost "No log files found in $logsFolder" -ForegroundColor Yellow -Log
        return
    }
    
    # Display header
    $limitText = if ($Limit -gt 0) { " (showing latest $Limit)" } else { "" }
    Write-CCLSHost "`n==========================================================" -ForegroundColor DarkGray -Log
    Write-CCLSHost "Log Files Browser - $($logFiles.Count) files found$limitText" -ForegroundColor Green -Log
    Write-CCLSHost "==========================================================" -ForegroundColor DarkGray -Log
    
    # Calculate column widths
    $maxNameLength = ($logFiles | ForEach-Object { $_.Name.Length } | Measure-Object -Maximum).Maximum
    $nameWidth = [Math]::Max($maxNameLength, 30)
    
    # Display header row
    Write-CCLSHost ("#".PadRight(3) + 
                  "File Name".PadRight($nameWidth + 2) + 
                  "Size".PadRight(12) + 
                  "Last Modified".PadRight(20)) -ForegroundColor Cyan -Log
    
    Write-CCLSHost ("-" * 3 + " " + 
                  "-" * ($nameWidth + 1) + " " + 
                  "-" * 11 + " " + 
                  "-" * 19) -ForegroundColor Cyan -Log
    
    # Display each log file
    for ($i = 0; $i -lt $logFiles.Count; $i++) {
        $logFile = $logFiles[$i]
        $displayNumber = $i + 1
        $fileSize = Format-Size -Size $logFile.Length
        $lastModified = $logFile.LastWriteTime.ToString("yyyy-MM-dd HH:mm")
        
        # Format the line
        $line = "$displayNumber".PadRight(3) + 
               "$($logFile.Name)".PadRight($nameWidth + 2) + 
               "$fileSize".PadRight(12) + 
               $lastModified
        
        # Color code based on age (newer files are greener)
        $age = (Get-Date) - $logFile.LastWriteTime
        if ($age.TotalDays -lt 1) {
            $color = "Green"
        } elseif ($age.TotalDays -lt 7) {
            $color = "Yellow"
        } else {
            $color = "White"
        }
        
        Write-CCLSHost $line -ForegroundColor $color -Log
    }
    
    # Show command help
    Write-CCLSHost "`nCommands:" -ForegroundColor Yellow -Log
    Write-CCLSHost "  view [number/filename] - View contents of a log file" -ForegroundColor Cyan -Log
    Write-CCLSHost "  del [number/filename]  - Delete a log file" -ForegroundColor Cyan -Log
    Write-CCLSHost "  open [number/filename] - Open log file with default application" -ForegroundColor Cyan -Log
    Write-CCLSHost "  [number]               - Same as 'view [number]'" -ForegroundColor Cyan -Log
    Write-CCLSHost "  Press Enter to return to main menu" -ForegroundColor Cyan -Log
    
    # Command input loop
    while ($true) {
        Write-CCLSHost "`nLogs> " -ForegroundColor Yellow -NoNewline -Log
        $userInput = Read-Host
        Write-CCLSHost "$userInput" -NoConsole -Log
        
        # Check for empty input (exit)
        if ([string]::IsNullOrWhiteSpace($userInput)) {
            Write-CCLSHost "Returning to main menu..." -ForegroundColor Green -Log
            break
        }
        
        # Parse the command
        $inputParts = $userInput.Trim().Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)
        
        if ($inputParts.Count -eq 0) {
            continue
        }
        
        $command = $inputParts[0].ToLower()
        $fileIdentifier = $null
        
        # Handle different command formats
        if ($inputParts.Count -eq 1) {
            # Single input - could be just a number or a command
            $fileNumber = 0
            if ([int]::TryParse($command, [ref]$fileNumber)) {
                # It's just a number, treat as 'view'
                $fileIdentifier = $fileNumber
                $command = "view"
            } else {
                Write-CCLSHost "Invalid command. Please specify a file number or filename (e.g., 'view 1', 'del mylog.log', 'open 3')." -ForegroundColor Red -Log
                continue
            }
        }
        elseif ($inputParts.Count -eq 2) {
            # Command with identifier
            $fileIdentifier = $inputParts[1]
        }
        else {
            Write-CCLSHost "Invalid command format. Use: [command] [number/filename]" -ForegroundColor Red -Log
            continue
        }
        
        # Resolve file identifier to actual log file
        $selectedLogFile = $null
        $fileNumber = 0
        
        if ([int]::TryParse($fileIdentifier, [ref]$fileNumber)) {
            # It's a number
            if ($fileNumber -lt 1 -or $fileNumber -gt $logFiles.Count) {
                Write-CCLSHost "Invalid file number. Please enter a number between 1 and $($logFiles.Count)." -ForegroundColor Red -Log
                continue
            }
            $selectedLogFile = $logFiles[$fileNumber - 1]
        } else {
            # It's a filename
            $selectedLogFile = $logFiles | Where-Object { $_.Name -eq $fileIdentifier }
            if (-not $selectedLogFile) {
                Write-CCLSHost "Log file '$fileIdentifier' not found in the current list." -ForegroundColor Red -Log
                continue
            }
        }
        
        # Execute the command
        switch ($command) {
            "view" {
                Write-CCLSHost "`nViewing log file: $($selectedLogFile.Name)" -ForegroundColor Green -Log
                Show-LogFile -LogFileName $selectedLogFile.Name
            }
            
            "del" {
                Write-CCLSHost "`nDeleting log file: $($selectedLogFile.Name)" -ForegroundColor Red -Log
                Remove-LogFile -LogFileName $selectedLogFile.Name
                
                # Refresh the log files list after deletion
                Write-CCLSHost "`nRefreshing log list..." -ForegroundColor Cyan -Log
                $logFiles = Get-LogFiles -Limit $Limit
                
                if ($logFiles.Count -eq 0) {
                    Write-CCLSHost "No log files remaining. Returning to main menu..." -ForegroundColor Yellow -Log
                    break
                }
            }
            
            "open" {
                Write-CCLSHost "`nOpening log file: $($selectedLogFile.Name)" -ForegroundColor Cyan -Log
                Open-LogFile -LogFileName $selectedLogFile.Name
            }
            
            default {
                Write-CCLSHost "Unknown command '$command'. Available commands: view, del, open" -ForegroundColor Red -Log
            }
        }
    }
}

# Function to display a specific version's changelog
function Show-Changelog {
    param (
        [string]$Version
    )
    
    # Handle special cases first
    if ($Version -eq "list") {
        # List all available changelogs using the dedicated endpoint
        try {
            $webClient = New-Object System.Net.WebClient
            $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
            $listUrl = "$baseUrl/CLI/api/2.0/changelogs_list.php"
            $response = $webClient.DownloadString($listUrl)
            
            # Parse the JSON response
            $changelogVersions = $response | ConvertFrom-Json
            
            Write-CCLSHost "Available Changelogs:" -ForegroundColor Green -Log
            Write-CCLSHost "-------------------" -ForegroundColor Green -Log
            
            if ($changelogVersions.Count -eq 0) {
                Write-CCLSHost "No changelogs available." -ForegroundColor Yellow -Log
            } else {
                foreach ($version in $changelogVersions) {
                    Write-CCLSHost "  $version" -Log
                }
            }
            
            Write-CCLSHost "`nUse 'changelog [version]' to view a specific changelog" -ForegroundColor Cyan -Log
        }
        catch {
            Write-CCLSHost "Error retrieving changelog list" -ForegroundColor Red -Log
        }
        return
    }
    elseif ($Version -eq "latest") {
        # Show the latest version's changelog
        try {
            # Use existing Test-VersionUpdate function to get latest version
            $versionInfo = Test-VersionUpdate
            $latestVersion = $versionInfo.LatestVersion
            
            if ([string]::IsNullOrWhiteSpace($latestVersion)) {
                Write-CCLSHost "Error: Unable to determine latest version." -ForegroundColor Red -Log
                return
            }
            
            # Now get that version's changelog
            Show-Changelog -Version $latestVersion
        }
        catch {
            Write-CCLSHost "Error retrieving latest version information" -ForegroundColor Red -Log
        }
        return
    }
    
    # For a specific version, first check if it exists in the available versions
    try {
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "CCLS-CLI/2.0")
        
        # Get the list of available versions first - Updated for v2.0 API structure
        $listUrl = "$baseUrl/CLI/api/2.0/changelogs_list.php"
        $response = $webClient.DownloadString($listUrl)
        $availableVersions = $response | ConvertFrom-Json
        
        # Check if the requested version is available
        if ($availableVersions -contains $Version) {
            # Version exists, fetch and display the changelog - Updated for v2.0 API structure
            $changelogUrl = "https://games.ccls.icu/CLI/changelogs/$Version.txt"
            $changelogContent = $webClient.DownloadString($changelogUrl)
            
            Write-CCLSHost "Changelog for Version $Version" -ForegroundColor Green -Log
            Write-CCLSHost "------------------------" -ForegroundColor Green -Log
            Write-CCLSHost $changelogContent -Log
        } else {
            # Version doesn't exist in the available versions
            Write-CCLSHost "Unknown version. Type 'changelog list' for a list of all versions." -ForegroundColor Red -Log
        }
    }
    catch {
        Write-CCLSHost "Unknown version. Type 'changelog list' for a list of all versions." -ForegroundColor Red -Log
    }
}

function Refresh-LibraryCache {
    Write-CCLSHost "Manually refreshing library cache..." -ForegroundColor Cyan -Log
    
    try {
        Update-LibraryCache -Force
        Write-CCLSHost "Library cache refreshed successfully!" -ForegroundColor Green -Log
        
        if ($script:libraryCache) {
            Write-CCLSHost "Total games: $($script:libraryCache.totalGames)" -ForegroundColor Cyan -Log
            Write-CCLSHost "Total size: $($script:libraryCache.totalSizeFormatted)" -ForegroundColor Cyan -Log
            Write-CCLSHost "Last updated: $($script:libraryCache.lastUpdated)" -ForegroundColor Cyan -Log
        }
    } catch {
        Write-CCLSHost "Error refreshing library cache: $($_.Exception.Message)" -ForegroundColor Red -Log
    }
}

# Fixed Start-CommandInterface function (complete replacement)
function Start-CommandInterface($username) {
    $running = $true

    while ($running) {
        Write-CCLSHost "CCLS>" -ForegroundColor Yellow -NoNewline -Log
        $command = Read-Host
        Write-CCLSHost "$command" -NoConsole -Log
        
        # Check for empty input - if empty, just continue to next prompt
        if ([string]::IsNullOrWhiteSpace($command)) {
            continue
        }

        # Flag to track if a help command was processed
        $helpProcessed = $false
        
        # Flag to track if a base command was processed
        $baseCommandProcessed = $false
        
        # Process help commands first
        switch -Regex ($command.ToLower()) {
            # Add comprehensive help command
            "^help\s+(-list-all|-a)$" {
                Write-CCLSHost "CCLS Games CLI - Complete Command Reference" -ForegroundColor Green -Log
                Write-CCLSHost "=======================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nBASIC COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "-------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "help                                - Display basic help information" -Log
                Write-CCLSHost "help -list-all, help -a             - Display this complete command reference" -Log
                Write-CCLSHost "clear, cls                          - Clear the console screen" -Log
                Write-CCLSHost "exit, quit                          - Exit the application" -Log
                Write-CCLSHost "logout                              - Log out and exit" -Log
                Write-CCLSHost "forget                              - Remove stored credentials" -Log
                
                Write-CCLSHost "`nSYSTEM COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "--------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "setup                               - Configure download directories" -Log
                Write-CCLSHost "check                               - Check system requirements" -Log
                Write-CCLSHost "version                             - Display current version information" -Log
                Write-CCLSHost "update                              - Update the CLI tool to the latest version" -Log
                
                Write-CCLSHost "`nINSTALL COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "---------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "install help                        - Show install command help" -Log
                Write-CCLSHost "install 7zip                        - Install 7-Zip utility for extraction" -Log
                Write-CCLSHost "install python                      - Download and install Python" -Log
                Write-CCLSHost "install requests                    - Install Python requests library" -Log
                
                Write-CCLSHost "`nSEARCH COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "--------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "search help                         - Show search command help" -Log
                Write-CCLSHost "search [id]                         - Search for game or bundle information by ID" -Log
                Write-CCLSHost "search game [game]                  - Search for games matching your search term" -Log
                Write-CCLSHost "search library, search lib          - List all available games and bundles" -Log
                
                Write-CCLSHost "`nDOWNLOAD COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "----------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "get help                            - Show get command help" -Log
                Write-CCLSHost "get [id]                            - Download and install a game or bundle by ID" -Log
                Write-CCLSHost "get game [name]                     - Download and install a game by name" -Log
                Write-CCLSHost "get [id] -y                         - Download game by ID without confirmation prompt" -Log
                Write-CCLSHost "get game [name] -y                  - Download game by name without confirmation" -Log
                
                Write-CCLSHost "`nLIST COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "list help                           - Show list command help" -Log
                Write-CCLSHost "list all                            - List all installed games" -Log
                Write-CCLSHost "list all -d                         - List all installed games with details" -Log
                Write-CCLSHost "list [id]                           - Show info about a specific game by ID" -Log
                Write-CCLSHost "list [folder name]                  - Show info about a specific game by folder name" -Log
                Write-CCLSHost "list game [name]                    - Show info about a specific game by name" -Log
                Write-CCLSHost "list gamedir [folder name]          - Show info about a specific game by folder name" -Log
                Write-CCLSHost "list [id] -d                        - Show detailed info about a specific game by ID" -Log
                Write-CCLSHost "list [folder name] -d               - Show detailed info about a specific game by folder name" -Log
                Write-CCLSHost "list game [name] -d                 - Show detailed info about a specific game by name" -Log
                Write-CCLSHost "list gamedir [folder name] -d       - Show detailed info about a specific game by folder name" -Log
                Write-CCLSHost "list [id] -tree                     - View full file tree of a specific game by ID" -Log
                Write-CCLSHost "list [folder name] -tree            - View full file tree of a specific game by folder name" -Log
                Write-CCLSHost "list game [name] -tree              - View full file tree of a specific game by name" -Log
                Write-CCLSHost "list gamedir [folder name] -tree    - View full file tree of a specific game by folder name" -Log
                Write-CCLSHost "list [id] -tree -d                  - View full file tree and detailed info of a specific game by ID" -Log
                Write-CCLSHost "list [folder name] -tree -d         - View full file tree and detailed info of a specific game by folder name" -Log
                Write-CCLSHost "list game [name] -tree -d           - View full file tree and detailed info of a specific game by name" -Log
                Write-CCLSHost "list gamedir [folder name] -tree -d - View full file tree and detailed info  of a specific game by folder name" -Log
                
                Write-CCLSHost "`nDELETE COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "--------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "del help                            - Show del command help" -Log
                Write-CCLSHost "del [folder name]                   - Delete a game by folder name (with confirmation)" -Log
                Write-CCLSHost "del [id]                            - Delete a game by id (with confirmation)" -Log
                Write-CCLSHost "del game [name]                     - Delete a game by name (with confirmation)" -Log
                Write-CCLSHost "del gamedir [folder name]           - Delete a game by folder name (with confirmation)" -Log
                Write-CCLSHost "del [folder name] -y                - Delete a game by folder name (without confirmation)" -Log
                Write-CCLSHost "del [id] -y                         - Delete a game by id (without confirmation)" -Log
                Write-CCLSHost "del game [name] -y                  - Delete a game by name (without confirmation)" -Log
                Write-CCLSHost "del gamedir [folder name] -y        - Delete a game by folder name (without confirmation)" -Log

                Write-CCLSHost "`nCHANGELOG COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "---------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "changelog help                      - Show changelog command help" -Log
                Write-CCLSHost "changelog [version]                 - Display changelog for a specific version" -Log
                Write-CCLSHost "changelog list                      - Show list of all available changelogs" -Log
                Write-CCLSHost "changelog latest                    - Display changelog for the latest version" -Log

                Write-CCLSHost "`nBROWSE COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "--------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "browse                              - Interactive browser for installed games with detailed info" -Log
                Write-CCLSHost "browse help                         - Show browse command help" -Log

                Write-CCLSHost "`nLOG COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "log help                            - Show log command help" -Log
                Write-CCLSHost "log list                            - Browse all log files interactively" -Log
                Write-CCLSHost "log list -a, log list -all          - Browse all log files interactively" -Log
                Write-CCLSHost "log list -[number]                  - Show only specified number of newest log files" -Log
                Write-CCLSHost "log view [filename]                 - View contents of a specific log file" -Log
                Write-CCLSHost "log del [filename]                  - Delete a log file (with confirmation)" -Log
                Write-CCLSHost "log del [filename] -y               - Delete a log file (without confirmation)" -Log
                Write-CCLSHost "log open [filename]                 - Open log file with default application" -Log

                Write-CCLSHost "`nSYSTEM COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "---------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "sys help                            - Show system help" -Log

                Write-CCLSHost "`nSYSTEM LIBRARY CACHE COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "---------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "sys cache help                      - Show cache system help" -Log
                Write-CCLSHost "sys cache refresh                   - Manually refresh the library cache" -Log
                Write-CCLSHost "sys cache status                    - Show status of library cache" -Log

                Write-CCLSHost "`nSYSTEM STARTUP MESSAGE COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "------------------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "sys start-message help              - Show startup message system help" -Log
                Write-CCLSHost "sys start-message list              - List available templates from server" -Log
                Write-CCLSHost "sys start-message get [name]        - Download a template" -Log
                Write-CCLSHost "sys start-message enable [name]     - Enable a downloaded template" -Log
                Write-CCLSHost "sys start-message get,enable [name] - Download and enable a template" -Log
                Write-CCLSHost "sys start-message try [name]        - Preview a template without enabling" -Log
                Write-CCLSHost "sys start-message view              - View current startup message" -Log
                Write-CCLSHost "sys start-message default           - Disable startup message (use default)" -Log
                Write-CCLSHost "sys start-message del [name]        - Delete a specific template" -Log
                Write-CCLSHost "sys start-message wipe              - Delete all downloaded templates" -Log

                Write-CCLSHost "`nDEVELOPER MODE COMMANDS" -ForegroundColor Yellow -Log
                Write-CCLSHost "---------------" -ForegroundColor Yellow -Log
                Write-CCLSHost "devmode help                        - Show devmode command help (and information on usage of devmode)" -Log
                Write-CCLSHost "devmode                             - Activates and Deactivates Developer mode" -Log
                $helpProcessed = $true
            }
            # Main help command
            "^help$" {
                Write-CCLSHost "CCLS Games CLI - Help Overview" -ForegroundColor Green -Log
                Write-CCLSHost "============================" -ForegroundColor Green -Log
                Write-CCLSHost "`nBasic Commands:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  help                    - Show this help message" -Log
                Write-CCLSHost "  help -list-all, help -a - Show all available commands in one big array" -Log
                Write-CCLSHost "  clear, cls              - Clear the console screen" -Log
                Write-CCLSHost "  setup                   - Configure download directories" -Log
                Write-CCLSHost "  check                   - Check system requirements (Python, requests, 7-Zip)" -Log
                Write-CCLSHost "  version                 - Display the current version and check for updates" -Log
                Write-CCLSHost "  update                  - Update the CLI tool to the latest version" -Log
                Write-CCLSHost "  exit, quit              - Exit the application" -Log
                Write-CCLSHost "  logout                  - Log out and exit" -Log
                Write-CCLSHost "  forget                  - Remove stored credentials" -Log
                
                Write-CCLSHost "`nGame Management:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  browse                  - Interactive browser for installed games showing versions and status" -Log
                Write-CCLSHost "  search [cg0000/cb0000]  - Search for game/bundle information" -Log
                Write-CCLSHost "  search lib              - List all available games and bundles" -Log
                Write-CCLSHost "  get [cg0000/cb0000]     - Download and install a game/bundle by ID" -Log
                Write-CCLSHost "  get game [name]         - Download and install a game by name" -Log
                Write-CCLSHost "  list all                - List installed games (use -d for details)" -Log
                Write-CCLSHost "  list game [name]        - Show info about a specific game" -Log
                Write-CCLSHost "  del game [name]         - Delete an installed game" -Log
                Write-CCLSHost "  changelog [version]     - Display changelog for a specific version" -Log
                Write-CCLSHost "  log list                - Browse and manage log files" -Log
                Write-CCLSHost "  install [utility]       - Install specified utility" -Log
                
                Write-CCLSHost "`nFor detailed help on specific commands, type:" -ForegroundColor Yellow -Log
                Write-CCLSHost "  [command] help         - e.g., 'search help' or 'get help'" -Log
                $helpProcessed = $true
            }

            "^sys\s+help$" {
                Write-CCLSHost "CCLS Games CLI - System Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "================================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  sys cache help              - Show system cache message system help" -Log
                Write-CCLSHost "  sys start message help      - Show system startup message system help" -Log
                
                Write-CCLSHost "`nDescription:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  These are just the the help commands for each system command." -Log
                Write-CCLSHost "  For more info on a specific system command run specified help command." -Log
                $helpProcessed = $true
            }

            "^sys\s+cache\s+help$" {
                Write-CCLSHost "CCLS Games CLI - System Library Cache Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "================================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  sys cache refresh          - Manually refresh the library cache" -Log
                Write-CCLSHost "  sys cache status           - Show detailed cache status and information" -Log
                
                Write-CCLSHost "`nDescription:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  This command manually rebuilds the library cache (lib.json) by scanning" -Log
                Write-CCLSHost "  all installed games and calculating their sizes and metadata. This is" -Log
                Write-CCLSHost "  useful if the cache becomes corrupted or out of sync." -Log
                Write-CCLSHost "`n  The cache-status command shows detailed information about the current" -Log
                Write-CCLSHost "  state of the library cache including validity, file size, and integrity." -Log
                
                Write-CCLSHost "`nWhen to use:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - After manually copying/moving game folders" -Log
                Write-CCLSHost "  - If game listings show incorrect information" -Log
                Write-CCLSHost "  - If the cache file becomes corrupted" -Log
                Write-CCLSHost "  - After manually editing game JSON files" -Log
                Write-CCLSHost "  - To troubleshoot cache-related issues (use 'sys cache status')" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  sys cache refresh          - Rebuild the library cache" -Log
                Write-CCLSHost "  sys cache status           - Check current cache status and health" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - This process may take some time for large game libraries" -Log
                Write-CCLSHost "  - The cache is automatically updated when games are installed or deleted" -Log
                Write-CCLSHost "  - This command forces a complete rescan regardless of cache validity" -Log
                Write-CCLSHost "  - Use 'sys cache status' to diagnose cache issues before refreshing" -Log
                $helpProcessed = $true
            }
            
            # Sub-help commands with standardized formatting
            "^search\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Search Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "=================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  search [id]           - Search for a specific game or bundle" -Log
                Write-CCLSHost "  search game [term]    - Search for games matching your search term" -Log
                Write-CCLSHost "  search library        - List all available games and bundles" -Log
                Write-CCLSHost "  search lib            - List all available games and bundles" -Log
                
                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [id]                  - Game ID (cg0000) or Bundle ID (cb0000)" -Log
                Write-CCLSHost "  [term]                - Used to search games and bundles matching specified term" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  search cg0025         - Get information about game with ID cg0025" -Log
                Write-CCLSHost "  search cb0010         - Get information about bundle with ID cb0010" -Log
                Write-CCLSHost "  search game assasins  - Get a list of games matching 'assasins'" -Log
                Write-CCLSHost "  search library        - Display the complete game and bundle library" -Log
                Write-CCLSHost "  search lib            - Display the complete game and bundle library" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Use 'search game [term]' for a list of games matching your search term:" -Log
                Write-CCLSHost "  - When in the selectiong field of 'search game [term]' you can enter 'get [number]' to download the game." -Log
                Write-CCLSHost "  - Game/Bundle IDs can be found in the URL on the website:" -Log
                Write-CCLSHost "    https://games.ccls.icu/game.php?id=cg0000" -Log
                Write-CCLSHost "    https://games.ccls.icu/bundle.php?id=cb0000" -Log
                Write-CCLSHost "  - You can also find IDs by using the 'search library' command" -Log
                $helpProcessed = $true
            }
            
            "^get\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Get Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "==============================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  get [id] [options]        - Download and install a game or bundle by ID" -Log
                Write-CCLSHost "  get game [name] [options] - Download and install a game by name" -Log
                
                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [id]                  - Game ID (cg0000) or Bundle ID (cb0000)" -Log
                Write-CCLSHost "  [name]                - Game name (case-insensitive, supports partial matching)" -Log
                
                Write-CCLSHost "`nOptions:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  -y                    - Skip confirmation prompts (auto-confirm)" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  get cg0025            - Download and install game with ID cg0025" -Log
                Write-CCLSHost "  get cb0010 -y         - Download and install bundle with ID cb0010 without prompts" -Log
                Write-CCLSHost "  get game tekken 8     - Download and install TEKKEN 8 by name" -Log
                Write-CCLSHost "  get game plateup -y   - Download and install PlateUp! by name without prompts" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Game/Bundle IDs can be found using the 'search library' command" -Log
                Write-CCLSHost "  - Game names are case-insensitive and support partial matching" -Log
                Write-CCLSHost "  - The command will download, extract, and save game information" -Log
                Write-CCLSHost "  - Downloads can be stopped with Ctrl+Z" -Log
                $helpProcessed = $true
            }
            
            "^list\s+help$" {
                Write-CCLSHost "CCLS Games CLI - List Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "===============================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  list all [options]                   - List all installed games" -Log
                Write-CCLSHost "  list [folder name] [options]         - Display information about a specific game using game folder name" -Log
                Write-CCLSHost "  list [id] [options]                  - Display information about a specific game using game ID" -Log
                Write-CCLSHost "  list game [name] [options]           - Display information about a specific game using game name" -Log
                Write-CCLSHost "  list gamedir [folder name] [options] - Display information about a specific game using game folder name" -Log

                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [id]                   - Game ID (cg0000) or Bundle ID (cb0000)" -Log
                Write-CCLSHost "  [name]                 - Game name (case-insensitive, supports partial matching)" -Log
                Write-CCLSHost "  [folder name]          - Game folder name (case-insensitive)" -Log
                
                Write-CCLSHost "`nOptions:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  -d                     - View extended details (Description, etc) (works on all list commands)" -Log
                Write-CCLSHost "  -tree                  - View full file tree of a game (works only on game specific list commands)" -Log
                Write-CCLSHost "  -tree -d, -d -tree     - View full file tree and detailed info of a game (Description, etc) (works only on game specific list commands)" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  list the long drive          - Display information about The Long Drive" -Log
                Write-CCLSHost "  list the long drive -d       - Display extended information about The Long Drive" -Log
                Write-CCLSHost "  list the long drive -tree    - Display full file tree of The Long Drive" -Log
                Write-CCLSHost "  list the long drive -tree -d - Display full file tree and extended information of The Long Drive" -Log
                Write-CCLSHost "  list cg0023                  - Display information about The Long Drive using ID" -Log
                Write-CCLSHost "  list game the long drive     - Display information about The Long Drive using name" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Using 'list all -d' displays current version, size and checks for new updates on all downloaded games" -Log
                Write-CCLSHost "  - Using 'list [term]' only works if name of the game folder or game ID is specified" -Log
                Write-CCLSHost "  - Using 'list game [name]' or 'list [id]' can be useful as it works even if the game's folder name has been changed" -Log
                $helpProcessed = $true
            }
            
            "^del\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Delete Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "=================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  del [folder name] [options]         - Delete an installed game using game folder name" -Log
                Write-CCLSHost "  del [id] [options]                  - Delete an installed game using game ID" -Log
                Write-CCLSHost "  del game [name] [options]           - Delete an installed game using game name" -Log
                Write-CCLSHost "  del gamedir [folder name] [options] - Delete an installed game using game folder name" -Log
                
                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [name]                 - Name of the installed game to delete" -Log
                Write-CCLSHost "  [folder name]          - Folder name of the installed game to delete" -Log
                Write-CCLSHost "  [id]                   - ID of the installed game to delete" -Log
                
                Write-CCLSHost "`nOptions:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  -y                     - Skip confirmation prompt (auto-confirm) (works on all del command)" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  del The Long Drive     - Delete The Long Drive (with confirmation)" -Log
                Write-CCLSHost "  del cg0023             - Delete The Long Drive (cg0023) (with confirmation)" -Log
                Write-CCLSHost "  del The Long Drive -y  - Delete The Long Drive without confirmation" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - If using just 'del [term]' command 'term' must match game folder or id (non-case-sensitive)" -Log
                Write-CCLSHost "  - It's recommended to never use '-y' if you aren't 100% certain about game ID or game name" -Log
                Write-CCLSHost "  - This operation permanently deletes the game files" -Log
                Write-CCLSHost "  - You can always re-download deleted games with the 'get' command" -Log
                $helpProcessed = $true
            }
            
            # Updated help for install command
            "^install\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Install Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "==================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  install [utility]      - Install required utilities" -Log
                
                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [utility]              - Name of the utility to install" -Log
                
                Write-CCLSHost "`nSupported Utilities:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  7zip                   - 7-Zip for extracting downloaded files" -Log
                Write-CCLSHost "  python                 - Python interpreter (latest version)" -Log
                Write-CCLSHost "  requests               - Python requests library for better downloads" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  install 7zip           - Install 7-Zip for extraction" -Log
                Write-CCLSHost "  install python         - Download and install Python" -Log
                Write-CCLSHost "  install requests       - Install Python requests library" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - 7-Zip is required for extracting game archives" -Log
                Write-CCLSHost "  - Python is required for advanced download features" -Log
                Write-CCLSHost "  - Python requests is required if using Python downloader" -Log
                Write-CCLSHost "  - Run 'check' to see which utilities need to be installed" -Log
                $helpProcessed = $true
            }

            "^changelog\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Changelog Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "===================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  changelog [version]    - Display changelog for a specific version" -Log
                Write-CCLSHost "  changelog list         - Show list of all available changelogs" -Log
                Write-CCLSHost "  changelog latest       - Display changelog for the latest version" -Log

                Write-CCLSHost "`nParameters:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  [version]              - A valid version of CLI Tool" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  changelog 1.1.4        - Show changes in version 1.1.4" -Log
                Write-CCLSHost "  changelog list         - View all available changelog versions" -Log
                Write-CCLSHost "  changelog latest       - Show the most recent changes" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Changelogs document the changes, improvements, and bug fixes in each version" -Log
                Write-CCLSHost "  - The current version is shown with the 'version' command" -Log
                $helpProcessed = $true
            }

            "^devmode\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Devmode Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "===================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "devmode                  - Activates and Deactivates Developer mode" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Devmode is a tool which can be used if you want to try the script out" -Log
                Write-CCLSHost "  - No login or signup is required for devmode" -Log
                Write-CCLSHost "  - It can be easily started by pressing 'Ctrl+Q' at the login prompt" -Log
                Write-CCLSHost "  - When pressed type 'devmode' in the username prompt and press Enter" -Log
                Write-CCLSHost "  - And you are then in devmode, it can also be activated/deactivated by typing 'devmode' in the normal CLI window" -Log
                Write-CCLSHost "  - NOTE: when activating 'devmode' all previously stored credetials are deleted" -Log
                Write-CCLSHost "  - NOTE: all commands that call external API's like 'get' and 'search' wont work when in devmode" -Log
                $helpProcessed = $true
            }

            # Add this to your help command processing section:
            "^browse\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Browse Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "=================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  browse                 - Open interactive browser for installed games" -Log
                
                Write-CCLSHost "`nDescription:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  The browse command provides a fast, local-first interface to view and manage" -Log
                Write-CCLSHost "  all installed games. It shows local information immediately and only connects" -Log
                Write-CCLSHost "  to the server when you specifically request updates or online info." -Log
                
                Write-CCLSHost "`nBrowser Commands:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  view [number]          - View detailed information about an installed game" -Log
                Write-CCLSHost "  del [number]           - Delete an installed game (with confirmation)" -Log
                Write-CCLSHost "  update [number]        - Check for updates and download if available" -Log
                Write-CCLSHost "  refresh [number]       - Show current online information for a game" -Log
                Write-CCLSHost "  [number]               - Same as 'view [number]'" -Log
                Write-CCLSHost "  [Enter]                - Return to main menu" -Log
                
                Write-CCLSHost "`nInformation Displayed:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Game name (from metadata or folder name)" -Log
                Write-CCLSHost "  - Game ID (for CCLS games)" -Log
                Write-CCLSHost "  - Local folder size" -Log
                Write-CCLSHost "  - Local version (if available)" -Log
                Write-CCLSHost "  - Installation type" -Log
                
                Write-CCLSHost "`nGame Types:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  CCLS Game           - Game installed via CLI with metadata (Green)" -Log
                Write-CCLSHost "  Manual Install      - Game installed manually without metadata (Gray)" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  browse              - Open the installed games browser" -Log
                Write-CCLSHost "  [In browser] view 2 - View details for installed game #2" -Log
                Write-CCLSHost "  [In browser] update 3 - Check for updates for game #3" -Log
                Write-CCLSHost "  [In browser] refresh 1 - Show current online info for game #1" -Log
                Write-CCLSHost "  [In browser] del 5  - Delete installed game #5" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Browse loads instantly using only local data" -Log
                Write-CCLSHost "  - Online checks only happen when you request them (update/refresh)" -Log
                Write-CCLSHost "  - CCLS games support all features, manual installs support view/delete only" -Log
                Write-CCLSHost "  - Games with metadata are shown first, then manual installations" -Log
                Write-CCLSHost "  - All operations use existing game management functions" -Log
                $helpProcessed = $true
            }

            "^log\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Log Command Help" -ForegroundColor Green -Log
                Write-CCLSHost "==============================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  log list [options]           - Browse and manage log files" -Log
                Write-CCLSHost "  log view [filename]          - View contents of a specific log file" -Log
                Write-CCLSHost "  log del [filename] [options] - Delete a specific log file" -Log
                Write-CCLSHost "  log open [filename]          - Open log file with default application" -Log
                
                Write-CCLSHost "`nList Options:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  -a, -all                     - List all log files (default behavior)" -Log
                Write-CCLSHost "  -[number]                    - Limit display to specified number of files" -Log
                
                Write-CCLSHost "`nDelete Options:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  -y                           - Skip confirmation prompt" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  log list                     - Browse all log files interactively" -Log
                Write-CCLSHost "  log list -5                  - Show only the 5 newest log files" -Log
                Write-CCLSHost "  log list -all                - Show all log files (same as 'log list')" -Log
                Write-CCLSHost "  log view session_2024.log    - View contents of a specific log file" -Log
                Write-CCLSHost "  log del old_session.log      - Delete a log file with confirmation" -Log
                Write-CCLSHost "  log del old_session.log -y   - Delete a log file without confirmation" -Log
                Write-CCLSHost "  log open session_2024.log    - Open log file in default editor" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Log files are stored in the 'logs' folder" -Log
                Write-CCLSHost "  - Files are sorted by modification date (newest first)" -Log
                Write-CCLSHost "  - Interactive browser allows viewing, deleting, and opening files" -Log
                Write-CCLSHost "  - Opening files uses the system's default .log file association" -Log
                $helpProcessed = $true
            }

            "^sys\s+start-message\s+help$" {
                Write-CCLSHost "CCLS Games CLI - Startup Message System Help" -ForegroundColor Green -Log
                Write-CCLSHost "=========================================" -ForegroundColor Green -Log
                
                Write-CCLSHost "`nUsage:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  sys start-message list              - List available templates from server" -Log
                Write-CCLSHost "  sys start-message get [name]        - Download a template" -Log
                Write-CCLSHost "  sys start-message enable [name]     - Enable a downloaded template" -Log
                Write-CCLSHost "  sys start-message get,enable [name] - Download and enable a template" -Log
                Write-CCLSHost "  sys start-message try [name]        - Preview a template without enabling" -Log
                Write-CCLSHost "  sys start-message view              - View current startup message" -Log
                Write-CCLSHost "  sys start-message default           - Disable startup message (use default)" -Log
                Write-CCLSHost "  sys start-message del [name]        - Delete a specific template" -Log
                Write-CCLSHost "  sys start-message wipe              - Delete all downloaded templates" -Log
                
                Write-CCLSHost "`nExamples:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  sys start-message list              - See all available templates" -Log
                Write-CCLSHost "  sys start-message get gradient      - Download the 'gradient' template" -Log
                Write-CCLSHost "  sys start-message enable gradient   - Enable the 'gradient' template" -Log
                Write-CCLSHost "  sys start-message get,enable minimal - Download and enable 'minimal' template" -Log
                Write-CCLSHost "  sys start-message try gradient      - Preview the 'gradient' template" -Log
                Write-CCLSHost "  sys start-message view              - Show current startup message" -Log
                Write-CCLSHost "  sys start-message default           - Go back to default system messages" -Log
                
                Write-CCLSHost "`nNotes:" -ForegroundColor Cyan -Log
                Write-CCLSHost "  - Templates are JSON files that define colorful welcome messages" -Log
                Write-CCLSHost "  - Only one template can be active at a time" -Log
                Write-CCLSHost "  - Custom startup messages appear after login, before default messages" -Log
                Write-CCLSHost "  - Templates are stored in the settings/start-message folder" -Log
                Write-CCLSHost "  - Use 'try' to preview templates before enabling them" -Log
                $helpProcessed = $true
            }
        }
        
        if ($helpProcessed) {
            continue
        }
        
        # Handle base commands (commands without parameters)
        switch -Regex ($command.ToLower()) {
            "^search$" {
                Write-CCLSHost "Wrong command usage. Type 'search help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^get$" {
                Write-CCLSHost "Wrong command usage. Type 'get help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^list$" {
                Write-CCLSHost "Wrong command usage. Type 'list help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^del$" {
                Write-CCLSHost "Wrong command usage. Type 'del help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^install$" {
                Write-CCLSHost "Wrong command usage. Type 'install help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^changelog$" {
                Write-CCLSHost "Wrong command usage. Type 'changelog help' for a list of available options." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^log$" {
                Write-CCLSHost "Wrong command usage. Type 'log help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
            "^sys$" {
                Write-CCLSHost "Wrong command usage. Type 'sys start-message help' for a list of available commands." -ForegroundColor Red -Log
                $baseCommandProcessed = $true
            }
        }
        
        # If a base command was processed, skip the regular command processing
        if ($baseCommandProcessed) {
            continue
        }

        # Regular command processing with parameters
        switch -Regex ($command.ToLower()) {
            "^devmode$" {
                Toggle-DevMode
            }
            "^browse$" {
                Browse-Games
            }
            "^check$" {
                Test-SystemRequirements
            }
            "^exit$|^quit$" {
                $running = $false
                Write-CCLSHost "Thank you for using the CCLS Games CLI Tool. Goodbye!" -ForegroundColor Cyan -Log
            }
            "^clear$|^cls$" {
                Clear-ConsoleScreen
            }
            "^install(?:\s+(.+))?$" {
                $utilityName = if ($matches.Count -gt 1) { $matches[1] } else { "" }
                Install-Utility -UtilityName $utilityName
            }
            "^version$" {
                Show-Version
            }
            "^update$" {
                Update-CliTool
            }
            "^setup$" {
                Start-Setup
            }
            "^search\s+(c[gb]\d{4})$" {
                $id = $matches[1]
                Search-Game -id $id
            }
            "^search\s+game\s+(.+)$" {
                $searchTerm = $matches[1].Trim()
                # Pass "game" as the ID and the search term as additional arguments
                Search-Game -id "game" $searchTerm
            }
            "^get\s+(c[gb]\d{4})(?:\s+-y)?$" {
                $id = $matches[1]
                $skipConfirmation = $command -match "-y$"
                Get-Game -id $id -SkipConfirmation:$skipConfirmation
            }
            "^get\s+game\s+(.+?)(?:\s+-y)?$" {
                $gameName = $matches[1].Trim()
                $skipConfirmation = $command -match "-y$"
                # Pass "game" as the ID and the game name as additional arguments
                Get-Game -id "game" -SkipConfirmation:$skipConfirmation $gameName
            }
            "^search\s+library$|^search\s+lib$|^library$" {
                Get-GamesList
            }
            "^log\s+list(?:\s+(-a|-all|-\d+))?$" {
                $option = if ($matches.Count -gt 1 -and $matches[1]) { $matches[1].Trim() } else { "" }
                
                if ($option -eq "-a" -or $option -eq "-all" -or $option -eq "") {
                    # Show all log files
                    Show-LogBrowser
                } elseif ($option -match "^-(\d+)$") {
                    # Show limited number of log files
                    $limit = [int]$matches[1]
                    if ($limit -gt 0) {
                        Show-LogBrowser -Limit $limit
                    } else {
                        Write-CCLSHost "Invalid limit. Please specify a positive number." -ForegroundColor Red -Log
                    }
                } else {
                    Write-CCLSHost "Invalid option for log list. Use -a, -all, or -[number]." -ForegroundColor Red -Log
                }
            }
            "^log\s+view\s+(.+)$" {
                $logFileName = $matches[1].Trim()
                Show-LogFile -LogFileName $logFileName
            }
            "^log\s+del\s+(.+?)(?:\s+-y)?$" {
                $logFileName = $matches[1].Trim()
                $force = $command -match "-y$"
                
                # Remove -y from filename if present
                $logFileName = $logFileName -replace "\s+-y$", ""
                $logFileName = $logFileName.Trim()
                
                Remove-LogFile -LogFileName $logFileName -Force:$force
            }
            "^log\s+open\s+(.+)$" {
                $logFileName = $matches[1].Trim()
                Open-LogFile -LogFileName $logFileName
            }
            "^sys\s+cache\s+status$" {
                Show-LibraryCacheStatus
            }
            "^sys\s+cache\s+refresh$" {
                Refresh-LibraryCache
            }
            "^sys\s+start-message\s+(.+)$" {
                $params = $matches[1].Trim().Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)
                
                if ($params.Count -eq 1) {
                    # Single parameter commands
                    $action = $params[0]
                    Manage-StartupMessage -Action $action
                } elseif ($params.Count -eq 2) {
                    # Two parameter commands
                    $action = $params[0]
                    $templateName = $params[1]
                    Manage-StartupMessage -Action $action -TemplateName $templateName
                } else {
                    Write-CCLSHost "Invalid command format. Use: sys start-message [action] [template-name]" -ForegroundColor Red -Log
                    Write-CCLSHost "Type 'sys start-message list' to see available templates" -ForegroundColor Yellow -Log
                }
            }
            "^list(?:\s+(.+?))?(?:\s+(?:-d|-tree))*$" {
                if ($matches.Count -le 1 -or [string]::IsNullOrWhiteSpace($matches[1])) {
                    # No parameters provided
                    Write-CCLSHost "Wrong command usage. Type 'list help' for a list of available commands." -ForegroundColor Red -Log
                    continue
                }
                
                $parameters = $matches[1].Trim()
                $detailed = $command -match "\s+-d\b"
                $tree = $command -match "\s+-tree\b"
                
                # Remove flags from parameters if present
                $parameters = $parameters -replace "\s+(-d|-tree)+", ""
                $parameters = $parameters.Trim()
                
                # Handle 'list all' commands
                if ($parameters -eq "all") {
                    Get-InstalledGames -Detailed:$detailed
                }
                # Parse the command format for individual games
                elseif ($parameters -match "^(cg|cb)\d{4}$") {
                    # Direct ID match: list cg0055
                    Get-GameInfoByIdentifier -Identifier $parameters -SearchType "id" -Detailed:$detailed -Tree:$tree
                }
                elseif ($parameters -match "^game\s+(.+)$") {
                    # Game name match: list game [name]
                    $gameName = $matches[1].Trim()
                    Get-GameInfoByIdentifier -Identifier $gameName -SearchType "gamename" -Detailed:$detailed -Tree:$tree
                }
                elseif ($parameters -match "^gamedir\s+(.+)$") {
                    # Game directory match: list gamedir [folder]
                    $gameFolderName = $matches[1].Trim()
                    Get-GameInfoByIdentifier -Identifier $gameFolderName -SearchType "gamefoldername" -Detailed:$detailed -Tree:$tree
                }
                else {
                    # Default to gamefoldername for backward compatibility: list [folder]
                    Get-GameInfoByIdentifier -Identifier $parameters -SearchType "gamefoldername" -Detailed:$detailed -Tree:$tree
                }
            }
            "^del(?:\s+(.+?))?(?:\s+-y)?$" {
                if ($matches.Count -le 1 -or [string]::IsNullOrWhiteSpace($matches[1])) {
                    # No parameters provided
                    Write-CCLSHost "Wrong command usage. Type 'del help' for a list of available commands." -ForegroundColor Red -Log
                    continue
                }
                
                $parameters = $matches[1].Trim()
                $force = $command -match "-y$"
                
                # Remove -y from parameters if present
                $parameters = $parameters -replace "\s+-y$", ""
                $parameters = $parameters.Trim()
                
                # Parse the command format
                if ($parameters -match "^(cg|cb)\d{4}$") {
                    # Direct ID match: del cg0055
                    Remove-Game -Identifier $parameters -SearchType "id" -Force:$force
                }
                elseif ($parameters -match "^game\s+(.+)$") {
                    # Game name match: del game [name]
                    $gameName = $matches[1].Trim()
                    Remove-Game -Identifier $gameName -SearchType "game" -Force:$force
                }
                elseif ($parameters -match "^gamedir\s+(.+)$") {
                    # Game directory match: del gamedir [folder]
                    $gameFolderName = $matches[1].Trim()
                    Remove-Game -Identifier $gameFolderName -SearchType "gamedir" -Force:$force
                }
                else {
                    # Default to gamedir for backward compatibility: del [folder]
                    Remove-Game -Identifier $parameters -SearchType "gamedir" -Force:$force
                }
            }
            "^changelog\s+(.+)$" {
                $versionParam = $matches[1].Trim()
                Show-Changelog -Version $versionParam
                $commandProcessed = $true
            }
            "^logout$" {
                Write-CCLSHost "Logging out..." -ForegroundColor Cyan -Log
                
                # Clear stored credentials
                if (Test-Path $credentialsFile) {
                    Remove-Item -Path $credentialsFile -Force
                    Write-CCLSHost "#Removed stored credentials" -Log -NoConsole
                }
                
                # Clear cached credentials
                $script:cachedCredentials = $null
                
                # Update settings to disable remember login
                $settings = Initialize-Settings
                $settings.RememberLogin = $false
                Save-Settings -settings $settings
                
                # Clear the console
                Clear-Host
                
                # Show manual login screen
                Write-CCLSHost "Hello and welcome to the CCLS Games CLI Tool" -ForegroundColor Green -Log
                Write-CCLSHost "Before proceeding to using this software you will need to sign in." -Log
                Write-CCLSHost "If you do not have an account already please go to $baseUrl/login.php?signup to register a new account." -Log
                
                # Start manual login
                $loginResult = Start-ManualLogin
                
                if ($loginResult.Success) {
                    # Clear console again after successful login
                    Clear-Host
                    
                    # Check if we entered DevMode during login
                    if ($loginResult.DevMode) {
                        # DevMode was activated during login - start command interface
                        Start-CommandInterface -username $loginResult.Username
                        return
                    }
                    
                    # Check dependencies after successful login
                    Test-RequiredDependencies | Out-Null
                    
                    # Show oversight global message if available
                    if ($script:oversightEnabled -and $script:oversightData.global_message) {
                        $messageColor = Convert-HexToConsoleColor -HexColor $script:oversightData.global_message.color
                        Write-CCLSHost $script:oversightData.global_message.message -ForegroundColor $messageColor -Log
                    }
                    Show-StartupMessage
                    
                    # Show version warning if needed
                    Show-VersionWarningIfNeeded
                    
                    # Show welcome message
                    Write-CCLSHost "Welcome to CCLS Games CLI Tool, $($loginResult.Username)!" -ForegroundColor Green -Log
                    
                    # Show appropriate message based on setup status
                    $settings = Initialize-Settings
                    if ($settings.HasCompletedSetup) {
                        Write-CCLSHost "Type 'help' for a list of available commands." -ForegroundColor Cyan -Log
                    } else {
                        Write-CCLSHost "ALERT, type command 'setup' to set critical values before downloading." -ForegroundColor Red -Log
                    }
                    
                    # Continue with the command interface (don't exit the while loop)
                } else {
                    # Login failed, exit the application
                    $running = $false
                    Write-CCLSHost "Login failed. Press any key to exit..." -ForegroundColor Red -Log
                    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
                }
            }
            "^forget$" {
                if (Test-Path $credentialsFile) {
                    Remove-Item -Path $credentialsFile -Force
                    $settings = Initialize-Settings
                    $settings.RememberLogin = $false
                    Save-Settings -settings $settings
                    Write-CCLSHost "Stored credentials have been removed." -ForegroundColor Green -Log
                }
                else {
                    Write-CCLSHost "No stored credentials found." -ForegroundColor Yellow -Log
                }
            }
            default {
                # Extract the base command from the input (first word)
                $baseCommand = $command.Trim().Split()[0].ToLower()
                
                # Known base commands that have help available
                $knownCommands = @('search', 'get', 'list', 'del', 'install', 'log')
                
                if ($knownCommands -contains $baseCommand) {
                    # If it's a known command with incorrect parameters
                    Write-CCLSHost "Wrong command usage. Type '$baseCommand help' for a list of available commands." -ForegroundColor Red -Log
                } else {
                    # Completely unknown command
                    Write-CCLSHost "Unknown command. Type 'help' for a list of all available commands." -ForegroundColor Red -Log
                }
            }
        }
    }
}

# Add a line to log script completion
function End-Logging {
    $endTime = Get-Date
    "CCLS Games CLI Session ended at $endTime, duration: $(($endTime - [DateTime]::ParseExact($script:sessionStartTime, 'yyyy-MM-dd_HH-mm-ss', $null)).ToString())" | Out-File -FilePath $script:logFile -Append
}

# Register script exit event to ensure logging is completed
Register-EngineEvent -SourceIdentifier ([System.Management.Automation.PsEngineEvent]::Exiting) -Action {
    End-Logging
} | Out-Null

function Start-CclsCliTool {
    # Initialize script variables
    $script:versionChanged = $false
    $script:previousVersion = $null
    
    # Load settings to check for DevMode (this may generate errors on first run)
    $settings = Initialize-Settings

    Initialize-LibraryCache
    
    if ($settings.DevMode) {
        # In DevMode - skip login and warnings
        Write-CCLSHost "Hello and welcome to the CCLS Games CLI Tool (Developer Mode)" -ForegroundColor Green -Log
        Write-CCLSHost "You are in developer mode. 'get', 'search' and any other command that calls external API's will not work." -ForegroundColor Red -Log
        Write-CCLSHost "Type 'help' for a list of available commands." -ForegroundColor Cyan -Log
        
        # Clear any cached credentials to ensure we're not signed in
        $script:cachedCredentials = $null
        
        # Start command interface directly in DevMode
        Start-CommandInterface -username "Developer"
        return
    }
    
    # Try auto-login if remember login is enabled
    $loginResult = @{ Success = $false; DevMode = $false }
    if ($settings.RememberLogin) {
        $loginResult = Start-AutoLogin
    }
    
    # If auto-login failed or is disabled, do manual login
    if (-not $loginResult.Success) {
        # Check if we have stored credentials that failed
        $hasStoredCredentials = Test-Path $credentialsFile
        
        if ($hasStoredCredentials) {
            # Stored credentials exist but failed - show different message
            Write-CCLSHost "Your stored credentials are no longer valid or have expired." -ForegroundColor Yellow -Log
            Write-CCLSHost "Please sign in again to continue using the CCLS Games CLI Tool." -ForegroundColor Yellow -Log
            # Add any additional messaging for failed stored credentials here
        } else {
            # No stored credentials - show first-time welcome message
            Write-CCLSHost "Hello and welcome to the CCLS Games CLI Tool" -ForegroundColor Green -Log
            Write-CCLSHost "Before proceeding to using this software you will need to sign in." -Log
            Write-CCLSHost "If you do not have an account already please go to $baseUrl/login.php?signup to register a new account." -Log
        }
        
        $loginResult = Start-ManualLogin
        
        # Clear the console after successful manual login
        if ($loginResult.Success) {
            Clear-Host
        }
    }
    
    # If login succeeded, show main interface
    if ($loginResult.Success) {
        # Check if we entered DevMode during login
        if ($loginResult.DevMode) {
            # DevMode was activated during login - start command interface
            Start-CommandInterface -username $loginResult.Username
            return
        }

        # Check dependencies after successful login
        Test-RequiredDependencies | Out-Null
        
        # Show oversight global message if available
        if ($script:oversightEnabled -and $script:oversightData.global_message) {
            $messageColor = Convert-HexToConsoleColor -HexColor $script:oversightData.global_message.color
            Write-CCLSHost $script:oversightData.global_message.message -ForegroundColor $messageColor -Log
        }
        

        
        # Check if version has changed and show notification
        if ($script:versionChanged) {
            $versionInfo = Test-VersionUpdate
            $currentVersion = $versionInfo.CurrentVersion
            Show-StartupMessage
            Write-CCLSHost "Welcome to CCLS Games CLI Tool v$currentVersion, $($loginResult.Username)! Type 'changelog latest' to view the changes made." -ForegroundColor Green -Log
        }
        else {
            Show-StartupMessage
            Write-CCLSHost "Welcome to CCLS Games CLI Tool, $($loginResult.Username)!" -ForegroundColor Green -Log
        }
        
        # Show appropriate message based on setup status (only if not in DevMode)
        if ($settings.HasCompletedSetup) {
            Write-CCLSHost "Type 'help' for a list of available commands." -ForegroundColor Cyan -Log
        }
        else {
            Write-CCLSHost "ALERT, type command 'setup' to set critical values before downloading." -ForegroundColor Red -Log
        }

        # NOW show version warning (after oversight data is loaded)
        Show-VersionWarningIfNeeded
        
        Start-CommandInterface -username $loginResult.Username
    }
    else {
        Write-CCLSHost "Login failed. Press any key to exit..." -ForegroundColor Red -Log
        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}

# Format a file size in bytes to a human-readable string
function Format-Size {
    param (
        [long]$Size
    )
    
    if ($Size -ge 1GB) {
        return "{0:N2} GB" -f ($Size / 1GB)
    }
    elseif ($Size -ge 1MB) {
        return "{0:N2} MB" -f ($Size / 1MB)
    }
    elseif ($Size -ge 1KB) {
        return "{0:N2} KB" -f ($Size / 1KB)
    }
    else {
        return "$Size B"
    }
}

# Start the application
Try {
    Start-CclsCliTool
}
Finally {
    # Ensure logging is completed even if script exits unexpectedly
    End-Logging
}