<#
.SYNOPSIS
    Removes pre-installed bloatware: AppX packages, Capabilities, and Optional Features.

.DESCRIPTION
    Removes Microsoft-bundled apps and features not needed in a business MSP deployment.
    Removal is done for all users (-AllUsers) and from the provisioning store so new
    users do not get them either. Calculator and Photos are intentionally kept.

.ITEMS
    appx-balicky-odstraneni-pro-vsechny-uziv: Uses Remove-AppxPackage -AllUsers and Remove-AppxProvisionedPackage. The provisioned removal prevents apps from reinstalling for new user profiles. Covers ~35 apps including Cortana, Copilot, Teams personal, Xbox, Skype, News, Weather, Maps.
    zachovano-microsoft-windowscalculator: Calculator is explicitly excluded. Lightweight utility frequently used by technicians and end users. Removing it would require manual reinstall from Store.
    zachovano-microsoft-windows-photos: Photos is explicitly excluded via KeepPackages. Default image viewer expected by end users; removing it leaves no built-in viewer and would require manual reinstall from Store.
    windows-capabilities-fax-ie-openssh-wmp-: Removed via Remove-WindowsCapability: Fax & Scan, Internet Explorer mode, OpenSSH client, Windows Media Player (legacy), WordPad, Handwriting recognition, Steps Recorder, Math Input Panel, Quick Assist.
    windows-optional-features-ps-2-0-mediapl: Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component.
    feature-toggles: Three GUI feature flags gate removal. standardBloatware (default on) covers the bulk list. removeNewOutlook (default on) controls Microsoft.OutlookForWindows; classic Outlook from M365 is a Win32 app and is never touched. removeSnippingTool (default OFF) controls Snipping Tool across all three lists (ScreenSketch app + legacy capability + legacy feature) - kept by default as a common productivity tool, like Calculator.
#>
param(
    [string]$ConfigPath,
    [string]$LogFile
)

. "$PSScriptRoot\common.ps1"
$Config = Load-Config $ConfigPath

# -----------------------------------------------------------------------
# Feature flags (see CLAUDE.md features system)
#   standardBloatware  - removes the bulk AppX/capability/feature list
#   removeNewOutlook   - new Outlook for Windows (Microsoft.OutlookForWindows)
#   removeSnippingTool - Snipping Tool, spans all three lists; default OFF
# Outlook and Snipping items are gated by their own flag, independent of the
# standard flag, so each GUI checkbox does exactly what it says.
# -----------------------------------------------------------------------
$DoStandard = Get-Feature $Config "bloatware" "standardBloatware"  $true
$DoOutlook  = Get-Feature $Config "bloatware" "removeNewOutlook"   $true
$DoSnipping = Get-Feature $Config "bloatware" "removeSnippingTool" $false

# Snipping Tool appears as an AppX package (ScreenSketch, the modern app),
# a legacy capability, and a legacy optional feature.
$SnippingItems = @(
    "Microsoft.ScreenSketch"
    "Microsoft.Windows.SnippingTool"
    "Microsoft-SnippingTool"
)

function Test-RemovalAllowed {
    param([string]$Name)
    if ($Name -eq "Microsoft.OutlookForWindows") { return $DoOutlook }
    if ($SnippingItems -contains $Name)          { return $DoSnipping }
    return $DoStandard
}

# -----------------------------------------------------------------------
# 1a - AppX packages
# -----------------------------------------------------------------------
$AppxToRemove = @(
    "Microsoft.Microsoft3DViewer"
    "Microsoft.BingSearch"
    "Microsoft.WindowsCamera"
    "Clipchamp.Clipchamp"
    "Microsoft.WindowsAlarms"
    "Microsoft.Copilot"
    "Microsoft.549981C3F5F10"
    "Microsoft.Windows.DevHome"
    "MicrosoftCorporationII.MicrosoftFamily"
    "Microsoft.WindowsFeedbackHub"
    "Microsoft.Edge.GameAssist"
    "Microsoft.GetHelp"
    "Microsoft.Getstarted"
    "microsoft.windowscommunicationsapps"
    "Microsoft.WindowsMaps"
    "Microsoft.MixedReality.Portal"
    "Microsoft.BingNews"
    "Microsoft.MicrosoftOfficeHub"
    "Microsoft.Office.OneNote"
    "Microsoft.OutlookForWindows"
    "Microsoft.Paint"
    "Microsoft.MSPaint"
    "Microsoft.People"
    "Microsoft.Windows.Photos"
    "Microsoft.PowerAutomateDesktop"
    "MicrosoftCorporationII.QuickAssist"
    "Microsoft.SkypeApp"
    "Microsoft.ScreenSketch"
    "Microsoft.MicrosoftSolitaireCollection"
    "Microsoft.MicrosoftStickyNotes"
    "MicrosoftTeams"
    "MSTeams"
    "Microsoft.Todos"
    "Microsoft.WindowsSoundRecorder"
    "Microsoft.Wallet"
    "Microsoft.BingWeather"
    "Microsoft.WindowsTerminal"
    "Microsoft.Xbox.TCUI"
    "Microsoft.XboxApp"
    "Microsoft.XboxGameOverlay"
    "Microsoft.XboxGamingOverlay"
    "Microsoft.XboxIdentityProvider"
    "Microsoft.XboxSpeechToTextOverlay"
    "Microsoft.GamingApp"
    "Microsoft.YourPhone"
    "Microsoft.ZuneMusic"
    "Microsoft.ZuneVideo"
    "7EE7776C.LinkedInforWindows"
)

