Poshify.psm1

<#
.SYNOPSIS
    A PowerShell module for managing Oh My Posh themes

.DESCRIPTION
    This module provides functions to browse, download, install, and switch between Oh My Posh themes
    with an easy-to-use interface.
#>


# Module variables
$script:OhMyPoshConfigPath = Join-Path $HOME ".posh-themes"
$script:OhMyPoshThemesUrl = "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes"

<#
.SYNOPSIS
    Gets available Oh My Posh themes from the official repository

.DESCRIPTION
    Downloads and displays a list of available Oh My Posh themes from the official GitHub repository

.EXAMPLE
    Get-PoshTheme
    Lists all available themes

.EXAMPLE
    Get-PoshTheme -Filter "*power*"
    Lists themes containing "power" in their name
#>

function Get-PoshTheme {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0)]
        [string]$Filter = "*"
    )

    try {
        Write-Host "Fetching available Oh My Posh themes..." -ForegroundColor Cyan
        
        # Create themes directory if it doesn't exist
        if (-not (Test-Path $script:OhMyPoshConfigPath)) {
            New-Item -ItemType Directory -Path $script:OhMyPoshConfigPath -Force | Out-Null
        }

        # Get theme list from GitHub API
        $themesApiUrl = "https://api.github.com/repos/JanDeDobbeleer/oh-my-posh/contents/themes"
        $response = Invoke-RestMethod -Uri $themesApiUrl -Method Get
        
        # Filter theme files
        $themes = $response | Where-Object { $_.name -like "*.omp.json" -and $_.name -like $Filter } | 
                  Select-Object @{Name="ThemeName";Expression={$_.name -replace '\.omp\.json$', ''}}, 
                               @{Name="DownloadUrl";Expression={$_.download_url}},
                               @{Name="Size";Expression={[math]::Round($_.size / 1KB, 2)}}

        if ($themes.Count -eq 0) {
            Write-Host "No themes found matching filter: $Filter" -ForegroundColor Yellow
            return
        }

        Write-Host "`nAvailable themes:" -ForegroundColor Green
        Write-Host ("=" * 50) -ForegroundColor Gray
        
        $index = 1
        foreach ($theme in $themes) {
            Write-Host "[$index] $($theme.ThemeName) ($($theme.Size) KB)" -ForegroundColor White
            $index++
        }
        
        return $themes
    }
    catch {
        Write-Error "Failed to fetch themes: $($_.Exception.Message)"
        return $null
    }
}

<#
.SYNOPSIS
    Downloads and installs an Oh My Posh theme

.DESCRIPTION
    Downloads a specific Oh My Posh theme from the official repository and saves it locally

.PARAMETER ThemeName
    The name of the theme to install

.PARAMETER Force
    Overwrite the theme if it already exists

.EXAMPLE
    Install-PoshTheme -ThemeName "powerlevel10k_rainbow"
    Downloads and installs the powerlevel10k_rainbow theme
#>

