<#
.SYNOPSIS
    Applies registry settings to the Default User profile, current user, and sets visual theme.

.DESCRIPTION
    Loads C:\Users\Default\NTUSER.DAT as a temporary hive (HKU\DefaultProfile), applies
    all taskbar, Start menu, Explorer, and personalization settings, then unloads it.
    Every new user account inherits these settings on first logon. The same settings are
    applied directly to the current user's HKCU. Visual identity: dark taskbar/Start with
    accent color #223B47 (deep blue-gray), light app mode, no transparency. Wallpaper is
    set to a solid color matching the accent - BackInfo.exe overwrites it on every logon.

.ITEMS
    taskbar-zarovnat-vlevo-taskbaral-0: TaskbarAl = 0 in Explorer\Advanced. Left alignment matches Windows 10 muscle memory.
    taskbar-skryt-search-copilot-task-view-w: Hides Search box, Copilot, Task View, Widgets, Chat/Teams buttons.
    taskbar-zobrazit-vsechny-ikonky-v-tray: EnableAutoTray=0 and TrayNotify icon streams cleared.
    taskbar-vyprazdnit-pinlist-taskbarlayout: Deploys TaskbarLayoutModification.xml per ProfileType.
    explorer-zobrazovat-pripony-souboru-hide: HideFileExt = 0. Shows file extensions in Explorer.
    explorer-otevrit-na-this-pc-launchto-1: LaunchTo = 1. Explorer opens to This PC.
    explorer-showrecent-0-showfrequent-0: ShowRecent=0, ShowFrequent=0. Hides recent/frequent from Quick Access.
    explorer-fullpath-1-cabinetstate: FullPath=1 in CabinetState. Full path in Explorer title bar.
    start-menu-vyprazdnit-piny-win11: ConfigureStartPins = {"pinnedList":[]}. Empty Start menu grid.
    start-menu-zakaz-bing-vyhledavani: DisableSearchBoxSuggestions = 1. Local search only.
    copilot-zakaz-turnoffwindowscopilot-1: TurnOffWindowsCopilot = 1. Disables Copilot sidebar.
    numlock-zapnout-pri-startu: InitialKeyboardIndicators = 2.
    system-tema-taskbar-start-dark: SystemUsesLightTheme=0. Dark shell, light apps.
    accent-barva-223b47: AccentColor 0xFF473B22, ColorPrevalence=1, taskbar/Start branded.
    pruhlednost-vypnuta: EnableTransparency=0.
    tapeta-jednobarevna-223b47: Solid color #223B47 via SystemParametersInfo. BackInfo overwrites on logon.
#>
param(
    [string]$ConfigPath,
    [string]$LogFile,
    [ValidateSet("default","admin","user")]
    [string]$ProfileType = "default"
)

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

