<#
.SYNOPSIS
    Initializes the user interface for the BuildFFUVM_UI application.

.DESCRIPTION
    This script module contains functions responsible for initializing the WPF user interface.
    It handles several key tasks:
    - Caching references to all UI controls for efficient access.
    - Populating UI elements like combo boxes with data (e.g., Hyper-V switches).
    - Setting default values for all controls based on configuration or predefined settings.
    - Dynamically creating and configuring complex UI components, such as sortable/selectable GridView columns and feature selection grids.
    
    This module is critical for setting up the initial state of the application window when it first loads.
#>

function Initialize-FluentTheme {
    param(
        [Parameter(Mandatory = $true)]
        [System.Windows.Window]$Window,
        [Parameter(Mandatory = $false)]
        [string]$ThemeMode = "System",
        [Parameter(Mandatory = $false)]
        [PSCustomObject]$State
    )

    # Check if the current .NET runtime supports Window.ThemeMode (requires .NET 9+ / PowerShell 7.5+)
    $themeModeProperty = [System.Windows.Window].GetProperty("ThemeMode")
    if ($null -eq $themeModeProperty) {
        WriteLog "Fluent theme not available. Window.ThemeMode requires PowerShell 7.5+ (.NET 9+). Using default Aero2 theme."
        if ($null -ne $State) {
            $State.Flags.isFluentSupported = $false
        }
        # Still create tooltip styles for non-Fluent mode so Tag-to-ToolTip binding works
        $controlTypes = @(
            [System.Windows.Controls.TextBox],
            [System.Windows.Controls.TextBlock],
            [System.Windows.Controls.CheckBox]
        )
        foreach ($controlType in $controlTypes) {
            $newStyle = New-Object System.Windows.Style($controlType)
            $toolTipBinding = New-Object System.Windows.Data.Binding("Tag")
            $toolTipBinding.RelativeSource = [System.Windows.Data.RelativeSource]::new([System.Windows.Data.RelativeSourceMode]::Self)
            $toolTipSetter = New-Object System.Windows.Setter([System.Windows.FrameworkElement]::ToolTipProperty, $toolTipBinding)
            $newStyle.Setters.Add($toolTipSetter)
            if ($Window.Resources.Contains($controlType)) {
                $Window.Resources.Remove($controlType)
            }
            $Window.Resources.Add($controlType, $newStyle)
        }
        WriteLog "Tooltip styles created for non-Fluent mode."
        return
    }

    # Mark Fluent as supported in state
    if ($null -ne $State) {
        $State.Flags.isFluentSupported = $true
    }

    # Resolve the ThemeMode enum value using reflection to avoid compile-time experimental attribute issues
    $themeModeType = [System.Windows.Window].GetProperty("ThemeMode").PropertyType
    $themeModeValue = $null
    switch ($ThemeMode) {
        "Light" { $themeModeValue = $themeModeType::Light }
        "Dark" { $themeModeValue = $themeModeType::Dark }
        "System" { $themeModeValue = $themeModeType::System }
        default { $themeModeValue = $themeModeType::System }
    }

    # Apply the Fluent theme mode to the window
    $themeModeProperty.SetValue($Window, $themeModeValue)
    WriteLog "Applied Fluent theme: $ThemeMode"

    # Re-create implicit tooltip styles with BasedOn pointing to the Fluent base style
    # This preserves the Tag-to-ToolTip binding while inheriting Fluent visual styling
    $controlTypes = @(
        [System.Windows.Controls.TextBox],
        [System.Windows.Controls.TextBlock],
        [System.Windows.Controls.CheckBox]
    )

    foreach ($controlType in $controlTypes) {
        # Get the Fluent base style that was loaded by ThemeMode
        $fluentBaseStyle = $Window.TryFindResource($controlType)

        # Create a new implicit style with ToolTip binding
        $newStyle = New-Object System.Windows.Style($controlType)
        if ($null -ne $fluentBaseStyle) {
            $newStyle.BasedOn = $fluentBaseStyle
        }

        # Add the ToolTip setter that binds to the Tag property
        $toolTipBinding = New-Object System.Windows.Data.Binding("Tag")
        $toolTipBinding.RelativeSource = [System.Windows.Data.RelativeSource]::new([System.Windows.Data.RelativeSourceMode]::Self)
        $toolTipSetter = New-Object System.Windows.Setter([System.Windows.FrameworkElement]::ToolTipProperty, $toolTipBinding)
        $newStyle.Setters.Add($toolTipSetter)

        # Remove any existing implicit style for this type before adding the new one
        if ($Window.Resources.Contains($controlType)) {
            $Window.Resources.Remove($controlType)
        }
        $Window.Resources.Add($controlType, $newStyle)
    }

        WriteLog "Tooltip styles updated with Fluent base styles."
    }

