Public/Set-BudgetWorkspace.ps1

function Set-BudgetWorkspace {
    <#
    .SYNOPSIS
        Changes the budget workspace directory path.
     
    .DESCRIPTION
        Updates the workspace path in preferences.json to point to a different
        budget workspace directory. This allows switching between different
        workspace locations (e.g., OneDrive, local disk, network share).
     
    .PARAMETER Path
        The full path to the workspace directory. Must exist and contain a
        valid preferences.json file with budget data.
     
    .PARAMETER CreateIfMissing
        If specified, creates and initializes the workspace if it doesn't exist.
     
    .EXAMPLE
        Set-BudgetWorkspace -Path 'D:\Budgets\.mybudget'
         
        Switches to a different workspace on D: drive
     
    .EXAMPLE
        Set-BudgetWorkspace -Path 'C:\Users\user\OneDrive\.mybudget'
         
        Switches to a workspace in OneDrive
     
    .EXAMPLE
        Set-BudgetWorkspace -Path 'E:\NewWorkspace\.mybudget' -CreateIfMissing
         
        Creates and switches to a new workspace
     
    .OUTPUTS
        PSCustomObject - Updated preferences
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [string]$Path,
        
        [Parameter()]
        [switch]$CreateIfMissing
    )
    
    # Resolve to full path
    try {
        $resolvedPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
    }
    catch {
        Write-Error "Invalid path: $Path"
        return
    }
    
    # Check if workspace exists
    if (-not (Test-Path $resolvedPath)) {
        if ($CreateIfMissing) {
            if ($PSCmdlet.ShouldProcess($resolvedPath, "Create new workspace directory")) {
                Write-Verbose "Creating workspace directory: $resolvedPath"
                try {
                    New-Item -Path $resolvedPath -ItemType Directory -Force | Out-Null
                }
                catch {
                    Write-Error "Failed to create workspace directory: $_"
                    return
                }
            }
            else {
                return
            }
        }
        else {
            Write-Error "Workspace path does not exist: $resolvedPath. Use -CreateIfMissing to create it, or run Initialize-BudgetWorkspace."
            return
        }
    }
    
    # Check for preferences.json
    $preferencesPath = Join-Path $resolvedPath 'preferences.json'
    
    if (-not (Test-Path $preferencesPath)) {
        if ($CreateIfMissing) {
            Write-Warning "Workspace is not initialized. Run Initialize-BudgetWorkspace -WorkspacePath '$resolvedPath' to set it up."
        }
        else {
            Write-Error "Workspace does not contain preferences.json. Run Initialize-BudgetWorkspace -WorkspacePath '$resolvedPath' first."
            return
        }
    }
    
    if ($PSCmdlet.ShouldProcess($resolvedPath, "Set as workspace path")) {
        # Get current preferences (from current workspace)
        $currentPreferences = Get-Preferences -ErrorAction SilentlyContinue
        
        # Load preferences from target workspace (or create minimal if CreateIfMissing)
        if (Test-Path $preferencesPath) {
            try {
                $targetPreferences = Get-Content -Path $preferencesPath -Raw | ConvertFrom-Json
            }
            catch {
                Write-Error "Failed to read preferences from target workspace: $_"
                return
            }
        }
        else {
            # Create minimal preferences for new workspace
            $targetPreferences = [PSCustomObject]@{
                workspacePath = $resolvedPath
                defaultBudget = ''
                activeBudget = ''
                dateFormat = 'yyyy-MM-dd'
                currencySymbol = '$'
                version = '0.4.0'
            }
            
            try {
                $targetPreferences | ConvertTo-Json | Set-Content -Path $preferencesPath -ErrorAction Stop
                Write-Verbose "Created preferences.json in new workspace"
            }
            catch {
                Write-Error "Failed to create preferences.json: $_"
                return
            }
        }
        
        # Update workspace path in target preferences
        $targetPreferences.workspacePath = $resolvedPath
        
        # Save to target workspace
        try {
            $targetPreferences | ConvertTo-Json | Set-Content -Path $preferencesPath -ErrorAction Stop
            Write-Host "Workspace path updated to: $resolvedPath" -ForegroundColor Green
            
            # Also update current session's default location if there was one
            if ($currentPreferences) {
                $currentPrefsPath = Join-Path (Split-Path $preferencesPath -Parent) 'preferences.json'
                if (Test-Path $currentPrefsPath) {
                    # This updates the old workspace to point to new location (optional behavior)
                    # Comment out if you don't want cross-workspace linking
                }
            }
            
            Write-Host "Active budget: $($targetPreferences.activeBudget)" -ForegroundColor Cyan
            Write-Verbose "You may need to restart PowerShell or reimport the module for changes to take full effect"
            
            return $targetPreferences
        }
        catch {
            Write-Error "Failed to update preferences: $_"
            return
        }
    }
}