# -----------------------------------------------------------------------
# Helpers - apply registry to both Default hive and current HKCU
# -----------------------------------------------------------------------
function Grant-HiveWriteAccess {
    param([string]$HivePath)
    try {
        $acl  = Get-Acl -Path $HivePath -ErrorAction Stop
        $rule = New-Object System.Security.AccessControl.RegistryAccessRule(
            "BUILTIN\Administrators",
            [System.Security.AccessControl.RegistryRights]::FullControl,
            [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit",
            [System.Security.AccessControl.PropagationFlags]::None,
            [System.Security.AccessControl.AccessControlType]::Allow
        )
        $acl.SetAccessRule($rule)
        Set-Acl -Path $HivePath -AclObject $acl -ErrorAction Stop
    }
    catch {
        Write-Log "  Grant-HiveWriteAccess failed for $HivePath - $_" -Level WARN
    }
}

function Set-ProfileReg {
    param(
        [string]$SubKey,
        [string]$Name,
        $Value,
        [string]$Type = "DWord"
    )

    # Apply to loaded Default hive
    $defPath = "Registry::HKU\DefaultProfile\$SubKey"
    try {
        if (-not (Test-Path $defPath)) {
            New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null
        }
        Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
    }
    catch {
        try {
            $parentPath = $defPath -replace '\\[^\\]+$', ''
            if (Test-Path $parentPath) { Grant-HiveWriteAccess -HivePath $parentPath }
            if (-not (Test-Path $defPath)) {
                New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null
            }
            Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
        }
        catch {
            Write-Log "  DEFAULT HIVE failed $SubKey\$Name - $_" -Level ERROR
        }
    }

    # Apply to current user as well
    $hkcuPath = "HKCU:\$SubKey"
    try {
        if (-not (Test-Path $hkcuPath)) {
            New-Item -Path $hkcuPath -Force -ErrorAction Stop | Out-Null
        }
        Set-ItemProperty -Path $hkcuPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
        Write-Log "  SET $SubKey\$Name = $Value" -Level OK
    }
    catch {
        Write-Log "  HKCU failed $SubKey\$Name - $_" -Level ERROR
    }
}

# Accent color #223B47 (R=34 G=59 B=71) stored as ABGR DWORD: 0xFF473B22
$AccentColorABGR = 0xFF473B22
$AccentR = 0x22; $AccentG = 0x3B; $AccentB = 0x47

# Build the 8-shade AccentPalette that Settings writes under Explorer\Accent.
# Without it Win11 ignores the custom accent on Start/taskbar and falls back to
# the default - the root cause of "colors not applied everywhere". Layout:
# Light3, Light2, Light1, Accent(base, index 3), Dark1..Dark4. Each entry RGBA.
function Get-AccentPalette {
    param([int]$R, [int]$G, [int]$B)
    $tints  = @(0.70, 0.45, 0.20)              # light3 (lightest) -> light1
    $shades = @(0.25, 0.45, 0.65, 0.85)        # dark1 -> dark4
    $bytes  = New-Object System.Collections.Generic.List[byte]
    foreach ($t in $tints) {
        $bytes.Add([byte][math]::Round($R + (255 - $R) * $t))
        $bytes.Add([byte][math]::Round($G + (255 - $G) * $t))
        $bytes.Add([byte][math]::Round($B + (255 - $B) * $t))
        $bytes.Add(0xFF)
    }
    $bytes.Add([byte]$R); $bytes.Add([byte]$G); $bytes.Add([byte]$B); $bytes.Add(0xFF)  # base accent
    foreach ($s in $shades) {
        $bytes.Add([byte][math]::Round($R * (1 - $s)))
        $bytes.Add([byte][math]::Round($G * (1 - $s)))
        $bytes.Add([byte][math]::Round($B * (1 - $s)))
        $bytes.Add(0xFF)
    }
    return ,([byte[]]$bytes.ToArray())
}
$AccentPalette = Get-AccentPalette $AccentR $AccentG $AccentB

# -----------------------------------------------------------------------
# Load Default profile hive
# -----------------------------------------------------------------------
$hivePath = "C:\Users\Default\NTUSER.DAT"
$hiveKey  = "DefaultProfile"

Write-Log "Loading Default hive: $hivePath" -Level INFO

# Unload first in case previous run left it mounted
& reg unload "HKU\$hiveKey" 2>&1 | Out-Null

$loadResult = & reg load "HKU\$hiveKey" $hivePath 2>&1
if ($LASTEXITCODE -ne 0) {
    Write-Log "Failed to load Default hive: $loadResult" -Level ERROR
    exit 1
}
Write-Log "Default hive loaded" -Level OK

try {
    # ===================================================================
    # TASKBAR TWEAKS
    # ===================================================================
    if (Get-Feature $Config "defaultProfile" "taskbarTweaks") {
        Write-Log "Applying taskbar tweaks" -Level STEP

        $tbPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"

        # Win11: align taskbar to left
        Set-ProfileReg -SubKey $tbPath -Name "TaskbarAl" -Value 0

        # Hide Search box - set both Win10 and Win11 locations
        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Search" `
                       -Name "SearchboxTaskbarMode" -Value 0
        Set-ProfileReg -SubKey $tbPath -Name "SearchboxTaskbarMode" -Value 0

        # Hide Task View, Widgets, Chat/Teams, Copilot buttons
        Set-ProfileReg -SubKey $tbPath -Name "ShowTaskViewButton" -Value 0
        Set-ProfileReg -SubKey $tbPath -Name "TaskbarDa" -Value 0
        Set-ProfileReg -SubKey $tbPath -Name "TaskbarMn" -Value 0
        Set-ProfileReg -SubKey $tbPath -Name "ShowCopilotButton" -Value 0

        # Show all tray icons
        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
                       -Name "EnableAutoTray" -Value 0

        # Win11: clear cached tray icon streams
        $trayNotifyKey = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"
        if (Test-Path $trayNotifyKey) {
            Remove-ItemProperty -Path $trayNotifyKey -Name "IconStreams"     -Force -ErrorAction SilentlyContinue
            Remove-ItemProperty -Path $trayNotifyKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue
            Write-Log "  Cleared TrayNotify icon streams (Win11 systray workaround)" -Level OK
        }
        $defTrayKey = "Registry::HKU\DefaultProfile\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"
        if (Test-Path $defTrayKey) {
            Remove-ItemProperty -Path $defTrayKey -Name "IconStreams"     -Force -ErrorAction SilentlyContinue
            Remove-ItemProperty -Path $defTrayKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue
            Write-Log "  Cleared TrayNotify icon streams in Default hive" -Level OK
        }

        # Desktop icons - show This PC
        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel" `
                       -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -Value 0

        # Taskbar pinned apps layout
        Write-Log "  Writing taskbar layout (ProfileType=$ProfileType)" -Level INFO

        $wsh = New-Object -ComObject WScript.Shell
        $defRoaming = "C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs"

        # File Explorer is pinned via its AppUserModelID (see pin list below),
        # not a custom .lnk. A hand-made shortcut to explorer.exe pins as a
        # separate app: clicking it launches a second Explorer that does not
        # group with the running window, and the icon cannot be unpinned
        # normally. The AUMID pin behaves like the built-in Explorer button.

        if ($ProfileType -eq "admin") {
            $psLnkDir = "$defRoaming\Windows PowerShell"
            $psLnk    = "$psLnkDir\Windows PowerShell.lnk"
            if (-not (Test-Path $psLnk)) {
                if (-not (Test-Path $psLnkDir)) { New-Item -ItemType Directory -Path $psLnkDir -Force | Out-Null }
                $sc = $wsh.CreateShortcut($psLnk)
                $sc.TargetPath = "$env:WINDIR\System32\WindowsPowerShell\v1.0\powershell.exe"
                $sc.Save()
                Write-Log "  Created Windows PowerShell.lnk in Default profile Start Menu" -Level OK
            }
        }

        $taskbarLayoutDir = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell"
        if (-not (Test-Path $taskbarLayoutDir)) {
            New-Item -ItemType Directory -Path $taskbarLayoutDir -Force | Out-Null
        }

        $pinList = switch ($ProfileType) {
            "admin" {
@'
        <taskbar:DesktopApp DesktopApplicationID="Microsoft.Windows.Explorer"/>
        <taskbar:DesktopApp DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk"/>
        <taskbar:DesktopApp DesktopApplicationLinkPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"/>
'@
            }
            default {
@'
        <taskbar:DesktopApp DesktopApplicationID="Microsoft.Windows.Explorer"/>
        <taskbar:DesktopApp DesktopApplicationLinkPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"/>
'@
            }
        }

        $taskbarLayoutXml = @"
<?xml version="1.0" encoding="utf-8"?>
<LayoutModificationTemplate
    xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification"
    xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout"
    xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout"
    xmlns:taskbar="http://schemas.microsoft.com/Start/2014/TaskbarLayout"
    Version="1">
  <CustomTaskbarLayoutCollection PinListPlacement="Replace">
    <defaultlayout:TaskbarLayout>
      <taskbar:TaskbarPinList>
$pinList
      </taskbar:TaskbarPinList>
    </defaultlayout:TaskbarLayout>
  </CustomTaskbarLayoutCollection>
</LayoutModificationTemplate>
"@
        $utf8NoBom = New-Object System.Text.UTF8Encoding $false
        [System.IO.File]::WriteAllText("$taskbarLayoutDir\LayoutModification.xml", $taskbarLayoutXml, $utf8NoBom)
        Write-Log "  Taskbar LayoutModification.xml written (profile: $ProfileType)" -Level OK

        # NumLock on startup
        Set-ProfileReg -SubKey "Control Panel\Keyboard" `
                       -Name "InitialKeyboardIndicators" -Value 2 -Type "String"
    } else {
        Write-Log "taskbarTweaks feature disabled - skipping" -Level INFO
    }

    # ===================================================================
    # START MENU TWEAKS
    # ===================================================================
    if (Get-Feature $Config "defaultProfile" "startMenuTweaks") {
        Write-Log "Applying Start menu tweaks" -Level STEP

        Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\Explorer" `
                       -Name "DisableSearchBoxSuggestions" -Value 1

        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Start" `
                       -Name "ConfigureStartPins" `
                       -Value '{"pinnedList":[]}' `
                       -Type "String"

        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" `
                       -Name "Start_TrackProgs" -Value 0

        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" `
                       -Name "Start_TrackDocs" -Value 0

        Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\WindowsCopilot" `
                       -Name "TurnOffWindowsCopilot" -Value 1

        Set-ProfileReg -SubKey "System\GameConfigStore" `
                       -Name "GameDVR_Enabled" -Value 0
        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\GameDVR" `
                       -Name "AppCaptureEnabled" -Value 0
    } else {
        Write-Log "startMenuTweaks feature disabled - skipping" -Level INFO
    }

    # ===================================================================
    # EXPLORER TWEAKS
    # ===================================================================
    if (Get-Feature $Config "defaultProfile" "explorerTweaks") {
        Write-Log "Applying Explorer tweaks" -Level STEP

        $advPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"

        Set-ProfileReg -SubKey $advPath -Name "HideFileExt" -Value 0
        Set-ProfileReg -SubKey $advPath -Name "LaunchTo" -Value 1

        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
                       -Name "ShowRecent" -Value 0
        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
                       -Name "ShowFrequent" -Value 0

        Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState" `
                       -Name "FullPath" -Value 1
    } else {
        Write-Log "explorerTweaks feature disabled - skipping" -Level INFO
    }

    # ===================================================================
    # PERSONALIZATION (theme, accent color, wallpaper)
    # ===================================================================
    Write-Log "Applying personalization (theme, accent, wallpaper)" -Level STEP

    # Dark shell (taskbar, Start), light apps
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
                   -Name "SystemUsesLightTheme" -Value 0
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
                   -Name "AppsUseLightTheme" -Value 1

    # Accent color on Start and taskbar
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
                   -Name "ColorPrevalence" -Value 1

    # Transparency disabled
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
                   -Name "EnableTransparency" -Value 0

    # Accent color #223B47
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" `
                   -Name "AccentColor" -Value $AccentColorABGR -Type "DWord"
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" `
                   -Name "ColorizationColor" -Value $AccentColorABGR -Type "DWord"
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" `
                   -Name "ColorizationAfterglow" -Value $AccentColorABGR -Type "DWord"
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" `
                   -Name "ColorPrevalence" -Value 1

    # Taskbar accent color (Explorer\Accent, not DWM)
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Accent" `
                   -Name "AccentColorMenu" -Value $AccentColorABGR -Type "DWord"
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Accent" `
                   -Name "StartColorMenu" -Value $AccentColorABGR -Type "DWord"

    # AccentPalette - required for Win11 to actually honor the accent on Start
    # and taskbar (without it the custom color is dropped for the default).
    Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Accent" `
                   -Name "AccentPalette" -Value $AccentPalette -Type "Binary"

    # Wallpaper - solid color #223B47 (BackInfo overwrites on logon)
    Set-ProfileReg -SubKey "Control Panel\Colors" `
                   -Name "Background" -Value "34 59 71" -Type "String"
    Set-ProfileReg -SubKey "Control Panel\Desktop" `
                   -Name "Wallpaper" -Value "" -Type "String"
    Set-ProfileReg -SubKey "Control Panel\Desktop" `
                   -Name "WallpaperStyle" -Value "0" -Type "String"
    Set-ProfileReg -SubKey "Control Panel\Desktop" `
                   -Name "TileWallpaper" -Value "0" -Type "String"

    # Mirror the theme + accent into HKU\.DEFAULT so the lock/welcome screen and
    # system-context UI use the same branding (covers "all profiles", not just
    # newly created users which inherit from the Default hive above).
    $defaultColors = @(
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; Name="SystemUsesLightTheme"; Val=0;                Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; Name="AppsUseLightTheme";    Val=1;                Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; Name="ColorPrevalence";      Val=1;                Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; Name="EnableTransparency";   Val=0;                Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\DWM";                               Name="AccentColor";          Val=$AccentColorABGR; Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\DWM";                               Name="ColorizationColor";    Val=$AccentColorABGR; Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\DWM";                               Name="ColorizationAfterglow";Val=$AccentColorABGR; Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\DWM";                               Name="ColorPrevalence";      Val=1;                Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Explorer\Accent";    Name="AccentColorMenu";      Val=$AccentColorABGR; Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Explorer\Accent";    Name="StartColorMenu";       Val=$AccentColorABGR; Type="DWord"  },
        @{ Key="Software\Microsoft\Windows\CurrentVersion\Explorer\Accent";    Name="AccentPalette";        Val=$AccentPalette;   Type="Binary" },
        @{ Key="Control Panel\Colors";                                         Name="Background";           Val="34 59 71";       Type="String" }
    )
    foreach ($c in $defaultColors) {
        $cp = "Registry::HKU\.DEFAULT\$($c.Key)"
        try {
            if (-not (Test-Path $cp)) { New-Item -Path $cp -Force -ErrorAction Stop | Out-Null }
            Set-ItemProperty -Path $cp -Name $c.Name -Value $c.Val -Type $c.Type -Force -ErrorAction Stop
        }
        catch {
            Write-Log "  .DEFAULT color $($c.Key)\$($c.Name) failed - $_" -Level WARN
        }
    }
    Write-Log "  Theme/accent mirrored to HKU\.DEFAULT" -Level OK

    # -------------------------------------------------------------------
    # Desktop background color in EVERY existing user profile
    # -------------------------------------------------------------------
    # BackInfo paints a centered bitmap; if it is smaller than the screen, the
    # area around it shows HKCU\Control Panel\Colors\Background. New users get
    # #223B47 from the Default hive and the current user from HKCU above, but
    # pre-existing profiles would show the default black border. Set the color
    # in each real user profile (loading its hive if it is not already mounted).
    Write-Log "Applying desktop background color to existing user profiles" -Level STEP
    $profileList = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
    foreach ($pl in (Get-ChildItem $profileList -ErrorAction SilentlyContinue)) {
        $sid = Split-Path $pl.Name -Leaf
        if ($sid -notmatch '^S-1-5-21-') { continue }   # real interactive users only
        $img = (Get-ItemProperty $pl.PSPath -Name ProfileImagePath -ErrorAction SilentlyContinue).ProfileImagePath
        if (-not $img) { continue }

        $hiveKeyPath = "Registry::HKU\$sid"
        $tempLoaded  = $false
        if (-not (Test-Path $hiveKeyPath)) {
            $ntuser = Join-Path $img "NTUSER.DAT"
            if (-not (Test-Path $ntuser)) { continue }
            & reg load "HKU\$sid" $ntuser 2>&1 | Out-Null
            if ($LASTEXITCODE -ne 0) {
                Write-Log "  Could not load hive for $sid (in use?) - skipped" -Level WARN
                continue
            }
            $tempLoaded = $true
        }
        try {
            $colorsKey = "$hiveKeyPath\Control Panel\Colors"
            if (-not (Test-Path $colorsKey)) { New-Item -Path $colorsKey -Force -ErrorAction Stop | Out-Null }
            Set-ItemProperty -Path $colorsKey -Name "Background" -Value "34 59 71" -Type String -Force -ErrorAction Stop
            Write-Log "  Background color set for $sid ($(Split-Path $img -Leaf))" -Level OK
        }
        catch {
            Write-Log "  Failed background color for $sid - $_" -Level WARN
        }
        finally {
            if ($tempLoaded) {
                [GC]::Collect(); [GC]::WaitForPendingFinalizers(); Start-Sleep -Milliseconds 300
                & reg unload "HKU\$sid" 2>&1 | Out-Null
            }
        }
    }

    # ===================================================================
    # KEYBOARD LAYOUTS - Czech primary, US secondary
    # ===================================================================
    # CZ stays the primary input language; US English is added as a harmless
    # secondary so programmer/special chars are reachable. Applied in three
    # places so every account type gets it:
    #   - current user (adminx9) via Set-WinUserLanguageList
    #   - Default profile hive -> every newly created user inherits it
    #   - HKU\.DEFAULT         -> welcome screen and system/service accounts
    # KLIDs: 00000405 = Czech, 00000409 = US English.
    Write-Log "Configuring keyboard layouts (CZ primary, US secondary)" -Level STEP

    function Set-PreloadLayouts {
        param([string]$KeyPath)   # full Registry:: path to the "...\Keyboard Layout\Preload" key
        try {
            if (-not (Test-Path $KeyPath)) { New-Item -Path $KeyPath -Force -ErrorAction Stop | Out-Null }
            Set-ItemProperty -Path $KeyPath -Name "1" -Value "00000405" -Type String -Force -ErrorAction Stop
            Set-ItemProperty -Path $KeyPath -Name "2" -Value "00000409" -Type String -Force -ErrorAction Stop
            Write-Log "  Preload set (1=CZ, 2=US): $KeyPath" -Level OK
        }
        catch {
            Write-Log "  Failed to set Preload at $KeyPath - $_" -Level WARN
        }
    }

    # Current user: use the language-list API so the secondary layout shows up
    # in the language bar, not just the raw Preload key.
    try {
        $langs = New-WinUserLanguageList -Language "cs-CZ"
        $langs.Add("en-US")
        Set-WinUserLanguageList -LanguageList $langs -Force -ErrorAction Stop
        Write-Log "  Current user language list set (cs-CZ + en-US)" -Level OK
    }
    catch {
        Write-Log "  Set-WinUserLanguageList failed - $_" -Level WARN
    }

    # New users (Default profile hive) and welcome screen / system accounts (.DEFAULT)
    Set-PreloadLayouts -KeyPath "Registry::HKU\DefaultProfile\Keyboard Layout\Preload"
    Set-PreloadLayouts -KeyPath "Registry::HKU\.DEFAULT\Keyboard Layout\Preload"
}
finally {
    # -----------------------------------------------------------------------
    # Unload Default hive - always, even on error. Retry because GC and
    # other processes (antivirus) may hold handles briefly.
    # -----------------------------------------------------------------------
    Write-Log "Unloading Default hive" -Level INFO
    $unloaded = $false
    for ($attempt = 1; $attempt -le 5; $attempt++) {
        [GC]::Collect()
        [GC]::WaitForPendingFinalizers()
        Start-Sleep -Milliseconds ($attempt * 500)

        $unloadResult = & reg unload "HKU\$hiveKey" 2>&1
        if ($LASTEXITCODE -eq 0) {
            Write-Log "Default hive unloaded (attempt $attempt)" -Level OK
            $unloaded = $true
            break
        }
    }
    if (-not $unloaded) {
        Write-Log "Failed to unload Default hive after 5 attempts: $unloadResult" -Level ERROR
        Write-Log "  New user profiles may not inherit all settings until next reboot" -Level WARN
    }
}

# -----------------------------------------------------------------------
# Apply wallpaper (solid color) to current desktop session
# -----------------------------------------------------------------------
Write-Log "Setting desktop wallpaper to solid color" -Level INFO
try {
    Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class WallpaperHelper {
    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
}
"@ -ErrorAction SilentlyContinue
    [WallpaperHelper]::SystemParametersInfo(20, 0, "", 3) | Out-Null
    Write-Log "  Desktop wallpaper updated" -Level OK
}
catch {
    Write-Log "  Failed to update wallpaper: $_" -Level WARN
}

Write-Log "Step 4 complete" -Level OK