function Initialize-UIControls {
    param([PSCustomObject]$State)
    WriteLog "Initializing UI control references..."
    $window = $State.Window
    # Find all controls ONCE and store them in the state object
    $State.Controls.cmbWindowsRelease = $window.FindName('cmbWindowsRelease')
    $State.Controls.cmbWindowsVersion = $window.FindName('cmbWindowsVersion')
    $State.Controls.txtISOPath = $window.FindName('txtISOPath')
    $State.Controls.rbDownloadESD = $window.FindName('rbDownloadESD')
    $State.Controls.rbProvideISO = $window.FindName('rbProvideISO')
    $State.Controls.isoPathPanel = $window.FindName('isoPathPanel')
    $State.Controls.btnBrowseISO = $window.FindName('btnBrowseISO')
    $State.Controls.cmbWindowsArch = $window.FindName('cmbWindowsArch')
    $State.Controls.cmbWindowsLang = $window.FindName('cmbWindowsLang')
    $State.Controls.WindowsLangStackPanel = $window.FindName('WindowsLangStackPanel')
    $State.Controls.cmbWindowsSKU = $window.FindName('cmbWindowsSKU')
    $State.Controls.cmbMediaType = $window.FindName('cmbMediaType')
    $State.Controls.MediaTypeStackPanel = $window.FindName('MediaTypeStackPanel')
    $State.Controls.featuresPanel = $window.FindName('stackFeaturesContainer')
    $State.Controls.chkDownloadDrivers = $window.FindName('chkDownloadDrivers')
    $State.Controls.cmbMake = $window.FindName('cmbMake')
    $State.Controls.spMakeSection = $window.FindName('spMakeSection')
    $State.Controls.btnGetModels = $window.FindName('btnGetModels')
    $State.Controls.spModelFilterSection = $window.FindName('spModelFilterSection')
    $State.Controls.txtModelFilter = $window.FindName('txtModelFilter')
    $State.Controls.lstDriverModels = $window.FindName('lstDriverModels')
    $State.Controls.spDriverActionButtons = $window.FindName('spDriverActionButtons')
    $State.Controls.btnSaveDriversJson = $window.FindName('btnSaveDriversJson')
    $State.Controls.btnImportDriversJson = $window.FindName('btnImportDriversJson')
    $State.Controls.btnDownloadSelectedDrivers = $window.FindName('btnDownloadSelectedDrivers')
    $State.Controls.btnClearDriverList = $window.FindName('btnClearDriverList')
    $State.Controls.chkInstallOffice = $window.FindName('chkInstallOffice')
    $State.Controls.chkInstallApps = $window.FindName('chkInstallApps')
    $State.Controls.OfficePathStackPanel = $window.FindName('OfficePathStackPanel')
    $State.Controls.OfficePathGrid = $window.FindName('OfficePathGrid')
    $State.Controls.CopyOfficeConfigXMLStackPanel = $window.FindName('CopyOfficeConfigXMLStackPanel')
    $State.Controls.OfficeConfigurationXMLFileStackPanel = $window.FindName('OfficeConfigurationXMLFileStackPanel')
    $State.Controls.OfficeConfigurationXMLFileGrid = $window.FindName('OfficeConfigurationXMLFileGrid')
    $State.Controls.chkCopyOfficeConfigXML = $window.FindName('chkCopyOfficeConfigXML')
    $State.Controls.chkLatestCU = $window.FindName('chkUpdateLatestCU')
    $State.Controls.chkPreviewCU = $window.FindName('chkUpdatePreviewCU')
    $State.Controls.btnCheckUSBDrives = $window.FindName('btnCheckUSBDrives')
    $State.Controls.lstUSBDrives = $window.FindName('lstUSBDrives')
    $State.Controls.chkBuildUSBDriveEnable = $window.FindName('chkBuildUSBDriveEnable')
    $State.Controls.usbSection = $window.FindName('usbDriveSection')
    $State.Controls.chkSelectSpecificUSBDrives = $window.FindName('chkSelectSpecificUSBDrives')
    $State.Controls.usbSelectionPanel = $window.FindName('usbDriveSelectionPanel')
    $State.Controls.chkAllowExternalHardDiskMedia = $window.FindName('chkAllowExternalHardDiskMedia')
    $State.Controls.chkPromptExternalHardDiskMedia = $window.FindName('chkPromptExternalHardDiskMedia')
    $State.Controls.chkCopyAdditionalFFUFiles = $window.FindName('chkCopyAdditionalFFUFiles')
    $State.Controls.additionalFFUPanel = $window.FindName('additionalFFUPanel')
    $State.Controls.lstAdditionalFFUs = $window.FindName('lstAdditionalFFUs')
    $State.Controls.btnRefreshAdditionalFFUs = $window.FindName('btnRefreshAdditionalFFUs')
    $State.Controls.chkInstallWingetApps = $window.FindName('chkInstallWingetApps')
    $State.Controls.wingetPanel = $window.FindName('wingetPanel')
    $State.Controls.btnCheckWingetModule = $window.FindName('btnCheckWingetModule')
    $State.Controls.txtWingetVersion = $window.FindName('txtWingetVersion')
    $State.Controls.txtWingetModuleVersion = $window.FindName('txtWingetModuleVersion')
    $State.Controls.applicationPathPanel = $window.FindName('applicationPathPanel')
    $State.Controls.appListJsonPathPanel = $window.FindName('appListJsonPathPanel')
    $State.Controls.userAppListPathPanel = $window.FindName('userAppListPathPanel')
    $State.Controls.btnBrowseApplicationPath = $window.FindName('btnBrowseApplicationPath')
    $State.Controls.btnBrowseAppListJsonPath = $window.FindName('btnBrowseAppListJsonPath')
    $State.Controls.btnBrowseUserAppListPath = $window.FindName('btnBrowseUserAppListPath')
    $State.Controls.chkBringYourOwnApps = $window.FindName('chkBringYourOwnApps')
    $State.Controls.byoApplicationPanel = $window.FindName('byoApplicationPanel')
    $State.Controls.wingetSearchPanel = $window.FindName('wingetSearchPanel')
    $State.Controls.txtWingetSearch = $window.FindName('txtWingetSearch')
    $State.Controls.btnWingetSearch = $window.FindName('btnWingetSearch')
    $State.Controls.lstWingetResults = $window.FindName('lstWingetResults')
    $State.Controls.btnSaveWingetList = $window.FindName('btnSaveWingetList')
    $State.Controls.btnImportWingetList = $window.FindName('btnImportWingetList')
    $State.Controls.btnClearWingetList = $window.FindName('btnClearWingetList')
    $State.Controls.btnDownloadSelected = $window.FindName('btnDownloadSelected')
    $State.Controls.btnBrowseAppSource = $window.FindName('btnBrowseAppSource')
    $State.Controls.btnBrowseFFUDevPath = $window.FindName('btnBrowseFFUDevPath')
    $State.Controls.btnBrowseFFUCaptureLocation = $window.FindName('btnBrowseFFUCaptureLocation')
    $State.Controls.btnBrowseOfficePath = $window.FindName('btnBrowseOfficePath')
    $State.Controls.btnBrowseDriversFolder = $window.FindName('btnBrowseDriversFolder')
    $State.Controls.btnBrowsePEDriversFolder = $window.FindName('btnBrowsePEDriversFolder')
    $State.Controls.txtAppName = $window.FindName('txtAppName')
    $State.Controls.txtAppCommandLine = $window.FindName('txtAppCommandLine')
    $State.Controls.txtAppArguments = $window.FindName('txtAppArguments')
    $State.Controls.txtAppSource = $window.FindName('txtAppSource')
    $State.Controls.txtAppAdditionalExitCodes = $window.FindName('txtAppAdditionalExitCodes')
    $State.Controls.chkIgnoreExitCodes = $window.FindName('chkIgnoreExitCodes')
    $State.Controls.btnAddApplication = $window.FindName('btnAddApplication')
    $State.Controls.btnSaveBYOApplications = $window.FindName('btnSaveBYOApplications')
    $State.Controls.btnLoadBYOApplications = $window.FindName('btnLoadBYOApplications')
    $State.Controls.btnEditApplication = $window.FindName('btnEditApplication')
    $State.Controls.btnClearBYOApplications = $window.FindName('btnClearBYOApplications')
    $State.Controls.btnRemoveSelectedBYOApps = $window.FindName('btnRemoveSelectedBYOApps')
    $State.Controls.btnCopyBYOApps = $window.FindName('btnCopyBYOApps')
    $State.Controls.lstApplications = $window.FindName('lstApplications')
    $State.Controls.btnMoveTop = $window.FindName('btnMoveTop')
    $State.Controls.btnMoveUp = $window.FindName('btnMoveUp')
    $State.Controls.btnMoveDown = $window.FindName('btnMoveDown')
    $State.Controls.btnMoveBottom = $window.FindName('btnMoveBottom')
    $State.Controls.txtStatus = $window.FindName('txtStatus')
    $State.Controls.pbOverallProgress = $window.FindName('progressBar')
    $State.Controls.txtOverallStatus = $window.FindName('txtStatus')
    $State.Controls.chkEnableVMNetworking = $window.FindName('chkEnableVMNetworking')
    $State.Controls.spVMNetworkingSettings = $window.FindName('spVMNetworkingSettings')
    $State.Controls.cmbVMSwitchName = $window.FindName('cmbVMSwitchName')
    $State.Controls.txtCustomVMSwitchName = $window.FindName('txtCustomVMSwitchName')
    $State.Controls.txtFFUDevPath = $window.FindName('txtFFUDevPath')
    $State.Controls.txtCustomFFUNameTemplate = $window.FindName('txtCustomFFUNameTemplate')
    $State.Controls.txtFFUCaptureLocation = $window.FindName('txtFFUCaptureLocation')
    $State.Controls.txtThreads = $window.FindName('txtThreads')
    $State.Controls.cmbBitsPriority = $window.FindName('cmbBitsPriority')
    $State.Controls.txtMaxUSBDrives = $window.FindName('txtMaxUSBDrives')
    $State.Controls.chkCompactOS = $window.FindName('chkCompactOS')
    $State.Controls.chkOptimize = $window.FindName('chkOptimize')
    $State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching')
    $State.Controls.chkCreateDeploymentMedia = $window.FindName('chkCreateDeploymentMedia')
    $State.Controls.chkInjectUnattend = $window.FindName('chkInjectUnattend')
    $State.Controls.txtUnattendX64FilePath = $window.FindName('txtUnattendX64FilePath')
    $State.Controls.btnBrowseUnattendX64FilePath = $window.FindName('btnBrowseUnattendX64FilePath')
    $State.Controls.txtUnattendArm64FilePath = $window.FindName('txtUnattendArm64FilePath')
    $State.Controls.btnBrowseUnattendArm64FilePath = $window.FindName('btnBrowseUnattendArm64FilePath')
    $State.Controls.rbDeviceNamingNone = $window.FindName('rbDeviceNamingNone')
    $State.Controls.rbDeviceNamingPrompt = $window.FindName('rbDeviceNamingPrompt')
    $State.Controls.rbDeviceNamingTemplate = $window.FindName('rbDeviceNamingTemplate')
    $State.Controls.rbDeviceNamingPrefixes = $window.FindName('rbDeviceNamingPrefixes')
    $State.Controls.rbDeviceNamingSerialComputerNames = $window.FindName('rbDeviceNamingSerialComputerNames')
    $State.Controls.deviceNameTemplatePanel = $window.FindName('deviceNameTemplatePanel')
    $State.Controls.deviceNamePrefixesPanel = $window.FindName('deviceNamePrefixesPanel')
    $State.Controls.deviceNameSerialComputerNamesPanel = $window.FindName('deviceNameSerialComputerNamesPanel')
    $State.Controls.txtDeviceNameTemplate = $window.FindName('txtDeviceNameTemplate')
    $State.Controls.txtDeviceNamePrefixesPath = $window.FindName('txtDeviceNamePrefixesPath')
    $State.Controls.btnBrowseDeviceNamePrefixesPath = $window.FindName('btnBrowseDeviceNamePrefixesPath')
    $State.Controls.txtDeviceNamePrefixes = $window.FindName('txtDeviceNamePrefixes')
    $State.Controls.btnSaveDeviceNamePrefixes = $window.FindName('btnSaveDeviceNamePrefixes')
    $State.Controls.txtDeviceNameSerialComputerNamesPath = $window.FindName('txtDeviceNameSerialComputerNamesPath')
    $State.Controls.btnBrowseDeviceNameSerialComputerNamesPath = $window.FindName('btnBrowseDeviceNameSerialComputerNamesPath')
    $State.Controls.txtDeviceNameSerialComputerNames = $window.FindName('txtDeviceNameSerialComputerNames')
    $State.Controls.btnSaveDeviceNameSerialComputerNames = $window.FindName('btnSaveDeviceNameSerialComputerNames')
    $State.Controls.chkVerbose = $window.FindName('chkVerbose')
    $State.Controls.chkCopyAutopilot = $window.FindName('chkCopyAutopilot')
    $State.Controls.chkCopyUnattend = $window.FindName('chkCopyUnattend')
    $State.Controls.chkCopyPPKG = $window.FindName('chkCopyPPKG')
    $State.Controls.chkCleanupAppsISO = $window.FindName('chkCleanupAppsISO')
    $State.Controls.chkCleanupDeployISO = $window.FindName('chkCleanupDeployISO')
    $State.Controls.chkCleanupDrivers = $window.FindName('chkCleanupDrivers')
    $State.Controls.chkRemoveFFU = $window.FindName('chkRemoveFFU')
    $State.Controls.chkRemoveDownloadedESD = $window.FindName('chkRemoveDownloadedESD')
    $State.Controls.txtDiskSize = $window.FindName('txtDiskSize')
    $State.Controls.txtMemory = $window.FindName('txtMemory')
    $State.Controls.txtProcessors = $window.FindName('txtProcessors')
    $State.Controls.txtVMLocation = $window.FindName('txtVMLocation')
    $State.Controls.txtVMNamePrefix = $window.FindName('txtVMNamePrefix')
    $State.Controls.cmbSystemPartitionDriveLetter = $window.FindName('cmbSystemPartitionDriveLetter')
    $State.Controls.cmbWindowsPartitionDriveLetter = $window.FindName('cmbWindowsPartitionDriveLetter')
    $State.Controls.cmbRecoveryPartitionDriveLetter = $window.FindName('cmbRecoveryPartitionDriveLetter')
    $State.Controls.txtOSPartitionSizeGB = $window.FindName('txtOSPartitionSizeGB')
    $State.Controls.txtRecoveryPartitionSizeGB = $window.FindName('txtRecoveryPartitionSizeGB')
    $State.Controls.ellipseDiskLayoutCapacityStatus = $window.FindName('ellipseDiskLayoutCapacityStatus')
    $State.Controls.txtDiskLayoutCapacityStatusValue = $window.FindName('txtDiskLayoutCapacityStatusValue')
    $State.Controls.txtDataPartitionName = $window.FindName('txtDataPartitionName')
    $State.Controls.cmbDataPartitionDriveLetter = $window.FindName('cmbDataPartitionDriveLetter')
    $State.Controls.txtDataPartitionSizeGB = $window.FindName('txtDataPartitionSizeGB')
    $State.Controls.chkDataPartitionFillRemaining = $window.FindName('chkDataPartitionFillRemaining')
    $State.Controls.chkDataPartitionPersistDriveLetter = $window.FindName('chkDataPartitionPersistDriveLetter')
    $State.Controls.btnAddDataPartition = $window.FindName('btnAddDataPartition')
    $State.Controls.btnRemoveSelectedDataPartitions = $window.FindName('btnRemoveSelectedDataPartitions')
    $State.Controls.btnClearDataPartitions = $window.FindName('btnClearDataPartitions')
	$State.Controls.btnResetDiskLayoutToDefaults = $window.FindName('btnResetDiskLayoutToDefaults')
    $State.Controls.btnRestoreRecoveryPartition = $window.FindName('btnRestoreRecoveryPartition')
    $State.Controls.btnMoveDataPartitionTop = $window.FindName('btnMoveDataPartitionTop')
    $State.Controls.btnMoveDataPartitionUp = $window.FindName('btnMoveDataPartitionUp')
    $State.Controls.btnMoveDataPartitionDown = $window.FindName('btnMoveDataPartitionDown')
    $State.Controls.btnMoveDataPartitionBottom = $window.FindName('btnMoveDataPartitionBottom')
    $State.Controls.lstDataPartitions = $window.FindName('lstDataPartitions')
    $State.Controls.cmbLogicalSectorSize = $window.FindName('cmbLogicalSectorSize')
    $State.Controls.txtProductKey = $window.FindName('txtProductKey')
    $State.Controls.txtOfficePath = $window.FindName('txtOfficePath')
    $State.Controls.txtOfficeConfigXMLFilePath = $window.FindName('txtOfficeConfigXMLFilePath')
    $State.Controls.btnBrowseOfficeConfigXMLFile = $window.FindName('btnBrowseOfficeConfigXMLFile')
    $State.Controls.txtDriversFolder = $window.FindName('txtDriversFolder')
    $State.Controls.txtPEDriversFolder = $window.FindName('txtPEDriversFolder')
    $State.Controls.chkCopyPEDrivers = $window.FindName('chkCopyPEDrivers')
    $State.Controls.chkUseDriversAsPEDrivers = $window.FindName('chkUseDriversAsPEDrivers')
    $State.Controls.chkUpdateLatestCU = $window.FindName('chkUpdateLatestCU')
    $State.Controls.chkUpdateLatestNet = $window.FindName('chkUpdateLatestNet')
    $State.Controls.chkUpdateLatestDefender = $window.FindName('chkUpdateLatestDefender')
    $State.Controls.chkUpdateEdge = $window.FindName('chkUpdateEdge')
    $State.Controls.chkUpdateOneDrive = $window.FindName('chkUpdateOneDrive')
    $State.Controls.chkUpdateLatestMSRT = $window.FindName('chkUpdateLatestMSRT')
    $State.Controls.chkUpdatePreviewCU = $window.FindName('chkUpdatePreviewCU')
    $State.Controls.txtApplicationPath = $window.FindName('txtApplicationPath')
    $State.Controls.txtAppListJsonPath = $window.FindName('txtAppListJsonPath')
    $State.Controls.txtUserAppListPath = $window.FindName('txtUserAppListPath')
    $State.Controls.chkInstallDrivers = $window.FindName('chkInstallDrivers')
    $State.Controls.chkCopyDrivers = $window.FindName('chkCopyDrivers')
    $State.Controls.chkCompressDriversToWIM = $window.FindName('chkCompressDriversToWIM')
    $State.Controls.chkRemoveApps = $window.FindName('chkRemoveApps')
    $State.Controls.chkRemoveUpdates = $window.FindName('chkRemoveUpdates')
    $State.Controls.chkUpdateLatestMicrocode = $window.FindName('chkUpdateLatestMicrocode')
    $State.Controls.chkDefineAppsScriptVariables = $window.FindName('chkDefineAppsScriptVariables')
    $State.Controls.appsScriptVariablesPanel = $window.FindName('appsScriptVariablesPanel')
    $State.Controls.txtAppsScriptKey = $window.FindName('txtAppsScriptKey')
    $State.Controls.txtAppsScriptValue = $window.FindName('txtAppsScriptValue')
    $State.Controls.btnAddAppsScriptVariable = $window.FindName('btnAddAppsScriptVariable')
    $State.Controls.lstAppsScriptVariables = $window.FindName('lstAppsScriptVariables')
    $State.Controls.btnRemoveSelectedAppsScriptVariables = $window.FindName('btnRemoveSelectedAppsScriptVariables')
    $State.Controls.btnClearAppsScriptVariables = $window.FindName('btnClearAppsScriptVariables')
    $State.Controls.txtDriversJsonPath = $window.FindName('txtDriversJsonPath')
    $State.Controls.btnBrowseDriversJsonPath = $window.FindName('btnBrowseDriversJsonPath')
    $State.Controls.chkUpdateADK = $window.FindName('chkUpdateADK')
    $State.Controls.btnLoadConfig = $window.FindName('btnLoadConfig')
    $State.Controls.btnRestoreDefaults = $window.FindName('btnRestoreDefaults')
    $State.Controls.btnBuildConfig = $window.FindName('btnBuildConfig')

    # Home page
    $State.Controls.txtHomeCurrentBuildValue = $window.FindName('txtHomeCurrentBuildValue')
    $State.Controls.txtHomeLatestReleaseValue = $window.FindName('txtHomeLatestReleaseValue')
    $State.Controls.txtHomeReleaseStatusValue = $window.FindName('txtHomeReleaseStatusValue')
    $State.Controls.spHomeReleaseNotesSections = $window.FindName('spHomeReleaseNotesSections')
    $State.Controls.ellipseHomeDiskSpaceStatus = $window.FindName('ellipseHomeDiskSpaceStatus')
    $State.Controls.txtHomeDiskSpaceStatusValue = $window.FindName('txtHomeDiskSpaceStatusValue')
    $State.Controls.ellipseHomeHyperVStatus = $window.FindName('ellipseHomeHyperVStatus')
    $State.Controls.txtHomeHyperVStatusValue = $window.FindName('txtHomeHyperVStatusValue')
    $State.Controls.txtHomeDiscussionsStatusValue = $window.FindName('txtHomeDiscussionsStatusValue')
    $State.Controls.tbDiscussion1 = $window.FindName('tbDiscussion1')
    $State.Controls.linkDiscussion1 = $window.FindName('linkDiscussion1')
    $State.Controls.runDiscussion1 = $window.FindName('runDiscussion1')
    $State.Controls.tbDiscussion2 = $window.FindName('tbDiscussion2')
    $State.Controls.linkDiscussion2 = $window.FindName('linkDiscussion2')
    $State.Controls.runDiscussion2 = $window.FindName('runDiscussion2')
    $State.Controls.tbDiscussion3 = $window.FindName('tbDiscussion3')
    $State.Controls.linkDiscussion3 = $window.FindName('linkDiscussion3')
    $State.Controls.runDiscussion3 = $window.FindName('runDiscussion3')
    $State.Controls.tbDiscussion4 = $window.FindName('tbDiscussion4')
    $State.Controls.linkDiscussion4 = $window.FindName('linkDiscussion4')
    $State.Controls.runDiscussion4 = $window.FindName('runDiscussion4')
    $State.Controls.tbDiscussion5 = $window.FindName('tbDiscussion5')
    $State.Controls.linkDiscussion5 = $window.FindName('linkDiscussion5')
    $State.Controls.runDiscussion5 = $window.FindName('runDiscussion5')
    $State.Controls.tbDiscussionsLink = $window.FindName('tbDiscussionsLink')
    $State.Controls.linkDiscussions = $window.FindName('linkDiscussions')

    # Settings page
    $State.Controls.cmbThemeMode = $window.FindName('cmbThemeMode')

    # Shared page shell
    $State.Controls.txtPageTitle = $window.FindName('txtPageTitle')

    # Navigation controls
    $State.Controls.lstNavigation = $window.FindName('lstNavigation')
    $State.Controls.lstNavSettings = $window.FindName('lstNavSettings')
    $State.Controls.lstLogOutput = $window.FindName('lstLogOutput')

    # Content pages (for navigation visibility toggling)
    $State.Controls.navigationPages = @(
        $window.FindName('pageHome'),
        $window.FindName('pageHyperV'),
        $window.FindName('pageWindows'),
        $window.FindName('pageUpdates'),
        $window.FindName('pageApplications'),
        $window.FindName('pageOffice'),
        $window.FindName('pageDrivers'),
        $window.FindName('pageBuild'),
        $window.FindName('pageMonitor')
    )
    $State.Controls.pageSettings = $window.FindName('pageSettings')

    # Initialize and bind the log data collection
    $State.Data.logData = New-Object System.Collections.ObjectModel.ObservableCollection[string]
    $State.Controls.lstLogOutput.ItemsSource = $State.Data.logData
}

