Public/New-Budget.ps1

function New-Budget {
    <#
    .SYNOPSIS
        Creates a new budget within the workspace.
     
    .DESCRIPTION
        Creates a new budget directory with metadata and empty entity files.
        Optionally sets the new budget as the active budget.
     
    .PARAMETER Name
        The name of the budget. Must contain only alphanumeric characters, hyphens, and underscores.
     
    .PARAMETER Description
        Optional description of the budget purpose.
     
    .PARAMETER InitialBalance
        Optional initial balance for the budget. Defaults to 0.
     
    .PARAMETER Tags
        Optional array of tags for organizing budgets.
     
    .PARAMETER SetActive
        If specified, sets this budget as the active budget after creation.
     
    .PARAMETER WorkspacePath
        Optional custom workspace path. Uses default if not specified.
     
    .EXAMPLE
        New-Budget -Name "daily-expenses" -Description "Day to day living expenses"
         
        Creates a new budget for daily expenses
     
    .EXAMPLE
        New-Budget -Name "japan-holiday-2026" -Description "Trip planning" -SetActive
         
        Creates a new budget and sets it as active
     
    .EXAMPLE
        New-Budget -Name "home-renovation" -InitialBalance 15000 -Tags "project","savings"
         
        Creates a budget with an initial balance and tags
     
    .OUTPUTS
        PSCustomObject - Budget metadata
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [ValidatePattern('^[a-zA-Z0-9\-_]+$')]
        [string]$Name,
        
        [Parameter()]
        [string]$Description = '',
        
        [Parameter()]
        [decimal]$InitialBalance = 0.00,
        
        [Parameter()]
        [string[]]$Tags = @(),
        
        [Parameter()]
        [switch]$SetActive,
        
        [Parameter()]
        [string]$WorkspacePath
    )
    
    # Check if workspace is initialized
    if (-not (Test-WorkspaceInitialized -WorkspacePath $WorkspacePath)) {
        Write-Error "Budget workspace not initialized. Run Initialize-BudgetWorkspace first."
        return
    }
    
    # Get workspace path
    if (-not $WorkspacePath) {
        $WorkspacePath = Get-WorkspacePath
    }
    
    # Get budget path
    $budgetPath = Get-BudgetPath -BudgetName $Name -WorkspacePath $WorkspacePath
    
    # Check if budget already exists
    if (Test-Path $budgetPath) {
        Write-Error "Budget '$Name' already exists at: $budgetPath"
        return
    }
    
    if ($PSCmdlet.ShouldProcess($Name, "Create new budget")) {
        # Create budget directory
        Write-Verbose "Creating budget directory: $budgetPath"
        New-Item -Path $budgetPath -ItemType Directory -Force | Out-Null
        
        # Create metadata
        $metadata = [PSCustomObject]@{
            name = $Name
            description = $Description
            created = (Get-Date).ToString('yyyy-MM-dd')
            lastModified = (Get-Date).ToString('yyyy-MM-dd')
            initialBalance = $InitialBalance
            tags = $Tags
        }
        
        if (Set-BudgetMetadata -Metadata $metadata -BudgetPath $budgetPath) {
            Write-Verbose "Created budget metadata"
        }
        
        # Create empty entity files
        @('Billers.json', 'Earnings.json', 'Accounts.json') | ForEach-Object {
            $filePath = Join-Path $budgetPath $_
            '[]' | Set-Content -Path $filePath -Encoding UTF8
            Write-Verbose "Created $_"
        }
        
        # Set as active if requested
        if ($SetActive) {
            $preferences = Get-Preferences -WorkspacePath $WorkspacePath
            $preferences.activeBudget = $Name
            
            if (-not $preferences.defaultBudget) {
                $preferences.defaultBudget = $Name
            }
            
            Set-Preferences -Preferences $preferences -WorkspacePath $WorkspacePath | Out-Null
            Write-Verbose "Set $Name as active budget"
        }
        
        Write-Host "Created budget: $Name" -ForegroundColor Green
        
        return $metadata
    }
}