# Packages to always keep
$KeepPackages = @("Microsoft.WindowsCalculator", "Microsoft.Windows.Photos")
if ($Config -and $Config.bloatware -and $Config.bloatware.keepPackages) {
    $KeepPackages += $Config.bloatware.keepPackages
}
$KeepPackages = $KeepPackages | Select-Object -Unique

Write-Log "1a - Removing AppX packages" -Level STEP

foreach ($pkg in $AppxToRemove) {
    if ($KeepPackages -contains $pkg) {
        Write-Log "  KEEP $pkg" -Level INFO
        continue
    }
    if (-not (Test-RemovalAllowed $pkg)) {
        Write-Log "  KEEP (feature off): $pkg" -Level INFO
        continue
    }

    # Installed packages (current user + all users)
    $installed = Get-AppxPackage -Name $pkg -AllUsers -ErrorAction SilentlyContinue
    if ($installed) {
        try {
            $installed | Remove-AppxPackage -AllUsers -ErrorAction Stop
            Write-Log "  Removed AppxPackage: $pkg" -Level OK
        }
        catch {
            Write-Log "  Failed to remove AppxPackage $pkg - $_" -Level WARN
        }
    }

    # Provisioned packages (for new users)
    $provisioned = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue |
                   Where-Object { $_.DisplayName -eq $pkg }
    if ($provisioned) {
        try {
            $provisioned | Remove-AppxProvisionedPackage -Online -ErrorAction Stop | Out-Null
            Write-Log "  Removed provisioned: $pkg" -Level OK
        }
        catch {
            Write-Log "  Failed to remove provisioned $pkg - $_" -Level WARN
        }
    }

    if (-not $installed -and -not $provisioned) {
        Write-Log "  Not found (already removed): $pkg" -Level INFO
    }
}

# -----------------------------------------------------------------------
# 1b - Windows Capabilities
# -----------------------------------------------------------------------
$CapabilitiesToRemove = @(
    "Print.Fax.Scan"
    "Language.Handwriting"
    "Browser.InternetExplorer"
    "MathRecognizer"
    "OneCoreUAP.OneSync"
    "OpenSSH.Client"
    "Microsoft.Windows.MSPaint"
    "Microsoft.Windows.PowerShell.ISE"
    "App.Support.QuickAssist"
    "Microsoft.Windows.SnippingTool"
    "App.StepsRecorder"
    "Hello.Face"
    "Media.WindowsMediaPlayer"
    "Microsoft.Windows.WordPad"
)

Write-Log "1b - Removing Windows Capabilities" -Level STEP

$installedCaps = Get-WindowsCapability -Online -ErrorAction SilentlyContinue

foreach ($cap in $CapabilitiesToRemove) {
    if (-not (Test-RemovalAllowed $cap)) {
        Write-Log "  KEEP (feature off): $cap" -Level INFO
        continue
    }
    # Match by prefix (e.g. Hello.Face matches Hello.Face.20134.0.0.0)
    $matches = $installedCaps | Where-Object {
        $_.Name -like "$cap*" -and $_.State -eq "Installed"
    }
    if ($matches) {
        foreach ($c in $matches) {
            try {
                Remove-WindowsCapability -Online -Name $c.Name -ErrorAction Stop | Out-Null
                Write-Log "  Removed capability: $($c.Name)" -Level OK
            }
            catch {
                Write-Log "  Failed to remove capability $($c.Name) - $_" -Level WARN
            }
        }
    } else {
        Write-Log "  Not found or not installed: $cap" -Level INFO
    }
}

# -----------------------------------------------------------------------
# 1c - Windows Optional Features
# -----------------------------------------------------------------------
$FeaturesToDisable = @(
    "MediaPlayback"
    "MicrosoftWindowsPowerShellV2Root"
    "Recall"
    "Microsoft-SnippingTool"
)

Write-Log "1c - Disabling Windows Optional Features" -Level STEP

foreach ($feat in $FeaturesToDisable) {
    if (-not (Test-RemovalAllowed $feat)) {
        Write-Log "  KEEP (feature off): $feat" -Level INFO
        continue
    }
    $feature = Get-WindowsOptionalFeature -Online -FeatureName $feat -ErrorAction SilentlyContinue
    if ($feature -and $feature.State -eq "Enabled") {
        try {
            Disable-WindowsOptionalFeature -Online -FeatureName $feat -NoRestart -ErrorAction Stop | Out-Null
            Write-Log "  Disabled feature: $feat" -Level OK
        }
        catch {
            Write-Log "  Failed to disable feature $feat - $_" -Level WARN
        }
    } else {
        Write-Log "  Not enabled or not found: $feat" -Level INFO
    }
}

Write-Log "Step 1 complete" -Level OK