function Initialize-VMSwitchData {
    param([PSCustomObject]$State)

    WriteLog "Initializing VM Switch data..."
    
    # Hyper-V Settings: Populate VM Switch ComboBox
    $vmSwitchData = Get-VMSwitchData
    $State.Data.vmSwitchMap = $vmSwitchData.SwitchMap
    $State.Controls.cmbVMSwitchName.Items.Clear()
    foreach ($switchName in $vmSwitchData.SwitchNames) {
        $State.Controls.cmbVMSwitchName.Items.Add($switchName) | Out-Null
    }
    $State.Controls.cmbVMSwitchName.Items.Add('Other') | Out-Null
    if ($State.Controls.cmbVMSwitchName.Items.Count -gt 1) {
        $State.Controls.cmbVMSwitchName.SelectedIndex = 0
        $State.Controls.txtCustomVMSwitchName.Visibility = 'Collapsed'
    }
    else {
        $State.Controls.cmbVMSwitchName.SelectedItem = 'Other'
        $State.Controls.txtCustomVMSwitchName.Visibility = 'Visible'
    }
}

function Initialize-UIDefaults {
    param([PSCustomObject]$State)
    WriteLog "Initializing UI defaults..."

    # Get default values from helper functions
    $State.Defaults.windowsSettingsDefaults = Get-WindowsSettingsDefaults
    $State.Defaults.generalDefaults = Get-GeneralDefaults -FFUDevelopmentPath $State.FFUDevelopmentPath

    # Build tab defaults from General Defaults
    $State.Controls.txtFFUDevPath.Text = $State.FFUDevelopmentPath 
    $State.Controls.txtCustomFFUNameTemplate.Text = $State.Defaults.generalDefaults.CustomFFUNameTemplate
    $State.Controls.txtFFUCaptureLocation.Text = $State.Defaults.generalDefaults.FFUCaptureLocation
    $State.Controls.txtThreads.Text = $State.Defaults.generalDefaults.Threads
    $State.Controls.cmbBitsPriority.SelectedItem = $State.Defaults.generalDefaults.BitsPriority
    $State.Controls.txtMaxUSBDrives.Text = $State.Defaults.generalDefaults.MaxUSBDrives
    $State.Controls.chkBuildUSBDriveEnable.IsChecked = $State.Defaults.generalDefaults.BuildUSBDriveEnable
    $State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS
    $State.Controls.chkUpdateADK.IsChecked = $State.Defaults.generalDefaults.UpdateADK
    $State.Controls.chkOptimize.IsChecked = $State.Defaults.generalDefaults.Optimize
    $State.Controls.chkAllowVHDXCaching.IsChecked = $State.Defaults.generalDefaults.AllowVHDXCaching
    $State.Controls.chkInjectUnattend.IsChecked = $State.Defaults.generalDefaults.InjectUnattend
    $State.Controls.txtUnattendX64FilePath.Text = $State.Defaults.generalDefaults.UnattendX64FilePath
    $State.Controls.txtUnattendArm64FilePath.Text = $State.Defaults.generalDefaults.UnattendArm64FilePath
    $State.Controls.chkCreateDeploymentMedia.IsChecked = $State.Defaults.generalDefaults.CreateDeploymentMedia
    $State.Controls.chkAllowExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.AllowExternalHardDiskMedia
    $State.Controls.chkPromptExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.PromptExternalHardDiskMedia
    $State.Controls.chkSelectSpecificUSBDrives.IsChecked = $State.Defaults.generalDefaults.SelectSpecificUSBDrives
    $State.Controls.chkCopyAutopilot.IsChecked = $State.Defaults.generalDefaults.CopyAutopilot
    $State.Controls.chkCopyUnattend.IsChecked = $State.Defaults.generalDefaults.CopyUnattend
    $State.Controls.chkCopyPPKG.IsChecked = $State.Defaults.generalDefaults.CopyPPKG
    $defaultDeviceNamingMode = if ($State.Defaults.generalDefaults.DeviceNamingMode -in @('None', 'Prompt', 'Template', 'Prefixes', 'SerialComputerNames')) {
        $State.Defaults.generalDefaults.DeviceNamingMode
    }
    else {
        'None'
    }
    Set-DeviceNamingModeState -State $State -DisplayMode $defaultDeviceNamingMode -LoadedMode $null
    $State.Controls.txtDeviceNameTemplate.Text = $State.Defaults.generalDefaults.DeviceNameTemplate
    $State.Controls.txtDeviceNamePrefixesPath.Text = $State.Defaults.generalDefaults.DeviceNamePrefixesPath
    $State.Controls.txtDeviceNamePrefixes.Text = ($State.Defaults.generalDefaults.DeviceNamePrefixes -join [System.Environment]::NewLine)
    $State.Controls.txtDeviceNameSerialComputerNamesPath.Text = $State.Defaults.generalDefaults.DeviceNameSerialComputerNamesPath
    $State.Controls.txtDeviceNameSerialComputerNames.Text = ($State.Defaults.generalDefaults.DeviceNameSerialComputerNames -join [System.Environment]::NewLine)
    Import-DeviceNamePrefixesFromConfiguredPath -State $State
    Import-SerialComputerNamesFromConfiguredPath -State $State
    Update-DeviceNamingControls -State $State
    $State.Controls.chkCleanupAppsISO.IsChecked = $State.Defaults.generalDefaults.CleanupAppsISO
    $State.Controls.chkCleanupDeployISO.IsChecked = $State.Defaults.generalDefaults.CleanupDeployISO
    $State.Controls.chkCleanupDrivers.IsChecked = $State.Defaults.generalDefaults.CleanupDrivers
    $State.Controls.chkRemoveFFU.IsChecked = $State.Defaults.generalDefaults.RemoveFFU
    $State.Controls.chkRemoveApps.IsChecked = $State.Defaults.generalDefaults.RemoveApps
    $State.Controls.chkRemoveUpdates.IsChecked = $State.Defaults.generalDefaults.RemoveUpdates
    $State.Controls.chkRemoveDownloadedESD.IsChecked = $State.Defaults.generalDefaults.RemoveDownloadedESD
    $State.Controls.chkVerbose.IsChecked = $State.Defaults.generalDefaults.Verbose
    $State.Controls.usbSelectionPanel.Visibility = if ($State.Controls.chkSelectSpecificUSBDrives.IsChecked) { 'Visible' } else { 'Collapsed' }
    $State.Controls.chkSelectSpecificUSBDrives.IsEnabled = $State.Controls.chkBuildUSBDriveEnable.IsChecked
    $State.Controls.chkPromptExternalHardDiskMedia.IsEnabled = $State.Controls.chkAllowExternalHardDiskMedia.IsChecked
    $State.Controls.chkCopyAdditionalFFUFiles.IsChecked = $State.Defaults.generalDefaults.CopyAdditionalFFUFiles
    $State.Controls.additionalFFUPanel.Visibility = if ($State.Controls.chkCopyAdditionalFFUFiles.IsChecked) { 'Visible' } else { 'Collapsed' }
    Update-BitsPrioritySetting -State $State

    # Hyper-V Settings defaults from General Defaults
    $State.Controls.chkEnableVMNetworking.IsChecked = $State.Defaults.generalDefaults.EnableVMNetworking
    Initialize-VMSwitchData -State $State
    $State.Controls.spVMNetworkingSettings.IsEnabled = $true -eq $State.Controls.chkEnableVMNetworking.IsChecked
    $State.Controls.txtDiskSize.Text = $State.Defaults.generalDefaults.DiskSizeGB
    $State.Controls.txtMemory.Text = $State.Defaults.generalDefaults.MemoryGB
    $State.Controls.txtProcessors.Text = $State.Defaults.generalDefaults.Processors
    $State.Controls.txtVMLocation.Text = $State.Defaults.generalDefaults.VMLocation
    $State.Controls.txtVMNamePrefix.Text = $State.Defaults.generalDefaults.VMNamePrefix
    $State.Controls.cmbSystemPartitionDriveLetter.SelectedItem = ($State.Controls.cmbSystemPartitionDriveLetter.Items | Where-Object { $_.Content -eq $State.Defaults.generalDefaults.SystemPartitionDriveLetter })
    $State.Controls.cmbWindowsPartitionDriveLetter.SelectedItem = ($State.Controls.cmbWindowsPartitionDriveLetter.Items | Where-Object { $_.Content -eq $State.Defaults.generalDefaults.WindowsPartitionDriveLetter })
    $State.Controls.cmbRecoveryPartitionDriveLetter.SelectedItem = ($State.Controls.cmbRecoveryPartitionDriveLetter.Items | Where-Object { $_.Content -eq $State.Defaults.generalDefaults.RecoveryPartitionDriveLetter })
    $State.Controls.txtOSPartitionSizeGB.Clear()
    $State.Data.createRecoveryPartition = $true
    $State.Controls.cmbLogicalSectorSize.SelectedItem = ($State.Controls.cmbLogicalSectorSize.Items | Where-Object { $_.Content -eq $State.Defaults.generalDefaults.LogicalSectorSize.ToString() })
   
    # Populate Windows Release, Version, and SKU comboboxes
    # Initialize Windows settings combos based on media source mode
    $initIsoPath = $State.Defaults.windowsSettingsDefaults.DefaultISOPath
    if ($null -ne $State.Controls.rbProvideISO -and -not $State.Controls.rbProvideISO.IsChecked) {
        $initIsoPath = ''
    }
    Get-WindowsSettingsCombos -isoPath $initIsoPath -State $State
    
    # Windows Settings tab defaults
    $State.Controls.cmbWindowsLang.ItemsSource = $State.Defaults.windowsSettingsDefaults.AllowedLanguages
    $State.Controls.cmbWindowsLang.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultWindowsLang
    $State.Controls.cmbMediaType.ItemsSource = $State.Defaults.windowsSettingsDefaults.AllowedMediaTypes
    $State.Controls.cmbMediaType.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultMediaType
    $State.Controls.txtProductKey.Text = $State.Defaults.windowsSettingsDefaults.DefaultProductKey

    # Updates tab defaults from General Defaults
    $State.Controls.chkUpdateLatestCU.IsChecked = $State.Defaults.generalDefaults.UpdateLatestCU
    $State.Controls.chkUpdateLatestNet.IsChecked = $State.Defaults.generalDefaults.UpdateLatestNet
    $State.Controls.chkUpdateLatestDefender.IsChecked = $State.Defaults.generalDefaults.UpdateLatestDefender
    $State.Controls.chkUpdateEdge.IsChecked = $State.Defaults.generalDefaults.UpdateEdge
    $State.Controls.chkUpdateOneDrive.IsChecked = $State.Defaults.generalDefaults.UpdateOneDrive
    $State.Controls.chkUpdateLatestMSRT.IsChecked = $State.Defaults.generalDefaults.UpdateLatestMSRT
    $State.Controls.chkUpdateLatestMicrocode.IsChecked = $State.Defaults.generalDefaults.UpdateLatestMicrocode
    $State.Controls.chkUpdatePreviewCU.IsChecked = $State.Defaults.generalDefaults.UpdatePreviewCU
    # Set initial state for CU checkbox interplay
    $State.Controls.chkPreviewCU.IsEnabled = -not $State.Controls.chkLatestCU.IsChecked
    $State.Controls.chkLatestCU.IsEnabled = -not $State.Controls.chkPreviewCU.IsChecked

    # Applications tab defaults from General Defaults
    $State.Controls.chkInstallApps.IsChecked = $State.Defaults.generalDefaults.InstallApps
    $State.Controls.txtApplicationPath.Text = $State.Defaults.generalDefaults.ApplicationPath
    $State.Controls.txtAppListJsonPath.Text = $State.Defaults.generalDefaults.AppListJsonPath
    $State.Controls.txtUserAppListPath.Text = $State.Defaults.generalDefaults.UserAppListPath
    $State.Controls.chkInstallWingetApps.IsChecked = $State.Defaults.generalDefaults.InstallWingetApps
    $State.Controls.chkBringYourOwnApps.IsChecked = $State.Defaults.generalDefaults.BringYourOwnApps

    # M365 Apps/Office tab defaults from General Defaults
    $State.Controls.chkInstallOffice.IsChecked = $State.Defaults.generalDefaults.InstallOffice
    $State.Controls.txtOfficePath.Text = $State.Defaults.generalDefaults.OfficePath
    $State.Controls.chkCopyOfficeConfigXML.IsChecked = $State.Defaults.generalDefaults.CopyOfficeConfigXML
    $State.Controls.txtOfficeConfigXMLFilePath.Text = $State.Defaults.generalDefaults.OfficeConfigXMLFilePath

    # Drivers tab defaults from General Defaults
    $State.Controls.txtDriversFolder.Text = $State.Defaults.generalDefaults.DriversFolder
    $State.Controls.txtPEDriversFolder.Text = $State.Defaults.generalDefaults.PEDriversFolder
    $State.Controls.txtDriversJsonPath.Text = $State.Defaults.generalDefaults.DriversJsonPath
    $State.Controls.chkDownloadDrivers.IsChecked = $State.Defaults.generalDefaults.DownloadDrivers
    $State.Controls.chkInstallDrivers.IsChecked = $State.Defaults.generalDefaults.InstallDrivers
    $State.Controls.chkCopyDrivers.IsChecked = $State.Defaults.generalDefaults.CopyDrivers
    $State.Controls.chkCopyPEDrivers.IsChecked = $State.Defaults.generalDefaults.CopyPEDrivers
    $State.Controls.chkUseDriversAsPEDrivers.IsChecked = $State.Defaults.generalDefaults.UseDriversAsPEDrivers
    $State.Controls.chkCompressDriversToWIM.IsChecked = $State.Defaults.generalDefaults.CompressDownloadedDriversToWim

    # Drivers tab UI logic
    $makeList = @('Microsoft', 'Dell', 'HP', 'Lenovo')
    if ($null -ne $State.Controls.cmbMake) {
        # Clear existing items to prevent duplication on re-initialization (e.g., after Restore Defaults)
        $State.Controls.cmbMake.Items.Clear()
        foreach ($m in $makeList) {
            [void]$State.Controls.cmbMake.Items.Add($m)
        }
        if ($State.Controls.cmbMake.Items.Count -gt 0) {
            $State.Controls.cmbMake.SelectedIndex = 0
        }
    }
    Update-DriverDownloadPanelVisibility -State $State

    # Set initial state for driver checkbox interplay
    Update-DriverCheckboxStates -State $State

    # Set initial state for InstallApps checkbox based on updates
    Update-InstallAppsState -State $State

    # Set default theme mode and disable if Fluent is not supported
    if ($null -ne $State.Controls.cmbThemeMode) {
        $State.Controls.cmbThemeMode.SelectedItem = "System"
        if (-not $State.Flags.isFluentSupported) {
            $State.Controls.cmbThemeMode.IsEnabled = $false
            $State.Controls.cmbThemeMode.Tag = "Fluent theme requires PowerShell 7.5+ (.NET 9+). Best experience on PowerShell 7.6+ (.NET 10)."
        }
    }

    # Set default navigation selection to Home and initialize the shared page title
    if ($null -ne $State.Controls.lstNavigation) {
        $State.Controls.lstNavigation.SelectedIndex = 0

        # Keep the shell header aligned with the selected navigation item on first render
        if ($null -ne $State.Controls.txtPageTitle) {
            $selectedNavigationItem = $State.Controls.lstNavigation.SelectedItem
            if ($null -ne $selectedNavigationItem -and -not [string]::IsNullOrWhiteSpace([string]$selectedNavigationItem.Tag)) {
                $State.Controls.txtPageTitle.Text = [string]$selectedNavigationItem.Tag
            }
            else {
                $State.Controls.txtPageTitle.Text = 'Home'
            }
        }
    }

    # Set initial state for Office panel visibility
    Update-OfficePanelVisibility -State $State
    
    # Set initial state for Application panel visibility
    Update-ApplicationPanelVisibility -State $State
    
        # Set initial state for BYO Apps copy button
        Update-CopyButtonState -State $State
    
        # Apply accent color to primary action button only (per Windows design guidance)
        if ($State.Flags.isFluentSupported) {
            try {
                $State.Controls.btnRun = $State.Window.FindName('btnRun')
                if ($null -ne $State.Controls.btnRun) {
                    # Use SetResourceReference for live accent color updates when user changes Windows theme
                    $State.Controls.btnRun.SetResourceReference(
                        [System.Windows.Controls.Control]::BackgroundProperty,
                        [System.Windows.SystemColors]::AccentColorBrushKey
                    )
                    $State.Controls.btnRun.Foreground = [System.Windows.Media.Brushes]::White
                }
            }
            catch {
                WriteLog "Could not apply accent color to Build FFU button: $($_.Exception.Message)"
            }
        }
    }