function Install-PoshTheme {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$ThemeName,
        
        [Parameter()]
        [switch]$Force
    )

    try {
        $themeUrl = "$script:OhMyPoshThemesUrl/$ThemeName.omp.json"
        $localPath = Join-Path $script:OhMyPoshConfigPath "$ThemeName.omp.json"
        
        # Check if theme already exists
        if ((Test-Path $localPath) -and -not $Force) {
            Write-Host "Theme '$ThemeName' already exists. Use -Force to overwrite." -ForegroundColor Yellow
            return
        }

        Write-Host "Downloading theme '$ThemeName'..." -ForegroundColor Cyan
        
        # Create directory if it doesn't exist
        if (-not (Test-Path $script:OhMyPoshConfigPath)) {
            New-Item -ItemType Directory -Path $script:OhMyPoshConfigPath -Force | Out-Null
        }

        # Download theme
        Invoke-WebRequest -Uri $themeUrl -OutFile $localPath -UseBasicParsing
        
        Write-Host "Theme '$ThemeName' installed successfully!" -ForegroundColor Green
        Write-Host "Location: $localPath" -ForegroundColor Gray
    }
    catch {
        Write-Error "Failed to install theme '$ThemeName': $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Sets the current Oh My Posh theme

.DESCRIPTION
    Applies the specified Oh My Posh theme to the current PowerShell session

.PARAMETER ThemeName
    The name of the theme to apply

.PARAMETER Permanent
    Make the theme permanent by updating the PowerShell profile

.EXAMPLE
    Set-PoshTheme -ThemeName "powerlevel10k_rainbow"
    Applies the theme for the current session only

.EXAMPLE
    Set-PoshTheme -ThemeName "powerlevel10k_rainbow" -Permanent
    Applies the theme and makes it permanent
#>

function Set-PoshTheme {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$ThemeName,
        
        [Parameter()]
        [switch]$Permanent
    )

    try {
        # Check if oh-my-posh is installed
        if (-not (Get-Command oh-my-posh -ErrorAction SilentlyContinue)) {
            Write-Error "Oh My Posh is not installed. Please install it first: https://ohmyposh.dev/docs/installation"
            return
        }

        $themePath = Join-Path $script:OhMyPoshConfigPath "$ThemeName.omp.json"
        
        # Check if theme exists locally
        if (-not (Test-Path $themePath)) {
            Write-Host "Theme '$ThemeName' not found locally. Attempting to download..." -ForegroundColor Yellow
            Install-PoshTheme -ThemeName $ThemeName
        }
        
        # Apply theme
        oh-my-posh init pwsh --config $themePath | Invoke-Expression
        
        Write-Host "Theme '$ThemeName' applied successfully!" -ForegroundColor Green
        
        # Make permanent if requested
        if ($Permanent) {
            $profilePath = $PROFILE.CurrentUserAllHosts
            $poshInit = "oh-my-posh init pwsh --config '$themePath' | Invoke-Expression"
            
            # Create profile if it doesn't exist
            if (-not (Test-Path $profilePath)) {
                New-Item -ItemType File -Path $profilePath -Force | Out-Null
            }
            
            # Remove existing oh-my-posh initialization
            $profileContent = Get-Content $profilePath -ErrorAction SilentlyContinue
            $profileContent = $profileContent | Where-Object { $_ -notmatch "oh-my-posh init" }
            
            # Add new initialization
            $profileContent += "`n# Oh My Posh Theme: $ThemeName"
            $profileContent += $poshInit
            
            Set-Content -Path $profilePath -Value $profileContent
            Write-Host "Theme set as permanent in profile: $profilePath" -ForegroundColor Green
        }
    }
    catch {
        Write-Error "Failed to set theme '$ThemeName': $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Uninstalls a locally installed Oh My Posh theme

.DESCRIPTION
    Removes a downloaded Oh My Posh theme from the local storage

.PARAMETER ThemeName
    The name of the theme to uninstall

.EXAMPLE
    Uninstall-PoshTheme -ThemeName "powerlevel10k_rainbow"
    Removes the specified theme from local storage
#>

function Uninstall-PoshTheme {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$ThemeName
    )

    try {
        $themePath = Join-Path $script:OhMyPoshConfigPath "$ThemeName.omp.json"
        
        if (-not (Test-Path $themePath)) {
            Write-Host "Theme '$ThemeName' is not installed locally." -ForegroundColor Yellow
            return
        }
        
        Remove-Item -Path $themePath -Force
        Write-Host "Theme '$ThemeName' uninstalled successfully!" -ForegroundColor Green
    }
    catch {
        Write-Error "Failed to uninstall theme '$ThemeName': $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Shows a preview of an Oh My Posh theme

.DESCRIPTION
    Displays a preview of the specified theme by applying it temporarily

.PARAMETER ThemeName
    The name of the theme to preview

.EXAMPLE
    Show-PoshThemePreview -ThemeName "powerlevel10k_rainbow"
    Shows a preview of the specified theme
#>

function Show-PoshThemePreview {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$ThemeName
    )

    try {
        Write-Host "Previewing theme '$ThemeName'..." -ForegroundColor Cyan
        Write-Host "Press any key to return to your previous theme..." -ForegroundColor Yellow
        
        # Store current theme
        $currentTheme = $env:POSH_THEME
        
        # Apply preview theme
        Set-PoshTheme -ThemeName $ThemeName
        
        # Wait for user input
        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        
        # Restore previous theme if available
        if ($currentTheme) {
            oh-my-posh init pwsh --config $currentTheme | Invoke-Expression
            Write-Host "`nReturned to previous theme." -ForegroundColor Green
        }
    }
    catch {
        Write-Error "Failed to preview theme '$ThemeName': $($_.Exception.Message)"
    }
}

# Export module functions
Export-ModuleMember -Function @(
    'Get-PoshTheme',
    'Install-PoshTheme', 
    'Set-PoshTheme',
    'Uninstall-PoshTheme',
    'Show-PoshThemePreview'
)