function Initialize-DynamicUIElements {
    param([PSCustomObject]$State)
    WriteLog "Initializing dynamic UI elements (Grids, Columns)..."

    # Get the Fluent base style for ListViewItem in GridView mode
    # Must use GridViewItemContainerStyleKey (not the generic ListViewItem type key) because the
    # generic Fluent ListViewItem style has a template without GridViewRowPresenter, which breaks
    # column-based rendering and causes items to display their ToString() representation.
    $listViewItemBaseStyle = $State.Window.TryFindResource([System.Windows.Controls.GridView]::GridViewItemContainerStyleKey)

    # Driver Models ListView setup
    # Set ListViewItem style to stretch content horizontally so cell templates fill the cell
    $itemStyleDriverModels = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleDriverModels.BasedOn = $listViewItemBaseStyle }
    $itemStyleDriverModels.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstDriverModels.ItemContainerStyle = $itemStyleDriverModels

    $driverModelsGridView = New-Object System.Windows.Controls.GridView
    $State.Controls.lstDriverModels.View = $driverModelsGridView # Assign GridView to ListView first

    # Add the selectable column and scope header select-all to visible filtered rows.
    Add-SelectableGridViewColumn -ListView $State.Controls.lstDriverModels -State $State -HeaderCheckBoxKeyName "chkSelectAllDriverModels" -ColumnWidth 70 -HeaderSelectionAffectsVisibleItemsOnly

    # Add other sortable columns with left-aligned headers
    Add-SortableColumn -gridView $driverModelsGridView -header "Make" -binding "Make" -width 100 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $driverModelsGridView -header "Model" -binding "Model" -width 200 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $driverModelsGridView -header "Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left
    $State.Controls.lstDriverModels.AddHandler(
        [System.Windows.Controls.GridViewColumnHeader]::ClickEvent,
        [System.Windows.RoutedEventHandler] {
            param($eventSource, $e) # $eventSource is the ListView control
            $header = $e.OriginalSource
            if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) {
                # Retrieve the main UI state object from the window's Tag property
                $listViewControl = $eventSource
                $window = [System.Windows.Window]::GetWindow($listViewControl)
                $uiStateFromWindowTag = $window.Tag
                
                Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag
            }
        }
    )

    # Keep driver model columns sized to the current visible content.
    Enable-ListViewColumnAutoResize -ListView $State.Controls.lstDriverModels -FixedColumnIndexes @(0)

    # Winget Search ListView setup
    $wingetGridView = New-Object System.Windows.Controls.GridView
    $State.Controls.lstWingetResults.View = $wingetGridView # Assign GridView to ListView first

    # Set ListViewItem style to stretch content horizontally so cell templates fill the cell
    $itemStyleWingetResults = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleWingetResults.BasedOn = $listViewItemBaseStyle }
    $itemStyleWingetResults.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstWingetResults.ItemContainerStyle = $itemStyleWingetResults

    # Add the selectable column using the new function
    Add-SelectableGridViewColumn -ListView $State.Controls.lstWingetResults -State $State -HeaderCheckBoxKeyName "chkSelectAllWingetResults" -ColumnWidth 60

    # Add other sortable columns with left-aligned headers
    Add-SortableColumn -gridView $wingetGridView -header "Name" -binding "Name" -width 200 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $wingetGridView -header "Id" -binding "Id" -width 200 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $wingetGridView -header "Version" -binding "Version" -width 100 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $wingetGridView -header "Source" -binding "Source" -width 100 -headerHorizontalAlignment Left

    # --- START: Add Architecture Column ---
    $archColumn = New-Object System.Windows.Controls.GridViewColumn
    $archHeader = New-Object System.Windows.Controls.GridViewColumnHeader
    $archHeader.Tag = "Architecture" # For sorting
    $archHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
    
    # Create header content with correct padding to match other columns
    $commonPaddingForHeader = New-Object System.Windows.Thickness(5, 2, 5, 2)
    $headerTextElementFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.TextBlock])
    $headerTextElementFactory.SetValue([System.Windows.Controls.TextBlock]::TextProperty, "Architecture")
    $headerTextBlockPadding = New-Object System.Windows.Thickness($commonPaddingForHeader.Left, $commonPaddingForHeader.Top, $commonPaddingForHeader.Right, $commonPaddingForHeader.Bottom)
    $headerTextElementFactory.SetValue([System.Windows.Controls.TextBlock]::PaddingProperty, $headerTextBlockPadding)
    $headerTextElementFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)
    
    $headerDataTemplate = New-Object System.Windows.DataTemplate
    $headerDataTemplate.VisualTree = $headerTextElementFactory
    $archHeader.ContentTemplate = $headerDataTemplate
    
    $archColumn.Header = $archHeader
    $archColumn.Width = 120

    # Create the CellTemplate with a ComboBox
    $archCellTemplate = New-Object System.Windows.DataTemplate
    $comboBoxFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.ComboBox])
    
    # The ItemsSource for the ComboBox
    $availableArchitectures = @('x86', 'x64', 'arm64', 'x86 x64', 'NA')
    $comboBoxFactory.SetValue([System.Windows.Controls.ItemsControl]::ItemsSourceProperty, $availableArchitectures)

    # Bind the text property to the 'Architecture' property of the data item.
    # This ensures the initial value is displayed correctly.
    $binding = New-Object System.Windows.Data.Binding("Architecture")
    $binding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $comboBoxFactory.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $binding)

    # Create a style to disable the ComboBox for 'msstore' source, inheriting the Fluent base style
    $comboBoxStyle = New-Object System.Windows.Style
    $comboBoxStyle.TargetType = [System.Windows.Controls.ComboBox]
    $comboBoxBaseStyle = $State.Window.TryFindResource([System.Windows.Controls.ComboBox])
    if ($null -ne $comboBoxBaseStyle) { $comboBoxStyle.BasedOn = $comboBoxBaseStyle }
    
    $dataTrigger = New-Object System.Windows.DataTrigger
    $dataTrigger.Binding = New-Object System.Windows.Data.Binding("Source")
    $dataTrigger.Value = "msstore"
    $dataTrigger.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ComboBox]::IsEnabledProperty, $false)))
    
    $comboBoxStyle.Triggers.Add($dataTrigger)
    $comboBoxFactory.SetValue([System.Windows.FrameworkElement]::StyleProperty, $comboBoxStyle)

    $archCellTemplate.VisualTree = $comboBoxFactory
    $archColumn.CellTemplate = $archCellTemplate
    $wingetGridView.Columns.Add($archColumn)
    # --- END: Add Architecture Column ---

    # --- START: Add Additional Exit Codes Column ---
    $exitCodesColumn = New-Object System.Windows.Controls.GridViewColumn
    $exitCodesHeader = New-Object System.Windows.Controls.GridViewColumnHeader
    $exitCodesHeader.Tag = "AdditionalExitCodes"
    $exitCodesHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left

    $exitHeaderTextFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.TextBlock])
    $exitHeaderTextFactory.SetValue([System.Windows.Controls.TextBlock]::TextProperty, "Additional Exit Codes")
    $exitHeaderTextFactory.SetValue([System.Windows.Controls.TextBlock]::PaddingProperty, (New-Object System.Windows.Thickness(5, 2, 5, 2)))
    $exitHeaderTextFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)

    $exitHeaderTemplate = New-Object System.Windows.DataTemplate
    $exitHeaderTemplate.VisualTree = $exitHeaderTextFactory
    $exitCodesHeader.ContentTemplate = $exitHeaderTemplate

    $exitCodesColumn.Header = $exitCodesHeader
    $exitCodesColumn.Width = 140

    $exitCodesCellTemplate = New-Object System.Windows.DataTemplate
    $exitCodesTextBoxFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.TextBox])
    $exitBinding = New-Object System.Windows.Data.Binding("AdditionalExitCodes")
    $exitBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $exitCodesTextBoxFactory.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $exitBinding)
    $exitCodesCellTemplate.VisualTree = $exitCodesTextBoxFactory
    $exitCodesColumn.CellTemplate = $exitCodesCellTemplate
    $wingetGridView.Columns.Add($exitCodesColumn)
    # --- END: Add Additional Exit Codes Column ---

    # --- START: Add Ignore Non-Zero Exit Codes Column ---
    $ignoreColumn = New-Object System.Windows.Controls.GridViewColumn
    $ignoreHeader = New-Object System.Windows.Controls.GridViewColumnHeader
    $ignoreHeader.Tag = "IgnoreNonZeroExitCodes"
    $ignoreHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left

    $ignoreHeaderTextFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.TextBlock])
    $ignoreHeaderTextFactory.SetValue([System.Windows.Controls.TextBlock]::TextProperty, "Ignore Exit Codes")
    $ignoreHeaderTextFactory.SetValue([System.Windows.Controls.TextBlock]::PaddingProperty, (New-Object System.Windows.Thickness(5, 2, 5, 2)))
    $ignoreHeaderTextFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)

    $ignoreHeaderTemplate = New-Object System.Windows.DataTemplate
    $ignoreHeaderTemplate.VisualTree = $ignoreHeaderTextFactory
    $ignoreHeader.ContentTemplate = $ignoreHeaderTemplate

    $ignoreColumn.Header = $ignoreHeader
    $ignoreColumn.Width = 140

    $ignoreCellTemplate = New-Object System.Windows.DataTemplate

    # Center the checkbox in the cell
    $ignoreCellGridFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Grid])
    $ignoreCellGridFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)
    $ignoreCellGridFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Stretch)

    $ignoreCheckFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.CheckBox])
    $ignoreCheckFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Center)
    $ignoreCheckFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)

    $ignoreBinding = New-Object System.Windows.Data.Binding("IgnoreNonZeroExitCodes")
    $ignoreBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $ignoreCheckFactory.SetBinding([System.Windows.Controls.Primitives.ToggleButton]::IsCheckedProperty, $ignoreBinding)

    # Build the visual tree: Grid -> CheckBox
    $ignoreCellGridFactory.AppendChild($ignoreCheckFactory)
    $ignoreCellTemplate.VisualTree = $ignoreCellGridFactory

    $ignoreColumn.CellTemplate = $ignoreCellTemplate
    $wingetGridView.Columns.Add($ignoreColumn)
    # --- END: Add Ignore Non-Zero Exit Codes Column ---

    Add-SortableColumn -gridView $wingetGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left
    $State.Controls.lstWingetResults.AddHandler(
        [System.Windows.Controls.GridViewColumnHeader]::ClickEvent,
        [System.Windows.RoutedEventHandler] {
            param($eventSource, $e) # $eventSource is the ListView control
            $header = $e.OriginalSource
            if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) {
                # Retrieve the main UI state object from the window's Tag property
                $listViewControl = $eventSource
                $window = [System.Windows.Window]::GetWindow($listViewControl)
                $uiStateFromWindowTag = $window.Tag
                
                Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag
            }
        }
    )

    # Keep Winget result columns sized to the current visible content.
    Enable-ListViewColumnAutoResize -ListView $State.Controls.lstWingetResults -FixedColumnIndexes @(0)

    # BYO Applications ListView setup
    $byoAppsGridView = New-Object System.Windows.Controls.GridView
    $State.Controls.lstApplications.View = $byoAppsGridView

    # Set ListViewItem style to stretch content horizontally
    $itemStyleBYOApps = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleBYOApps.BasedOn = $listViewItemBaseStyle }
    $itemStyleBYOApps.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstApplications.ItemContainerStyle = $itemStyleBYOApps

    # Add the selectable column
    Add-SelectableGridViewColumn -ListView $State.Controls.lstApplications -State $State -HeaderCheckBoxKeyName "chkSelectAllBYOApps" -ColumnWidth 60

    # Add other sortable columns
    Add-SortableColumn -gridView $byoAppsGridView -header "Priority" -binding "Priority" -width 60 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Name" -binding "Name" -width 150 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Command Line" -binding "CommandLine" -width 200 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Arguments" -binding "Arguments" -width 200 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Source" -binding "Source" -width 150 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Exit Codes" -binding "AdditionalExitCodes" -width 100 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Ignore Exit Codes" -binding "IgnoreExitCodes" -width 120 -headerHorizontalAlignment Left
    Add-SortableColumn -gridView $byoAppsGridView -header "Copy Status" -binding "CopyStatus" -width 150 -headerHorizontalAlignment Left

    # Keep BYO application columns sized to the current visible content.
    Enable-ListViewColumnAutoResize -ListView $State.Controls.lstApplications -FixedColumnIndexes @(0)

    # Disk Layout ListView setup
    $diskLayoutGridView = New-Object System.Windows.Controls.GridView
    $State.Controls.lstDataPartitions.View = $diskLayoutGridView

    $itemStyleDataPartitions = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleDataPartitions.BasedOn = $listViewItemBaseStyle }
    $itemStyleDataPartitions.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstDataPartitions.ItemContainerStyle = $itemStyleDataPartitions

    Add-SelectableGridViewColumn -ListView $State.Controls.lstDataPartitions -State $State -HeaderCheckBoxKeyName "chkSelectAllDataPartitions" -ColumnWidth 60 -IsSelectablePropertyName "CanSelect" -HeaderToolTip "Select all removable partitions in the disk layout." -ItemToolTip "Select this partition for removal. System, MSR, and Windows partitions cannot be removed."
    Add-SortableColumn -gridView $diskLayoutGridView -header "Name" -binding "Name" -width 180 -headerHorizontalAlignment Left

    $driveLetterColumn = New-Object System.Windows.Controls.GridViewColumn
    $driveLetterColumn.Header = "Drive Letter"
    $driveLetterColumn.Width = 120
    $driveLetterTemplate = New-Object System.Windows.DataTemplate
    $driveLetterFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.ComboBox])
    $driveLetterFactory.SetBinding([System.Windows.Controls.ItemsControl]::ItemsSourceProperty, (New-Object System.Windows.Data.Binding("DriveLetterOptions")))
    $driveLetterBinding = New-Object System.Windows.Data.Binding("DriveLetter")
    $driveLetterBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $driveLetterBinding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged
    $driveLetterFactory.SetBinding([System.Windows.Controls.Primitives.Selector]::SelectedItemProperty, $driveLetterBinding)
    $driveLetterFactory.SetBinding([System.Windows.Controls.Control]::IsEnabledProperty, (New-Object System.Windows.Data.Binding("CanEditDriveLetter")))
    $driveLetterTemplate.VisualTree = $driveLetterFactory
    $driveLetterColumn.CellTemplate = $driveLetterTemplate
    $diskLayoutGridView.Columns.Add($driveLetterColumn)

    $sizeColumn = New-Object System.Windows.Controls.GridViewColumn
    $sizeColumn.Header = "Size (GB)"
    $sizeColumn.Width = 120
    $sizeTemplate = New-Object System.Windows.DataTemplate
    $sizeFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.TextBox])
    $sizeBinding = New-Object System.Windows.Data.Binding("SizeGB")
    $sizeBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $sizeBinding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged
    $sizeFactory.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $sizeBinding)
    $sizeFactory.SetBinding([System.Windows.Controls.Control]::IsEnabledProperty, (New-Object System.Windows.Data.Binding("CanEditSize")))
    $sizeTemplate.VisualTree = $sizeFactory
    $sizeColumn.CellTemplate = $sizeTemplate
    $diskLayoutGridView.Columns.Add($sizeColumn)

    $fillRemainingColumn = New-Object System.Windows.Controls.GridViewColumn
    $fillRemainingColumn.Header = "Fill Remaining"
    $fillRemainingColumn.Width = 140
    $fillRemainingTemplate = New-Object System.Windows.DataTemplate
    $fillRemainingGridFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Grid])
    $fillRemainingGridFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)
    $fillRemainingFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.CheckBox])
    $fillRemainingFactory.SetValue([System.Windows.FrameworkElement]::TagProperty, 'DiskLayoutFillRemaining')
    $fillRemainingFactory.SetValue([System.Windows.Controls.Control]::ToolTipProperty, 'Use all remaining VHDX space for this partition. Only one partition can fill remaining space.')
    $fillRemainingFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Center)
    $fillRemainingFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)
    $fillRemainingBinding = New-Object System.Windows.Data.Binding("FillRemaining")
    $fillRemainingBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $fillRemainingBinding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged
    $fillRemainingFactory.SetBinding([System.Windows.Controls.Primitives.ToggleButton]::IsCheckedProperty, $fillRemainingBinding)
    $fillRemainingFactory.SetBinding([System.Windows.Controls.Control]::IsEnabledProperty, (New-Object System.Windows.Data.Binding("CanEditFillRemaining")))
    $fillRemainingFactory.SetBinding([System.Windows.UIElement]::VisibilityProperty, (New-Object System.Windows.Data.Binding("FillRemainingVisibility")))
    $fillRemainingGridFactory.AppendChild($fillRemainingFactory)
    $fillRemainingTemplate.VisualTree = $fillRemainingGridFactory
    $fillRemainingColumn.CellTemplate = $fillRemainingTemplate
    $diskLayoutGridView.Columns.Add($fillRemainingColumn)

    $persistDriveLetterColumn = New-Object System.Windows.Controls.GridViewColumn
    $persistDriveLetterColumn.Header = "Persist Drive Letter"
    $persistDriveLetterColumn.Width = 160
    $persistDriveLetterTemplate = New-Object System.Windows.DataTemplate
    $persistDriveLetterGridFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Grid])
    $persistDriveLetterGridFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)
    $persistDriveLetterFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.CheckBox])
    $persistDriveLetterFactory.SetValue([System.Windows.Controls.Control]::ToolTipProperty, 'Use the configured letter on physical devices. If cleared, deployed Windows assigns the next available letter from D: upward. The build VM always uses the configured letter. FFU deployment USB letters may be shifted.')
    $persistDriveLetterFactory.SetValue([System.Windows.FrameworkElement]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Center)
    $persistDriveLetterFactory.SetValue([System.Windows.FrameworkElement]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)
    $persistDriveLetterBinding = New-Object System.Windows.Data.Binding("PersistDriveLetter")
    $persistDriveLetterBinding.Mode = [System.Windows.Data.BindingMode]::TwoWay
    $persistDriveLetterBinding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged
    $persistDriveLetterFactory.SetBinding([System.Windows.Controls.Primitives.ToggleButton]::IsCheckedProperty, $persistDriveLetterBinding)
    $persistDriveLetterFactory.SetBinding([System.Windows.Controls.Control]::IsEnabledProperty, (New-Object System.Windows.Data.Binding("CanEditPersistDriveLetter")))
    $persistDriveLetterFactory.SetBinding([System.Windows.UIElement]::VisibilityProperty, (New-Object System.Windows.Data.Binding("PersistDriveLetterVisibility")))
    $persistDriveLetterGridFactory.AppendChild($persistDriveLetterFactory)
    $persistDriveLetterTemplate.VisualTree = $persistDriveLetterGridFactory
    $persistDriveLetterColumn.CellTemplate = $persistDriveLetterTemplate
    $diskLayoutGridView.Columns.Add($persistDriveLetterColumn)

    Update-AdditionalDataPartitionsListView -State $State

    # Apps Script Variables ListView setup
    # Bind ItemsSource to the data list
    $State.Controls.lstAppsScriptVariables.ItemsSource = $State.Data.appsScriptVariablesDataList.ToArray()

    # Set ListViewItem style to stretch content horizontally so cell templates fill the cell
    $itemStyleAppsScriptVars = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleAppsScriptVars.BasedOn = $listViewItemBaseStyle }
    $itemStyleAppsScriptVars.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstAppsScriptVariables.ItemContainerStyle = $itemStyleAppsScriptVars

    # The GridView for lstAppsScriptVariables is defined in XAML. We need to get it and add the column.
    if ($State.Controls.lstAppsScriptVariables.View -is [System.Windows.Controls.GridView]) {
        Add-SelectableGridViewColumn -ListView $State.Controls.lstAppsScriptVariables -State $State -HeaderCheckBoxKeyName "chkSelectAllAppsScriptVariables" -ColumnWidth 60

        # Make Key and Value columns sortable
        $appsScriptVarsGridView = $State.Controls.lstAppsScriptVariables.View

        # Key Column (should be at index 1 after selectable column is inserted at 0)
        if ($appsScriptVarsGridView.Columns.Count -gt 1) {
            $keyColumn = $appsScriptVarsGridView.Columns[1]
            $keyHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $keyHeader.Content = "Key"
            $keyHeader.Tag = "Key" # Property to sort by
            $keyHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $keyColumn.Header = $keyHeader
        }

        # Value Column (should be at index 2)
        if ($appsScriptVarsGridView.Columns.Count -gt 2) {
            $valueColumn = $appsScriptVarsGridView.Columns[2]
            $valueHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $valueHeader.Content = "Value"
            $valueHeader.Tag = "Value" # Property to sort by
            $valueHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $valueColumn.Header = $valueHeader
        }

        # Add Click event handler for sorting
        $State.Controls.lstAppsScriptVariables.AddHandler(
            [System.Windows.Controls.GridViewColumnHeader]::ClickEvent,
            [System.Windows.RoutedEventHandler] {
                param($eventSource, $e) # $eventSource is the ListView control
                $header = $e.OriginalSource
                if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) {
                    # Retrieve the main UI state object from the window's Tag property
                    $listViewControl = $eventSource
                    $window = [System.Windows.Window]::GetWindow($listViewControl)
                    $uiStateFromWindowTag = $window.Tag
                
                    Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag
                }
            }
        )

        # Keep apps script variable columns sized to the current visible content.
        Enable-ListViewColumnAutoResize -ListView $State.Controls.lstAppsScriptVariables -FixedColumnIndexes @(0)
    }
    else {
        WriteLog "Warning: lstAppsScriptVariables.View is not a GridView. Selectable column not added, and sorting cannot be enabled."
    }

    # Build dynamic multi-column checkboxes for optional features
    if ($State.Controls.featuresPanel -and $State.Defaults.windowsSettingsDefaults) {
        BuildFeaturesGrid -parent $State.Controls.featuresPanel -allowedFeatures $State.Defaults.windowsSettingsDefaults.AllowedFeatures -State $State
    }
    else {
        WriteLog "Initialize-DynamicUIElements: Could not build features grid. Panel or defaults missing."
    }
    
    # USB Drives ListView setup
    # Set ListViewItem style to stretch content horizontally so cell templates fill the cell
    $itemStyleUSBDrives = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleUSBDrives.BasedOn = $listViewItemBaseStyle }
    $itemStyleUSBDrives.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstUSBDrives.ItemContainerStyle = $itemStyleUSBDrives
    
    if ($State.Controls.lstUSBDrives.View -is [System.Windows.Controls.GridView]) {
        # Add the selectable column using the shared function
        Add-SelectableGridViewColumn -ListView $State.Controls.lstUSBDrives -State $State -HeaderCheckBoxKeyName "chkSelectAllUSBDrivesHeader" -ColumnWidth 70
    
        # Make other columns sortable
        $usbDrivesGridView = $State.Controls.lstUSBDrives.View
            
        # Model Column (index 0 in XAML, now 1)
        if ($usbDrivesGridView.Columns.Count -gt 1) {
            $modelColumn = $usbDrivesGridView.Columns[1]
            $modelHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $modelHeader.Content = "Model"
            $modelHeader.Tag = "Model" # Property to sort by
            $modelHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $modelColumn.Header = $modelHeader
        }
    
        # Unique ID Column (index 1 in XAML, now 2)
        if ($usbDrivesGridView.Columns.Count -gt 2) {
            $uniqueIdColumn = $usbDrivesGridView.Columns[2]
            $uniqueIdHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $uniqueIdHeader.Content = "Unique ID"
            $uniqueIdHeader.Tag = "UniqueId" # Property to sort by
            $uniqueIdHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $uniqueIdColumn.Header = $uniqueIdHeader
        }
    
        # Size Column (index 2 in XAML, now 3)
        if ($usbDrivesGridView.Columns.Count -gt 3) {
            $sizeColumn = $usbDrivesGridView.Columns[3]
            $sizeHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $sizeHeader.Content = "Size (GB)"
            $sizeHeader.Tag = "Size" # Property to sort by
            $sizeHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $sizeColumn.Header = $sizeHeader
        }
    
        # Add Click event handler for sorting
        $State.Controls.lstUSBDrives.AddHandler(
            [System.Windows.Controls.GridViewColumnHeader]::ClickEvent,
            [System.Windows.RoutedEventHandler] {
                param($eventSource, $e) # $eventSource is the ListView control
                $header = $e.OriginalSource
                if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) {
                    # Retrieve the main UI state object from the window's Tag property
                    $listViewControl = $eventSource
                    $window = [System.Windows.Window]::GetWindow($listViewControl)
                    $uiStateFromWindowTag = $window.Tag
                        
                    Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag
                }
            }
        )

        # Keep USB drive columns sized to the current visible content.
        Enable-ListViewColumnAutoResize -ListView $State.Controls.lstUSBDrives -FixedColumnIndexes @(0)
    }
    else {
        WriteLog "Warning: lstUSBDrives.View is not a GridView. Selectable column not added, and sorting cannot be enabled."
    }
    
    # Additional FFUs ListView setup
    $itemStyleAdditionalFFUs = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem])
    if ($null -ne $listViewItemBaseStyle) { $itemStyleAdditionalFFUs.BasedOn = $listViewItemBaseStyle }
    $itemStyleAdditionalFFUs.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch)))
    $State.Controls.lstAdditionalFFUs.ItemContainerStyle = $itemStyleAdditionalFFUs
    
    if ($State.Controls.lstAdditionalFFUs.View -is [System.Windows.Controls.GridView]) {
        Add-SelectableGridViewColumn -ListView $State.Controls.lstAdditionalFFUs -State $State -HeaderCheckBoxKeyName "chkSelectAllAdditionalFFUs" -ColumnWidth 70
    
        $additionalFFUsGridView = $State.Controls.lstAdditionalFFUs.View
    
        if ($additionalFFUsGridView.Columns.Count -gt 1) {
            $nameColumn = $additionalFFUsGridView.Columns[1]
            $nameHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $nameHeader.Content = "FFU Name"
            $nameHeader.Tag = "Name"
            $nameHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $nameColumn.Header = $nameHeader
        }
        if ($additionalFFUsGridView.Columns.Count -gt 2) {
            $lastModColumn = $additionalFFUsGridView.Columns[2]
            $lastModHeader = New-Object System.Windows.Controls.GridViewColumnHeader
            $lastModHeader.Content = "Last Modified"
            $lastModHeader.Tag = "LastModified"
            $lastModHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left
            $lastModColumn.Header = $lastModHeader
        }
    
        $State.Controls.lstAdditionalFFUs.AddHandler(
            [System.Windows.Controls.GridViewColumnHeader]::ClickEvent,
            [System.Windows.RoutedEventHandler] {
                param($eventSource, $e)
                $header = $e.OriginalSource
                if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) {
                    $listViewControl = $eventSource
                    $window = [System.Windows.Window]::GetWindow($listViewControl)
                    $uiStateFromWindowTag = $window.Tag
                    Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag
                }
            }
        )

        # Keep additional FFU columns sized to the current visible content.
        Enable-ListViewColumnAutoResize -ListView $State.Controls.lstAdditionalFFUs -FixedColumnIndexes @(0)
    }
    else {
        WriteLog "Warning: lstAdditionalFFUs.View is not a GridView. Selectable column not added, and sorting cannot be enabled."
    }
}


Export-ModuleMember -Function *
