universal-intel-wifi-bt-driver-updater.ps1

<#PSScriptInfo
.VERSION 2026.06.0006
.GUID b3a72f1e-9c4d-4b8a-a1f2-83d5e6c09f12
.NAME universal-intel-wifi-bt-driver-updater
.AUTHOR Marcin Grygiel
.COMPANYNAME FirstEver.tech
.COPYRIGHT (c) 2025-2026 Marcin Grygiel / FirstEver.tech. All rights reserved.
.TAGS Universal Intel Wi-Fi Bluetooth Drivers Updater CAB Windows Automation
.LICENSEURI https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/blob/main/LICENSE
.PROJECTURI https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater
.ICONURI https://raw.githubusercontent.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/main/icon.png
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
v2026.06.0006 - Bug fixes: added missing USB BT PID 0043 (AX211) to supported device list.
               Fixed incorrect Legacy flag shown for PCI Bluetooth devices when USB has a newer version.
               Fixed PCI legacy fallback in scanner (dead code corrected in v4.5 scanner).
               Author line in Show-FinalCredits aligned with Show-Header.
v2026.06.0006 - Added support for Intel Bluetooth PCI Enumerator devices.
               Detects PCI\VEN_8086&DEV_xxxx hardware IDs.
               Uses shared CAB package (intel-bt-<version>_pci.cab) for all PCI devices.
               Updated banner: version 2026.06.0006, author line, removed GitHub visit line.
               All comments are now in English.
#>


<#
.SYNOPSIS
    Detects and installs the latest Intel Wi-Fi and Bluetooth drivers.

.DESCRIPTION
    Automatically detects, downloads, and installs the latest Intel Wi-Fi (Wi-Fi 5/6/6E/7)
    and Bluetooth drivers (both USB and PCI variants) for your specific hardware.
    Compares installed driver versions against the latest available release,
    then downloads and installs the correct CAB driver package(s).

    Security: full SHA-256 hash verification and Microsoft WHCP digital signature validation
    before installation. Automatic System Restore Point created before any changes.

    Requires Administrator privileges (auto-elevates if needed) and internet access
    to GitHub. Downloads are verified before installation - no unverified files are
    ever installed.

    Supports silent unattended deployment via -quiet flag.

    Usage: .\universal-intel-wifi-bt-driver-updater.ps1 [options]

Options:
  -help, -? Display this help and exit.
  -version, -v Display the tool version and exit.
  -auto, -a All prompts are answered with Yes, no user interaction required.
  -quiet, -q Run in completely silent mode (no console window). Implies -auto.
  -beta Use beta database for new hardware testing.
  -debug, -d Enable debug output.
  -skipverify, -s Skip script self-hash verification. Use only for testing.

    Logging: All actions are logged to %ProgramData%\wifi_bt_update.log.

.PARAMETER version
    Display the tool version and exit.

.PARAMETER auto
    Run in automatic mode - all prompts are answered with Yes.

.PARAMETER quiet
    Run in completely silent mode with no console window. Implies -auto.

.PARAMETER beta
    Use the beta database for testing new hardware support.

.PARAMETER debug
    Enable debug output.

.PARAMETER skipverify
    Skip the script self-hash verification.

.EXAMPLE
    .\universal-intel-wifi-bt-driver-updater.ps1
    Runs the updater interactively.

.EXAMPLE
    .\universal-intel-wifi-bt-driver-updater.ps1 -auto
    Runs without any user prompts.

.EXAMPLE
    .\universal-intel-wifi-bt-driver-updater.ps1 -quiet
    Runs completely silently. Suitable for MDM deployment.

.NOTES
    Author: Marcin Grygiel / FirstEver.tech
    License: MIT

    All actions are logged to %ProgramData%\wifi_bt_update.log.

    This tool is not affiliated with Intel Corporation.
    Drivers are sourced from official Intel / Windows Update servers.
    Use at your own risk.

.LINK
    https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater
#>


# =============================================
# COMMAND-LINE PARAMETERS - MANUAL PARSING
# =============================================
$rawArgs = $args
$Help = $false
$Version = $false
$AutoMode = $false
$Debug = $false
$SkipVerification = $false
$QuietMode = $false
$Beta = $false
$Developer = $false

$allowedSwitches = @(
    '-help', '-?',
    '-version', '-v',
    '-auto', '-a',
    '-beta',
    '-developer',
    '-debug', '-d',
    '-skipverify', '-s',
    '-quiet', '-q'
)

for ($i = 0; $i -lt $rawArgs.Count; $i++) {
    $arg = $rawArgs[$i]
    if ($arg -match '^-') {
        if ($allowedSwitches -notcontains $arg) {
            Clear-Host
            Write-Host ""
            Write-Host " Unknown parameter: $arg"
            Write-Host " Use -help or -? to see available options."
            Write-Host ""
            exit 1
        }
        switch -Regex ($arg) {
            '^-help$'                { $Help = $true }
            '^-version$|^-v$'        { $Version = $true }
            '^-auto$|^-a$'           { $AutoMode = $true }
            '^-beta$'                { $Beta = $true }
            '^-developer$'           { $Developer = $true }
            '^-debug$|^-d$'          { $Debug = $true }
            '^-skipverify$|^-s$'     { $SkipVerification = $true }
            '^-quiet$|^-q$'          { $QuietMode = $true }
        }
    } else {
        Clear-Host
        Write-Host ""
        Write-Host " Positional arguments are not allowed."
        Write-Host " Use -help or -? to see available options."
        Write-Host ""
        exit 1
    }
}

if ($QuietMode) {
    $newArgs = @()
    $hasAuto = $false
    foreach ($arg in $rawArgs) {
        if ($arg -match '^-quiet$|^-q$') {
            # skip
        } else {
            $newArgs += $arg
            if ($arg -match '^-auto$|^-a$') { $hasAuto = $true }
        }
    }
    if (-not $hasAuto) { $newArgs += '-auto' }
    $scriptPath = $MyInvocation.MyCommand.Path
    $argString = ($newArgs -join ' ')
    Start-Process -FilePath "powershell.exe" -ArgumentList "-WindowStyle Hidden -File `"$scriptPath`" $argString"
    exit 0
}

[bool]$DebugMode = $Debug
[bool]$SkipSelfHashVerification = $SkipVerification

# =============================================
# SCRIPT VERSION
# =============================================
$ScriptVersion = "2026.06.0006"
# =============================================

$isSFX = $MyInvocation.ScriptName -like "$env:SystemRoot\Temp\universal-intel-wifi-bt-driver-updater*"

if ($ScriptVersion -match '^(\d+\.\d+)-(\d{4}\.\d{2}\.\d+)$') {
    $DisplayVersion = "$($matches[1]) ($($matches[2]))"
} else {
    $DisplayVersion = $ScriptVersion
}

if ($Help) {
    Get-Help $MyInvocation.MyCommand.Path
    exit 0
}

if ($Version) {
    Clear-Host
    Write-Host ""
    Write-Host " Universal Intel Wi-Fi and Bluetooth Drivers Updater version $DisplayVersion"
    Write-Host ""
    exit 0
}

# =============================================
# AUTO-ELEVATE IF NOT ADMIN
# =============================================
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    Clear-Host
    Write-Host ""
    Write-Host " Administrator privileges required. Restarting with elevation..." -ForegroundColor Yellow
    Write-Host ""
    $scriptPath = $MyInvocation.MyCommand.Path
    $argList = if ($rawArgs.Count -gt 0) { $rawArgs -join " " } else { "" }
    try {
        Start-Process -FilePath "powershell.exe" -ArgumentList "-NoExit -File `"$scriptPath`" $argList" -Verb RunAs
    } catch {
        Clear-Host
        Write-Host ""
        Write-Host " Elevation failed. Please run the script as Administrator manually." -ForegroundColor Red
        Write-Host ""
        pause
        exit 1
    }
    exit 0
}

# =============================================
# ELEVATED CONTEXT - CONSOLE SETUP
# =============================================
Write-Host "Running with administrator privileges. Applying console settings..." -ForegroundColor Green

$Host.UI.RawUI.BackgroundColor = "Black"

try {
    [console]::WindowWidth = 75
    [console]::WindowHeight = 58
    [console]::BufferWidth = [console]::WindowWidth
} catch {
    Write-Host "Failed to set console size: $_" -ForegroundColor Red
}

# =============================================
# CONFIGURATION
# =============================================
$githubBaseUrl     = "https://raw.githubusercontent.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/main/data/"
$githubArchiveWiFi = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/archive-wifi/"
$githubArchiveBT   = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/archive-bt/"

$wifiLatestUrl   = $githubBaseUrl + "intel-wifi-driver-latest.md"
$btLatestUrl     = $githubBaseUrl + "intel-bt-driver-latest.md"
$supportMessageUrl = $githubBaseUrl + "intel-wifi-bt-message.txt"

if ($Developer) {
    $wifiLatestUrl   = $githubBaseUrl + "intel-wifi-driver-dev.md"
    $btLatestUrl     = $githubBaseUrl + "intel-bt-driver-dev.md"
    Write-Host ""
    Write-Host " [DEVELOPER MODE] Using development databases." -ForegroundColor Magenta
    Write-Host ""
} elseif ($Beta) {
    $wifiLatestUrl   = $githubBaseUrl + "intel-wifi-driver-beta.md"
    $btLatestUrl     = $githubBaseUrl + "intel-bt-driver-beta.md"
    Write-Host ""
    Write-Host " [BETA MODE] Using beta databases." -ForegroundColor Yellow
    Write-Host ""
}

$tempDir = Join-Path $env:SystemRoot "Temp\IntelWiFiBT"

# =============================================
# GLOBAL STATE
# =============================================
$global:InstallationErrors = @()
$global:ScriptStartTime    = Get-Date
$global:NewVersionLaunched = $false
$logFile = Join-Path $env:ProgramData "wifi_bt_update.log"

# =============================================
# VERSION MANAGEMENT FUNCTIONS
# =============================================

function Get-VersionNumber {
    param([string]$Version)

    if ($Version -match '^(\d{4})\.(\d{2})\.(\d+)$') {
        return [int]$matches[3]
    }

    throw "Cannot parse version: $Version"
}

function Compare-Versions {
    param([string]$Version1, [string]$Version2)

    $ver1Num = Get-VersionNumber -Version $Version1
    $ver2Num = Get-VersionNumber -Version $Version2

    if ($ver1Num -eq $ver2Num) { return 0 }
    if ($ver1Num -lt $ver2Num) { return -1 }
    return 1
}

# =============================================
# LOGGING FUNCTIONS
# =============================================

function Write-Log {
    param([string]$Message, [string]$Type = "INFO")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp] [$Type] $Message"
    try {
        Add-Content -Path $logFile -Value $logEntry -ErrorAction SilentlyContinue
    } catch { }

    if ($Type -eq "ERROR") {
        $global:InstallationErrors += $Message
        Write-Host " ERROR: $Message" -ForegroundColor Red
    }
}

function Write-DebugMessage {
    param([string]$Message, [string]$Color = "Gray")
    Write-Log -Message $Message -Type "DEBUG"
    if ($DebugMode) {
        Write-Host " DEBUG: $Message" -ForegroundColor $Color
    }
}

function Show-FinalSummary {
    $duration = (Get-Date) - $global:ScriptStartTime
    if ($global:InstallationErrors.Count -gt 0) {
        Write-Host "`n Completed with $($global:InstallationErrors.Count) error(s)." -ForegroundColor Red
        Write-Host " See $logFile for details." -ForegroundColor Red
    } else {
        Write-Host "`n Operation completed successfully." -ForegroundColor Green
    }
    Write-Log "Script execution completed in $([math]::Round($duration.TotalMinutes, 2)) minutes with $($global:InstallationErrors.Count) errors"
}

# =============================================
# COLOR LINE PARSING FUNCTION
# =============================================
function Write-ColorLine {
    param([string]$Line)

    $validColors = [Enum]::GetNames([ConsoleColor])
    $currentFg = $Host.UI.RawUI.ForegroundColor
    $currentBg = $Host.UI.RawUI.BackgroundColor

    $segments = @()
    $position = 0
    $length = $Line.Length

    while ($position -lt $length) {
        $openBracket = $Line.IndexOf('[', $position)
        if ($openBracket -eq -1) {
            $text = $Line.Substring($position)
            if ($text) {
                $segments += [PSCustomObject]@{ Text = $text; Foreground = $currentFg; Background = $currentBg }
            }
            break
        }

        if ($openBracket -gt $position) {
            $text = $Line.Substring($position, $openBracket - $position)
            if ($text) {
                $segments += [PSCustomObject]@{ Text = $text; Foreground = $currentFg; Background = $currentBg }
            }
        }

        $closeBracket = $Line.IndexOf(']', $openBracket)
        if ($closeBracket -eq -1) {
            $text = $Line.Substring($openBracket)
            if ($text) {
                $segments += [PSCustomObject]@{ Text = $text; Foreground = $currentFg; Background = $currentBg }
            }
            break
        }

        $tagContent = $Line.Substring($openBracket + 1, $closeBracket - $openBracket - 1)
        $parts = $tagContent -split ','

        $newFg = $null
        $newBg = $null

        if ($parts.Count -eq 1 -and $validColors -contains $parts[0]) {
            $newFg = [ConsoleColor]$parts[0]
        } elseif ($parts.Count -eq 2 -and $validColors -contains $parts[0] -and $validColors -contains $parts[1]) {
            $newFg = [ConsoleColor]$parts[0]
            $newBg = [ConsoleColor]$parts[1]
        }

        if ($newFg -ne $null) {
            if ($newBg -ne $null) { $currentBg = $newBg }
            $currentFg = $newFg
            $position = $closeBracket + 1
        } else {
            $text = $Line.Substring($openBracket, $closeBracket - $openBracket + 1)
            $segments += [PSCustomObject]@{ Text = $text; Foreground = $currentFg; Background = $currentBg }
            $position = $closeBracket + 1
        }
    }

    foreach ($seg in $segments) {
        Write-Host $seg.Text -NoNewline -ForegroundColor $seg.Foreground -BackgroundColor $seg.Background
    }
    Write-Host ""
}

function Get-KeyAndUrlFromLine {
    param([string]$Line)

    $validColors = [Enum]::GetNames([ConsoleColor])
    $colorPattern = '\[(?:' + (($validColors | ForEach-Object { [regex]::Escape($_) }) -join '|') + ')(?:,(?:' + (($validColors | ForEach-Object { [regex]::Escape($_) }) -join '|') + '))?\]'
    $cleanLine = $Line -replace $colorPattern, ''

    if ($cleanLine -match 'press \[([A-Za-z])\]') {
        $key = $matches[1]
        if ($cleanLine -match '(https?://)?([a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:/[^\s]*)?)') {
            $urlCandidate = $matches[0]
            if ($urlCandidate -notmatch '^https?://') { $urlCandidate = "https://$urlCandidate" }
            return @{ Key = $key; Url = $urlCandidate }
        }
    }
    return $null
}

# =============================================
# HEADER DISPLAY FUNCTION (UPDATED BANNER)
# =============================================
function Show-Header {
    Clear-Host
    Write-Host "/*************************************************************************" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " UNIVERSAL INTEL WI-FI AND BLUETOOTH DRIVERS UPDATER " -NoNewline -ForegroundColor White -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue

    $paddedVersion = $DisplayVersion.PadRight(14)
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Tool Version: $paddedVersion " -NoNewline -ForegroundColor Yellow -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue

    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Author: Marcin Grygiel / GitHub.com/FirstEverTech " -NoNewline -ForegroundColor Green -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** This tool is not affiliated with Intel Corporation. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** Drivers are sourced from official Intel/WU servers. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** Use at your own risk. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "*************************************************************************/" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host ""
}

# =============================================
# SCREEN MANAGEMENT FUNCTIONS
# =============================================

function Show-Screen1 {
    Show-Header
    Write-Host " [SCREEN 1/4] INITIALIZATION AND SECURITY CHECKS" -ForegroundColor Cyan
    Write-Host " ===============================================" -ForegroundColor Cyan

    if ($DebugMode) {
        Write-Host " DEBUG MODE: ENABLED" -ForegroundColor Magenta
    }
    if ($SkipSelfHashVerification) {
        Write-Host "`n SELF-HASH VERIFICATION: DISABLED (Testing Mode)" -ForegroundColor Yellow
    }

    Write-Host ""

    Write-Host " Checking Windows system requirements..." -ForegroundColor Yellow
    try {
        $os = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
        $build = [int]$os.BuildNumber

        if ($build -lt 17763) {
            Write-Host " [WARNING] Windows 10 LTSB 2015/2016 detected." -ForegroundColor Red
            Write-Host " TLS 1.2 may not work properly." -ForegroundColor Gray
        } else {
            Write-Host " Windows Build: $build" -ForegroundColor Gray
            Write-Host " Operating system compatibility: PASSED" -ForegroundColor Green
        }
    } catch {
        Write-Host " [INFO] Could not determine Windows build." -ForegroundColor Gray
    }
    Write-Host ""

    Write-Host " Checking .NET Framework prerequisites..." -ForegroundColor Yellow
    try {
        $netRelease = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name "Release" -ErrorAction Stop
        if ($netRelease -ge 461808) {
            Write-Host " .NET Framework 4.7.2 or newer detected: PASSED" -ForegroundColor Green
        } else {
            Write-Host " [WARNING] .NET Framework older than 4.7.2" -ForegroundColor Red
        }
    } catch {
        Write-Host " [WARNING] .NET Framework 4.7.2+ not found or couldn't be checked" -ForegroundColor Red
    }
    Write-Host ""

    Write-Host " Testing GitHub connectivity..." -ForegroundColor Yellow
    try {
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        $null = Invoke-WebRequest -Uri "https://raw.githubusercontent.com" -UseBasicParsing -TimeoutSec 5 -ErrorAction Stop
        Write-Host " Repository access verification: PASSED" -ForegroundColor Green
    } catch {
        Write-Host " [WARNING] Cannot reach GitHub servers" -ForegroundColor Red
        Write-Host " Self-hash verification will be skipped." -ForegroundColor Gray
    }
    Write-Host ""

    Write-Host " Pre-check summary..." -ForegroundColor Yellow

    if ($build -lt 17763 -or !$netRelease -or $netRelease -lt 461808) {
        Write-Host " [IMPORTANT] Some issues were detected." -ForegroundColor Yellow
        Write-Host ""

        if ($AutoMode) {
            $choice = "Y"
            Write-Host " Auto mode: automatically continuing (Y)." -ForegroundColor Cyan
        } else {
            do {
                $choice = Read-Host " Continue despite warnings? (Y/N)"
                $choice = $choice.Trim().ToUpper()
                if ($choice -ne 'Y' -and $choice -ne 'N') {
                    Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
                }
            } while ($choice -ne 'Y' -and $choice -ne 'N')
        }

        if ($choice -eq 'N') {
            Write-Host " Operation cancelled." -ForegroundColor Red
            if (-not $AutoMode) {
                $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
            }
            exit 0
        }

        Write-Host " Continuing with limited functionality..." -ForegroundColor Yellow
        Write-Host ""
    } else {
        Write-Host " All system requirements verified successfully." -ForegroundColor Green
    }
}

function Show-Screen2 {
    Show-Header
    Write-Host " [SCREEN 2/4] HARDWARE DETECTION AND VERSION ANALYSIS" -ForegroundColor Cyan
    Write-Host " ====================================================" -ForegroundColor Cyan
    Write-Host ""
}

function Show-Screen3 {
    Show-Header
    Write-Host " [SCREEN 3/4] UPDATE CONFIRMATION AND SYSTEM PREPARATION" -ForegroundColor Cyan
    Write-Host " =======================================================" -ForegroundColor Cyan
    Write-Host ""

    Write-Host " IMPORTANT NOTICE:" -ForegroundColor Yellow
    Write-Host " The driver update process may take several minutes to complete." -ForegroundColor Yellow
    Write-Host " During installation, your Wi-Fi and/or Bluetooth connection may" -ForegroundColor Yellow
    Write-Host " temporarily disconnect. This is normal behavior and connectivity" -ForegroundColor Yellow
    Write-Host " will be restored once the installation is complete." -ForegroundColor Yellow
    Write-Host ""

    if ($AutoMode) {
        $response = "Y"
        Write-Host " Auto mode: automatically proceeding (Y)." -ForegroundColor Cyan
    } else {
        $response = Read-Host " Do you want to proceed with driver update? (Y/N)"
    }

    return $response
}

function Show-Screen4 {
    Show-Header
    Write-Host " [SCREEN 4/4] DOWNLOAD AND INSTALLATION PROGRESS" -ForegroundColor Cyan
    Write-Host " ===============================================" -ForegroundColor Cyan
# Write-Host ""
}

# =============================================
# SELF-HASH VERIFICATION
# =============================================

function Verify-ScriptHash {
    if ($SkipSelfHashVerification) {
        Write-Host " SKIPPED: Self-hash verification disabled (Testing Mode)." -ForegroundColor Yellow
        Write-Host ""
        return $true
    }

    try {
        Write-Host " Verifying Updater source file integrity..." -ForegroundColor Yellow

        $scriptPath = $null
        if ($PSCommandPath) {
            $scriptPath = $PSCommandPath
        } elseif ($MyInvocation.MyCommand.Path) {
            $scriptPath = $MyInvocation.MyCommand.Path
        } else {
            $potentialPath = Join-Path (Get-Location) "universal-intel-wifi-bt-driver-updater.ps1"
            if (Test-Path $potentialPath) { $scriptPath = $potentialPath }
        }

        if (-not $scriptPath -or -not (Test-Path $scriptPath)) {
            Write-Host " FAIL: Cannot locate script file for hash verification." -ForegroundColor Red
            return $false
        }

        $currentHash = $null
        $retryCount = 0
        $maxRetries = 3

        while ($retryCount -lt $maxRetries -and -not $currentHash) {
            try {
                $hashResult = Get-FileHash -Path $scriptPath -Algorithm SHA256
                $currentHash = $hashResult.Hash.ToUpper()
            } catch {
                $retryCount++
                if ($retryCount -eq $maxRetries) {
                    Write-Host " FAIL: Could not calculate script hash after $maxRetries attempts." -ForegroundColor Red
                    return $false
                }
                Start-Sleep -Milliseconds 500
            }
        }

        $hashFileUrl = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/v$ScriptVersion/universal-intel-wifi-bt-driver-updater-$ScriptVersion-ps1.sha256"
        Write-DebugMessage "Downloading hash from: $hashFileUrl"

        try {
            $expectedHashResponse = Invoke-WebRequest -Uri $hashFileUrl -UseBasicParsing -ErrorAction Stop
            $expectedHashLine = if ($expectedHashResponse.Content -is [byte[]]) {
                [System.Text.Encoding]::UTF8.GetString($expectedHashResponse.Content).Trim()
            } else {
                $expectedHashResponse.Content.ToString().Trim()
            }

            $expectedHashLine = $expectedHashLine.TrimStart([char]0xEF, [char]0xBB, [char]0xBF).Trim()

            $expectedHash = $null
            if ($expectedHashLine -match '^([A-Fa-f0-9]{64})\s+(\S+)$') {
                $expectedHash = $matches[1].ToUpper()
            } elseif ($expectedHashLine -match '^([A-Fa-f0-9]{64})$') {
                $expectedHash = $expectedHashLine.ToUpper()
            } elseif ($expectedHashLine -match '^([A-Fa-f0-9]{64})\s*\*?\s*(\S+)$') {
                $expectedHash = $matches[1].ToUpper()
            }

            if (-not $expectedHash) {
                Write-Host " FAIL: Could not parse hash from file." -ForegroundColor Red
                return $false
            }

            if ($currentHash -eq $expectedHash) {
                Write-Host " Updater hash verification: PASSED" -ForegroundColor Green
                Write-Host ""
                return $true
            } else {
                Write-Host " FAIL: Updater hash verification failed. Hash doesn't match." -ForegroundColor Red
                Write-Host "`n WARNING: The updater file may have been modified or corrupted!" -ForegroundColor Red
                Write-Host " Please download the Updater from the official source:" -ForegroundColor Red
                Write-Host " https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases" -ForegroundColor Cyan
                Write-Host ""
                Write-Host " Source: $expectedHash" -ForegroundColor Green
                Write-Host " Actual: $currentHash" -ForegroundColor Red
                return $false
            }
        } catch {
            Write-Host " ERROR: Could not download or parse hash file." -ForegroundColor Red
            Write-Host " Please download the Updater from the official source:" -ForegroundColor Red
            Write-Host " https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases" -ForegroundColor Red
            Write-Host ""
            Write-Host " Actual: $currentHash" -ForegroundColor Red
            return $false
        }
    } catch {
        Write-Host " ERROR: Could not verify script hash: $($_.Exception.Message)" -ForegroundColor Red
        return $false
    }
}

# =============================================
# UPDATER UPDATE CHECK
# =============================================

function Get-DownloadsFolder {
    try {
        $registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
        $downloadsGuid = "{374DE290-123F-4565-9164-39C4925E467B}"
        if (Test-Path $registryPath) {
            $downloadsValue = Get-ItemProperty -Path $registryPath -Name $downloadsGuid -ErrorAction SilentlyContinue
            if ($downloadsValue -and $downloadsValue.$downloadsGuid) {
                return [Environment]::ExpandEnvironmentVariables($downloadsValue.$downloadsGuid)
            }
        }
        return [Environment]::GetFolderPath("UserProfile") + "\Downloads"
    } catch {
        return [Environment]::GetFolderPath("UserProfile") + "\Downloads"
    }
}

function Check-ForUpdaterUpdates {
    try {
        Write-Host " Checking for newer updater version..." -ForegroundColor Yellow

        $versionFileUrl = "https://raw.githubusercontent.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/main/src/universal-intel-wifi-bt-driver-updater.ver"
        $latestVersionContent = Invoke-WebRequest -Uri $versionFileUrl -UseBasicParsing -ErrorAction Stop
        $latestVersion = $latestVersionContent.Content.Trim()

        $comparisonResult = Compare-Versions -Version1 $ScriptVersion -Version2 $latestVersion
        Write-DebugMessage "Current version: $ScriptVersion, Latest: $latestVersion, Result: $comparisonResult"

        if ($comparisonResult -eq 0) {
            Write-Host " Status: Already on latest version." -ForegroundColor Green
            Write-Host ""
            Write-Host " Starting hardware detection..." -ForegroundColor Gray
            Write-Host ""
            Start-Sleep -Seconds 3
            return $true
        } elseif ($comparisonResult -lt 0) {
            Write-Host " A new version $latestVersion is available (current: $ScriptVersion)." -ForegroundColor Yellow

            if ($AutoMode) {
                $continueChoice = "Y"
                Write-Host " Auto mode: automatically continuing with current version (Y)." -ForegroundColor Cyan
            } else {
                do {
                    Write-Host ""
                    $continueChoice = Read-Host " Do you want to continue with the current version? (Y/N)"
                    $continueChoice = $continueChoice.Trim().ToUpper()
                    if ($continueChoice -ne 'Y' -and $continueChoice -ne 'N') {
                        Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
                    }
                } while ($continueChoice -ne 'Y' -and $continueChoice -ne 'N')
            }

            if ($continueChoice -eq 'Y') { return $true }

            if ($AutoMode) {
                $downloadChoice = "N"
            } else {
                do {
                    $downloadChoice = Read-Host " Do you want to download the latest version? (Y/N)"
                    $downloadChoice = $downloadChoice.Trim().ToUpper()
                    if ($downloadChoice -ne 'Y' -and $downloadChoice -ne 'N') {
                        Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
                    }
                } while ($downloadChoice -ne 'Y' -and $downloadChoice -ne 'N')
            }

            if ($downloadChoice -eq 'Y') {
                $downloadUrl = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/v$latestVersion/WiFi-BT-Updater-$latestVersion-Win10-Win11.exe"
                $downloadsFolder = Get-DownloadsFolder
                $outputPath = Join-Path $downloadsFolder "WiFi-BT-Updater-$latestVersion-Win10-Win11.exe"

                Write-Host " Downloading new version to: $outputPath" -ForegroundColor Yellow
                Write-Host ""

                $downloadSuccess = $false
                try {
                    Invoke-WebRequest -Uri $downloadUrl -OutFile $outputPath -UseBasicParsing -ErrorAction Stop
                    Write-Host " SUCCESS: New version downloaded successfully." -ForegroundColor Green
                    Write-Host "`n File saved to:" -ForegroundColor Yellow
                    Write-Host " $outputPath" -ForegroundColor Yellow
                    $downloadSuccess = $true
                } catch {
                    Write-Host " ERROR: Failed to download new version - $($_.Exception.Message)" -ForegroundColor Red
                    Write-Host " Please download manually from: https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases" -ForegroundColor Red
                }

                if ($downloadSuccess) {
                    if ($AutoMode) {
                        $exitChoice = "Y"
                        Write-Host " Auto mode: automatically exiting to run new version (Y)." -ForegroundColor Cyan
                    } else {
                        do {
                            $exitChoice = Read-Host "`n Do you want to exit now to run the new version? (Y/N)"
                            $exitChoice = $exitChoice.Trim().ToUpper()
                            if ($exitChoice -ne 'Y' -and $exitChoice -ne 'N') {
                                Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
                            }
                        } while ($exitChoice -ne 'Y' -and $exitChoice -ne 'N')
                    }

                    if ($exitChoice -eq 'Y') {
                        Write-Host " Starting the new version and closing current updater..." -ForegroundColor Green
                        Write-Host ""
                        Start-Process -FilePath $outputPath
                        exit 100
                    }
                }
            }

            Cleanup
            if (-not $AutoMode) {
                Write-Host "`n Press any key..."
                $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
            }
            Show-FinalCredits
            $global:NewVersionLaunched = $true
            return $false
        } else {
            Write-Host " Status: Running a newer version than published ($ScriptVersion)." -ForegroundColor Cyan
            Write-Host ""
            Start-Sleep -Seconds 2
            return $true
        }
    } catch {
        Write-Host " WARNING: Could not check for updates. Continuing..." -ForegroundColor Yellow
        Write-DebugMessage "Update check failed: $($_.Exception.Message)"
        return $true
    }
}

# =============================================
# TEMP DIRECTORY MANAGEMENT
# =============================================

function Clear-TempDriverFolders {
    try {
        if (Test-Path $tempDir) {
            Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
            Write-DebugMessage "Cleaned up temporary directory: $tempDir"
        }
    } catch {
        Write-DebugMessage "Error during cleanup: $_"
    }
}

function Cleanup {
    Write-Host "`n Cleaning up temporary files..." -ForegroundColor Yellow
    if (Test-Path $tempDir) {
        try {
            Get-ChildItem -Path $tempDir -Exclude "*.ps1" -Recurse | Remove-Item -Force -Recurse -ErrorAction Stop
            Write-Host " Temporary files cleaned successfully." -ForegroundColor Green
        } catch {
            Write-Host " Warning: Could not clean all temporary files." -ForegroundColor Yellow
        }
    }
}

# =============================================
# HARDWARE DETECTION FUNCTIONS
# =============================================

# Supported Intel Wi-Fi DEV IDs (PCI)
$supportedWiFiDEVs = @(
    # Wi-Fi 7 (BE)
    "272B", "A840", "A841", "E340", "E440",
    # Wi-Fi 6E (AX - 6 GHz)
    "2725", "51F0", "51F1", "54F0", "7A70", "7AF0", "7E40", "7F70",
    # Wi-Fi 6 (AX)
    "2723", "02F0", "06F0", "34F0", "3DF0", "43F0", "4DF0", "A0F0", "7740",
    # Wi-Fi 5 (AC)
    "2526", "30DC", "31DC", "9DF0", "A370"
)

# Supported Intel Bluetooth USB PID IDs (VID_8087)
$supportedBTPIDs = @("0025", "0AAA", "0026", "0029", "0032", "0033", "0043", "0036", "0037", "0038")

# Supported Intel Bluetooth PCI DEV IDs (VEN_8086)
$supportedBTDEVs = @("A876", "4D76", "E476", "E376")   # Intel Bluetooth PCI Enumerator

function Get-IntelWiFiDevice {
    try {
        $devices = Get-PnpDevice -Class "Net" -ErrorAction SilentlyContinue |
            Where-Object { $_.Status -eq "OK" }

        foreach ($device in $devices) {
            foreach ($hwid in $device.HardwareID) {
                if ($hwid -match 'PCI\\VEN_8086&DEV_([A-F0-9]{4})') {
                    $devId = $matches[1].ToUpper()
                    if ($supportedWiFiDEVs -contains $devId) {
                        Write-DebugMessage "Found Intel Wi-Fi device: $devId ($($device.FriendlyName))"
                        return [PSCustomObject]@{
                            DEV          = $devId
                            InstanceId   = $device.InstanceId
                            FriendlyName = $device.FriendlyName
                            HardwareID   = $hwid
                        }
                    }
                }
            }
        }
    } catch {
        Write-DebugMessage "Error scanning for Wi-Fi devices: $_"
    }
    return $null
}

function Get-IntelBTDevice {
    try {
        # First, scan Bluetooth class devices
        $devices = Get-PnpDevice -Class "Bluetooth" -ErrorAction SilentlyContinue |
            Where-Object { $_.Status -eq "OK" }

        # Fallback to scanning all devices if none found in Bluetooth class
        if (-not $devices -or $devices.Count -eq 0) {
            $devices = Get-PnpDevice -ErrorAction SilentlyContinue |
                Where-Object { $_.Status -eq "OK" -and ($_.HardwareID -like "*VID_8087*" -or $_.HardwareID -like "*VEN_8086*") }
        }

        foreach ($device in $devices) {
            foreach ($hwid in $device.HardwareID) {
                # USB Bluetooth (VID_8087)
                if ($hwid -match 'USB\\VID_8087&PID_([0-9A-F]{4})') {
                    $btPid = $matches[1].ToUpper()
                    if ($supportedBTPIDs -contains $btPid) {
                        Write-DebugMessage "Found Intel USB BT device: PID=$btPid ($($device.FriendlyName))"
                        return [PSCustomObject]@{
                            Type         = "USB"
                            PID          = $btPid
                            InstanceId   = $device.InstanceId
                            FriendlyName = $device.FriendlyName
                            HardwareID   = $hwid
                        }
                    }
                }
                # PCI Bluetooth (VEN_8086) - Intel Bluetooth PCI Enumerator
                if ($hwid -match 'PCI\\VEN_8086&DEV_([0-9A-F]{4})') {
                    $devId = $matches[1].ToUpper()
                    if ($supportedBTDEVs -contains $devId) {
                        Write-DebugMessage "Found Intel PCI BT device: DEV=$devId ($($device.FriendlyName))"
                        return [PSCustomObject]@{
                            Type         = "PCI"
                            PID          = $devId   # store DEV as PID for unified handling
                            InstanceId   = $device.InstanceId
                            FriendlyName = $device.FriendlyName
                            HardwareID   = $hwid
                        }
                    }
                }
            }
        }
    } catch {
        Write-DebugMessage "Error scanning for BT devices: $_"
    }
    return $null
}

function Get-CurrentDriverVersion {
    param([string]$DeviceInstanceId)

    try {
        $device = Get-PnpDevice | Where-Object { $_.InstanceId -eq $DeviceInstanceId }
        if ($device) {
            $versionProperty = $device | Get-PnpDeviceProperty -KeyName "DEVPKEY_Device_DriverVersion" -ErrorAction SilentlyContinue
            if ($versionProperty -and $versionProperty.Data) {
                Write-DebugMessage "Got version from DEVPKEY: $($versionProperty.Data)"
                return $versionProperty.Data
            }
        }

        $driverInfo = Get-CimInstance -ClassName Win32_PnPSignedDriver |
            Where-Object { $_.DeviceID -eq $DeviceInstanceId -and $_.DriverVersion } |
            Select-Object -First 1

        if ($driverInfo) {
            Write-DebugMessage "Got version from WMI: $($driverInfo.DriverVersion)"
            return $driverInfo.DriverVersion
        }
    } catch {
        Write-DebugMessage "Error getting driver version: $_"
    }
    return $null
}

# =============================================
# DATA DOWNLOAD FUNCTION
# =============================================

function Get-RemoteContent {
    param([string]$Url)

    try {
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        $cacheBuster = "t=" + (Get-Date -Format 'yyyyMMddHHmmss')
        if ($Url.Contains('?')) {
            $finalUrl = $Url + "&" + $cacheBuster
        } else {
            $finalUrl = $Url + "?" + $cacheBuster
        }
        Write-DebugMessage "Downloading: $finalUrl"
        $content = Invoke-WebRequest -Uri $finalUrl -UseBasicParsing -ErrorAction Stop
        return $content.Content
    } catch {
        Write-Log "Error downloading from: $Url - $($_.Exception.Message)" -Type "ERROR"
        return $null
    }
}

# =============================================
# RELEASE ASSET DOWNLOAD FUNCTION
# (no cache buster - GitHub release assets are immutable)
# =============================================

function Get-ReleaseAssetContent {
    param([string]$Url)

    try {
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        Write-DebugMessage "Downloading release asset: $Url"
        $wc = New-Object System.Net.WebClient
        $wc.Headers.Add("User-Agent", "Mozilla/5.0")
        $rawContent = $wc.DownloadString($Url)
        return $rawContent
    } catch {
        Write-Log "Error downloading release asset: $Url - $($_.Exception.Message)" -Type "ERROR"
        return $null
    }
}

# =============================================
# VERSIONED DOWNLOAD INFO FUNCTIONS (using release assets)
# =============================================

function Get-VersionedWiFiDownloadInfo {
    param([string]$Version)

    $url = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/archive-wifi/intel-wifi-$Version.txt"
    Write-DebugMessage "Attempting to download versioned Wi-Fi driver info: $url"
    $content = Get-ReleaseAssetContent -Url $url
    if (-not $content) {
        Write-DebugMessage "Versioned Wi-Fi file not found for version $Version"
        return $null
    }

    $lines = $content -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
    $info = @{ SHA256 = $null; Link = $null; Backup = $null; Version = $Version; Date = $null }
    foreach ($line in $lines) {
        if ($line -match '^SHA256\s*=\s*([A-Fa-f0-9]{64})') {
            $info.SHA256 = $matches[1].ToUpper()
        } elseif ($line -match '^Link\s*=\s*(https?://.+)') {
            $info.Link = $matches[1].Trim()
        } elseif ($line -match '^Backup\s*=\s*(https?://.+)') {
            $info.Backup = $matches[1].Trim()
        } elseif ($line -match '^DriverVer\s*=\s*([^,]+),\s*([0-9.]+)') {
            $info.Date = $matches[1].Trim()
        }
    }

    if ($info.SHA256 -and $info.Link) {
        Write-DebugMessage "Versioned Wi-Fi download info loaded for version $Version"
        return $info
    } else {
        Write-DebugMessage "Versioned Wi-Fi file missing required fields SHA256 or Link"
        return $null
    }
}

function Get-VersionedBTDownloadInfo {
    param([string]$Version, [string]$BtPID, [string]$DeviceType = "USB")

    if ($DeviceType -eq "PCI") {
        # PCI devices use a shared CAB: intel-bt-<version>_pci.txt
        $url = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/archive-bt/intel-bt-${Version}_pci.txt"
        Write-DebugMessage "Attempting to download PCI BT driver info (shared): $url"
    } else {
        # USB devices use per-PID files
        $url = "https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases/download/archive-bt/intel-bt-${Version}_pid${BtPID}.txt"
        Write-DebugMessage "Attempting to download versioned BT driver info (per-PID): $url"
    }

    $content = Get-ReleaseAssetContent -Url $url
    if (-not $content) {
        Write-DebugMessage "Versioned BT file not found for $DeviceType (ID: $BtPID, version $Version)"
        return $null
    }

    $lines = $content -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
    $info = @{ SHA256 = $null; Link = $null; Backup = $null; Version = $Version; Date = $null }
    foreach ($line in $lines) {
        if ($line -match '^SHA256\s*=\s*([A-Fa-f0-9]{64})') {
            $info.SHA256 = $matches[1].ToUpper()
        } elseif ($line -match '^Link\s*=\s*(https?://.+)') {
            $info.Link = $matches[1].Trim()
        } elseif ($line -match '^Backup\s*=\s*(https?://.+)') {
            $info.Backup = $matches[1].Trim()
        } elseif ($line -match '^DriverVer\s*=\s*([^,]+),\s*([0-9.]+)') {
            $info.Date = $matches[1].Trim()
        }
    }

    if ($info.SHA256 -and $info.Link) {
        Write-DebugMessage "Versioned BT download info loaded for $DeviceType (ID: $BtPID) version $Version"
        return $info
    } else {
        Write-DebugMessage "Versioned BT file missing required fields SHA256 or Link"
        return $null
    }
}

# =============================================
# DATA PARSING FUNCTIONS (for .md files)
# =============================================

function Parse-WiFiLatestMd {
    param([string]$Content)

    $result = @{
        LatestVersion = $null
        ReleaseDate   = $null
        Devices       = @{}   # DEV_xxxx -> @{ Chipset, Models, Generation, LatestVersion, ReleaseDate }
    }

    try {
        $lines = $Content -split "`n"
        foreach ($line in $lines) {
            $line = $line.Trim()
            if ($line -match '^Latest Version\s*=\s*([0-9.]+)') {
                $result.LatestVersion = $matches[1]
                Write-DebugMessage "WiFi Latest Version (global): $($result.LatestVersion)"
            } elseif ($line -match '^Release Date\s*=\s*(.+)') {
                $result.ReleaseDate = $matches[1].Trim()
            } elseif ($line -match '^\|\s*(DEV_[A-F0-9]{4})\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|') {
                $devId    = $matches[1] -replace 'DEV_', ''
                $chipset  = $matches[2].Trim()
                $models   = $matches[3].Trim()
                $gen      = $matches[4].Trim()

                $deviceVersion = $null
                $deviceDate    = $null
                if ($line -match '^\|\s*DEV_[A-F0-9]{4}\s*\|\s*.+?\s*\|\s*.+?\s*\|\s*.+?\s*\|\s*([0-9][0-9.]+)\s*\|\s*(.+?)\s*\|') {
                    $deviceVersion = $matches[1].Trim()
                    $deviceDate    = $matches[2].Trim()
                    Write-DebugMessage "WiFi per-device version: $devId -> $deviceVersion ($deviceDate)"
                }

                $result.Devices[$devId] = @{
                    Chipset       = $chipset
                    Models        = $models
                    Generation    = $gen
                    LatestVersion = $deviceVersion
                    ReleaseDate   = $deviceDate
                }
                Write-DebugMessage "WiFi device parsed: $devId -> Chipset=$chipset, Models=$models, Gen=$gen"
            }
        }
    } catch {
        Write-Log "WiFi MD parsing failed: $($_.Exception.Message)" -Type "ERROR"
    }

    return $result
}

function Parse-BTLatestMd {
    param([string]$Content)

    $result = @{
        LatestVersion = $null
        ReleaseDate   = $null
        Devices       = @{}   # Key can be USB PID or PCI DEV (both 4-hex)
    }

    try {
        $lines = $Content -split "`n"

        foreach ($line in $lines) {
            $line = $line.Trim()

            if ($line -match '^Latest Version\s*=\s*([0-9.]+)') {
                $result.LatestVersion = $matches[1]
                Write-DebugMessage "BT Latest Version (global): $($result.LatestVersion)"
            } elseif ($line -match '^Release Date\s*=\s*(.+)') {
                $result.ReleaseDate = $matches[1].Trim()
            } elseif ($line -match '^\|\s*([0-9A-Fa-f]{4})\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|') {
                $btId    = $matches[1].ToUpper()
                $chipset = $matches[2].Trim()
                $gen     = $matches[3].Trim()
                $bt      = $matches[4].Trim()

                $deviceVersion = $null
                $deviceDate    = $null
                if ($line -match '^\|\s*[0-9A-Fa-f]{4}\s*\|\s*.+?\s*\|\s*.+?\s*\|\s*.+?\s*\|\s*([0-9][0-9.]+)\s*\|\s*(.+?)\s*\|') {
                    $deviceVersion = $matches[1].Trim()
                    $deviceDate    = $matches[2].Trim()
                    Write-DebugMessage "BT per-device version: $btId -> $deviceVersion ($deviceDate)"
                }

                $result.Devices[$btId] = @{
                    Chipset       = $chipset
                    Generation    = $gen
                    Bluetooth     = $bt
                    LatestVersion = $deviceVersion
                    ReleaseDate   = $deviceDate
                }
                Write-DebugMessage "BT device parsed: $btId -> $chipset BT $bt"
            }
        }
    } catch {
        Write-Log "BT MD parsing failed: $($_.Exception.Message)" -Type "ERROR"
    }

    return $result
}

# =============================================
# HASH VERIFICATION
# =============================================

function Verify-FileHash {
    param(
        [string]$FilePath,
        [string]$ExpectedHash,
        [string]$HashType = "Primary",
        [string]$OriginalFileName = ""
    )

    if (-not $ExpectedHash) {
        Write-Host " WARNING: No expected hash provided. Skipping verification." -ForegroundColor Yellow
        return $true
    }

    try {
        if (-not (Test-Path $FilePath)) {
            Write-Log "File not found for hash check: $FilePath" -Type "ERROR"
            return $false
        }
        $actualHash = (Get-FileHash -Path $FilePath -Algorithm SHA256).Hash
        Write-DebugMessage "SHA256 for $FilePath : $actualHash"
    } catch {
        Write-Log "Error calculating hash: $($_.Exception.Message)" -Type "ERROR"
        return $false
    }

    if ($actualHash -eq $ExpectedHash) {
        Write-Host " PASS: $HashType hash verification passed." -ForegroundColor Green
        return $true
    } else {
        $displayName = if ($OriginalFileName) { $OriginalFileName } else { Split-Path $FilePath -Leaf }
        Write-Host " $HashType hash verification FAILED: $displayName" -ForegroundColor Red
        Write-Host " Source: $ExpectedHash" -ForegroundColor Red
        Write-Host " Actual: $actualHash" -ForegroundColor Red
        Write-Log "$HashType hash mismatch for $displayName. Source: $ExpectedHash, Actual: $actualHash" -Type "ERROR"
        return $false
    }
}

# =============================================
# DIGITAL SIGNATURE VERIFICATION FUNCTIONS
# =============================================

function Verify-FileSignature {
    param([string]$FilePath)

    try {
        Write-DebugMessage "Verifying digital signature for: $FilePath"

        $signature = Get-AuthenticodeSignature -FilePath $FilePath
        Write-DebugMessage "Signature status: $($signature.Status)"
        Write-DebugMessage "Signer: $($signature.SignerCertificate.Subject)"
        Write-DebugMessage "Signature Algorithm: $($signature.SignerCertificate.SignatureAlgorithm.FriendlyName)"

        if ($signature.Status -ne 'Valid') {
            Write-Log "Digital signature is not valid. Status: $($signature.Status)" -Type "ERROR"
            Write-Host " FAIL: Digital signature verification - Status: $($signature.Status)" -ForegroundColor Red
            return $false
        }

        if ($signature.SignerCertificate.Subject -notmatch 'CN=Microsoft Windows Hardware Compatibility Publisher') {
            Write-Log "File not signed by Microsoft Windows HW Compatibility Publisher. Signer: $($signature.SignerCertificate.Subject)" -Type "ERROR"
            Write-Host " FAIL: Digital signature verification - Not signed by Microsoft Windows HW Compatibility Publisher." -ForegroundColor Red
            return $false
        }

        if ($signature.SignerCertificate.SignatureAlgorithm.FriendlyName -notmatch 'sha256') {
            Write-Log "Signature not using SHA256 algorithm. Algorithm: $($signature.SignerCertificate.SignatureAlgorithm.FriendlyName)" -Type "ERROR"
            Write-Host " FAIL: Digital signature verification - Not using SHA256 algorithm" -ForegroundColor Red
            return $false
        }

        Write-Host " PASS: Digitally signed by Microsoft Windows HW Compatibility Publisher." -ForegroundColor Green
        Write-DebugMessage "Digital signature verification passed for $FilePath"
        return $true
    } catch {
        Write-Log "Error verifying digital signature: $($_.Exception.Message)" -Type "ERROR"
        Write-Host " FAIL: Digital signature verification - Error: $($_.Exception.Message)" -ForegroundColor Red
        return $false
    }
}

# =============================================
# DOWNLOAD FUNCTION
# =============================================

function Download-VerifyFile {
    param(
        [string]$Url,
        [string]$OutFile,
        [string]$ExpectedHash,
        [string]$SourceName = "Primary"
    )

    try {
        Write-Host " Downloading from $SourceName source..." -ForegroundColor Yellow
        Write-DebugMessage "URL: $Url"

        try {
            Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing -ErrorAction Stop
        } catch {
            Write-Log "Download failed [$SourceName]: $($_.Exception.Message)" -Type "ERROR"
            return @{ Success = $false; ErrorType = "DownloadFailed" }
        }

        if (-not (Test-Path $OutFile)) {
            return @{ Success = $false; ErrorType = "DownloadFailed" }
        }

        if ($ExpectedHash) {
            Write-Host " Verifying $SourceName source file integrity..." -ForegroundColor Yellow
            $fileName = [System.IO.Path]::GetFileName($Url)
            if (-not (Verify-FileHash -FilePath $OutFile -ExpectedHash $ExpectedHash -HashType $SourceName -OriginalFileName $fileName)) {
                Remove-Item $OutFile -Force -ErrorAction SilentlyContinue
                return @{ Success = $false; ErrorType = "HashMismatch" }
            }
        }

        return @{ Success = $true; ErrorType = "None" }
    } catch {
        Write-Log "Unexpected error in Download-VerifyFile: $_" -Type "ERROR"
        return @{ Success = $false; ErrorType = "UnknownError" }
    }
}

# =============================================
# CAB EXTRACTION AND DRIVER INSTALLATION
# =============================================

function Install-DriverFromCab {
    param(
        [string]$CabPath,
        [string]$DeviceInstanceId,
        [string]$DeviceType
    )

    $extractPath = "$tempDir\extracted_$(Get-Random)"

    try {
        New-Item -ItemType Directory -Path $extractPath -Force | Out-Null

        Write-Host " Verifying driver digital signature..." -ForegroundColor Yellow
        if (-not (Verify-FileSignature -FilePath $CabPath)) {
            Write-Log "Driver digital signature verification failed. Aborting installation." -Type "ERROR"
            Write-Host " ERROR: Driver digital signature verification failed. Installation aborted." -ForegroundColor Red
            return $false
        }

        Write-Host " Extracting driver package..." -ForegroundColor Yellow
        Write-DebugMessage "Extracting $CabPath to $extractPath"

        $expandResult = & expand.exe "$CabPath" "$extractPath" -F:* 2>&1
        if ($LASTEXITCODE -ne 0) {
            Write-Log "CAB extraction failed (exit $LASTEXITCODE): $expandResult" -Type "ERROR"
            return $false
        }

        $infFiles = Get-ChildItem -Path $extractPath -Filter "*.inf" -Recurse -ErrorAction SilentlyContinue
        if ($infFiles.Count -eq 0) {
            Write-Log "No INF files found in extracted CAB: $CabPath" -Type "ERROR"
            return $false
        }

        Write-DebugMessage "Found $($infFiles.Count) INF file(s): $($infFiles.Name -join ', ')"

        Write-Host " Staging driver to Windows driver store..." -ForegroundColor Yellow
        foreach ($inf in $infFiles) {
            $pnpOut = pnputil /add-driver "$($inf.FullName)" /install 2>&1
            Write-DebugMessage "pnputil /add-driver: $pnpOut"
            if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 3010 -and $LASTEXITCODE -ne 259) {
                Write-Log "pnputil /add-driver failed (exit $LASTEXITCODE)" -Type "ERROR"
                return $false
            }
        }

        if ($DeviceInstanceId) {
            Write-Host " Updating $DeviceType device driver..." -ForegroundColor Yellow
            $updateOut = pnputil /update-device "$DeviceInstanceId" /install 2>&1
            Write-DebugMessage "pnputil /update-device: $updateOut"
            if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 1 -and $LASTEXITCODE -ne 3010 -and $LASTEXITCODE -ne 259) {
                Write-Log "pnputil /update-device failed (exit $LASTEXITCODE)" -Type "ERROR"
                return $false
            }
        }

        Write-Host " $DeviceType driver installed successfully." -ForegroundColor Green
        Write-Log "$DeviceType driver installed from: $CabPath"
        return $true

    } catch {
        Write-Log "Error installing $DeviceType driver from CAB: $_" -Type "ERROR"
        return $false
    } finally {
        if (Test-Path $extractPath) {
            Remove-Item $extractPath -Recurse -Force -ErrorAction SilentlyContinue
        }
    }
}

function Install-DriverWithFallback {
    param(
        [string]$PrimaryUrl,
        [string]$BackupUrl,
        [string]$ExpectedHash,
        [string]$DeviceInstanceId,
        [string]$DeviceType,
        [string]$VersionLabel
    )

    Write-Host "`n Installing $DeviceType driver ($VersionLabel)" -ForegroundColor Cyan

    $tempCab = "$tempDir\temp_$(Get-Random).cab"
    $downloadSuccess = $false
    $errorPhase = $null

    Write-Host " Attempting download from primary source..." -ForegroundColor Yellow
    $primaryResult = Download-VerifyFile -Url $PrimaryUrl -OutFile $tempCab -ExpectedHash $ExpectedHash -SourceName "Primary"

    if ($primaryResult.Success) {
        $downloadSuccess = $true
        Write-Host " SUCCESS: Primary source - download and hash verification successful." -ForegroundColor Green
    } else {
        $errorPhase = if ($primaryResult.ErrorType -eq "HashMismatch") { "1b" } else { "1a" }

        if ($BackupUrl) {
            Write-Host " Attempting download from backup source..." -ForegroundColor Yellow
            $backupResult = Download-VerifyFile -Url $BackupUrl -OutFile $tempCab -ExpectedHash $ExpectedHash -SourceName "Backup"

            if ($backupResult.Success) {
                $downloadSuccess = $true
                Write-Host " SUCCESS: Backup source - download and hash verification successful." -ForegroundColor Green
            } else {
                $errorPhase = if ($backupResult.ErrorType -eq "HashMismatch") { "2b" } else { "2a" }
            }
        } else {
            Write-Host " No backup source available." -ForegroundColor Red
        }
    }

    if (-not $downloadSuccess) {
        $msg = switch ($errorPhase) {
            "1a" { "Primary source download failed and no backup available." }
            "1b" { "Primary source file corrupted (hash mismatch) and no backup available." }
            "2a" { "Both primary and backup sources download failed." }
            "2b" { "Both primary and backup sources have hash mismatches." }
            default { "Unknown download error." }
        }
        Write-Host "`n ERROR: $msg" -ForegroundColor Red
        if (Test-Path $tempCab) { Remove-Item $tempCab -Force -ErrorAction SilentlyContinue }
        return $false
    }

    $installResult = Install-DriverFromCab -CabPath $tempCab -DeviceInstanceId $DeviceInstanceId -DeviceType $DeviceType

    if (Test-Path $tempCab) { Remove-Item $tempCab -Force -ErrorAction SilentlyContinue }
    return $installResult
}

# =============================================
# FINAL CREDITS FUNCTION
# =============================================

function Show-FinalCredits {
    Clear-Host
    Write-Host "/*************************************************************************" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " UNIVERSAL INTEL WI-FI AND BLUETOOTH DRIVERS UPDATER " -NoNewline -ForegroundColor White -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue

    $paddedVersion = $DisplayVersion.PadRight(14)
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Tool Version: $paddedVersion " -NoNewline -ForegroundColor Yellow -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue

    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Author: Marcin Grygiel / GitHub.com/FirstEverTech " -NoNewline -ForegroundColor Green -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** This tool is not affiliated with Intel Corporation. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** Drivers are sourced from official Intel/WU servers. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** Use at your own risk. **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "*************************************************************************/" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host ""

    Write-Host " THANK YOU FOR USING UNIVERSAL INTEL WI-FI AND BLUETOOTH DRIVERS UPDATER" -ForegroundColor Cyan
    Write-Host " ========================================================================" -ForegroundColor Cyan
    Write-Host ""
    Write-Host " I hope this tool has been helpful in updating your system." -ForegroundColor Yellow
    Write-Host ""

    $keyActions = @{}

    $cacheBuster = "?t=$(Get-Date -Format 'yyyyMMddHHmmss')"
    try {
        $content = Invoke-WebRequest -Uri ($supportMessageUrl + $cacheBuster) -UseBasicParsing -ErrorAction Stop
        $lines = $content.Content -split "`r?`n"
    } catch {
        $lines = @(
            "[Magenta]",
            "[Magenta] SUPPORT THIS PROJECT",
            "[Magenta] ====================",
            "",
            " This project is maintained in my free time.",
            " Your support ensures regular updates and compatibility.",
            "",
            " Support options:",
            "",
            "[Green] - PayPal Donation:[Yellow] tinyurl.com/fet-paypal[Gray] - press [Black,Gray][P][Gray,Black] key",
            "[Green] - Buy Me a Coffee:[Yellow] tinyurl.com/fet-coffee[Gray] - press [Black,Gray][C][Gray,Black] key",
            "[Green] - GitHub Sponsors:[Yellow] tinyurl.com/fet-github[Gray] - press [Black,Gray][G][Gray,Black] key",
            "",
            " If this project helped you, please consider:",
            "",
            "[Green] - Giving it a STAR on GitHub",
            "[Green] - Sharing with friends and colleagues",
            "[Green] - Reporting issues or suggesting features",
            "[Green] - Supporting development financially",
            "",
            "[Magenta]",
            "[Magenta] CAREER OPPORTUNITY",
            "[Magenta] ==================",
            "",
            " I'm currently seeking new challenges where I can apply my expertise",
            " in solving complex IT infrastructure problems. If your organization",
            " struggles with system compatibility, automation, or tooling gaps,",
            " let's discuss how I can help.",
            "",
            "[Green] - Connect with me:[Yellow] linkedin.com/in/marcin-grygiel[Gray] - press [Black,Gray][L][Gray,Black] key"
        )
    }

    foreach ($line in $lines) {
        Write-ColorLine $line
        $keyInfo = Get-KeyAndUrlFromLine -Line $line
        if ($keyInfo) {
            if ($keyInfo.Key -match '[a-zA-Z]') {
                $keyActions[$keyInfo.Key.ToUpper()] = $keyInfo.Url
                $keyActions[$keyInfo.Key.ToLower()] = $keyInfo.Url
            } else {
                $keyActions[$keyInfo.Key] = $keyInfo.Url
            }
        }
    }

    if ($AutoMode) { return }

    Write-Host "`n Press " -NoNewline -ForegroundColor Gray
    Write-Host "P" -NoNewline -ForegroundColor Yellow
    Write-Host "=PayPal, " -NoNewline -ForegroundColor Gray
    Write-Host "C" -NoNewline -ForegroundColor Yellow
    Write-Host "=Coffee, " -NoNewline -ForegroundColor Gray
    Write-Host "G" -NoNewline -ForegroundColor Yellow
    Write-Host "=GitHub, " -NoNewline -ForegroundColor Gray
    Write-Host "L" -NoNewline -ForegroundColor Yellow
    Write-Host "=LinkedIn, or any other key to exit." -ForegroundColor Gray

    $key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    $pressed = $key.Character.ToString()

    if ($keyActions.ContainsKey($pressed)) {
        Start-Process $keyActions[$pressed]
    }

    if (-not $isSFX) {
        Clear-Host
        Write-Host "`n Thank you for using Universal Intel Wi-Fi and Bluetooth Drivers Updater!`n" -ForegroundColor Cyan
    }
    exit
}

# =============================================
# MAIN SCRIPT EXECUTION
# =============================================

try {
    Show-Screen1

    Write-Host ""
    if (-not (Verify-ScriptHash)) {
        Write-Host " Update process aborted for security reasons." -ForegroundColor Red
        Cleanup
        if (-not $AutoMode) {
            Write-Host "`n Press any key..."
            $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
        }
        Show-FinalCredits
        exit 1
    }

    $updateCheckResult = Check-ForUpdaterUpdates
    if (-not $updateCheckResult) { exit 100 }

    Clear-TempDriverFolders
    New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
    Write-DebugMessage "Created temporary directory: $tempDir"

    # ------------------------------------------
    Show-Screen2
    # ------------------------------------------

    # Hardware detection
    Write-Host " Scanning for Intel Wi-Fi and Bluetooth devices..." -ForegroundColor Yellow
    Write-Host ""

    $wifiDevice = Get-IntelWiFiDevice
    $btDevice   = Get-IntelBTDevice

    $totalFound = 0
    if ($wifiDevice) { $totalFound++ }
    if ($btDevice)   { $totalFound++ }

    if ($totalFound -eq 0) {
        Write-Host " No supported Intel Wi-Fi or Bluetooth devices found." -ForegroundColor Yellow
        Write-Host " Supported: Wi-Fi 5 (AC) / Wi-Fi 6 (AX) / Wi-Fi 6E (AXE) / Wi-Fi 7 (BE)" -ForegroundColor Gray
        Write-Host " Supported Bluetooth: USB (PID 0025,0AAA,0026,0029,0032,0033,0036,0037,0038) and PCI (DEV A876,4D76,E476,E376)" -ForegroundColor Gray
        Cleanup
        if (-not $AutoMode) {
            Write-Host "`n Press any key to continue..."
            $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
        }
        Show-FinalCredits
        exit
    }

    Write-Host " Found $totalFound Intel Wireless device(s)" -ForegroundColor Green
    Write-Host " Downloading latest driver information..." -ForegroundColor Yellow

    # Download databases
    $wifiLatestContent = $null
    $btLatestContent   = $null

    if ($wifiDevice) { $wifiLatestContent = Get-RemoteContent -Url $wifiLatestUrl }
    if ($btDevice)   { $btLatestContent   = Get-RemoteContent -Url $btLatestUrl }

    if (($wifiDevice -and (-not $wifiLatestContent)) -or
        ($btDevice   -and (-not $btLatestContent))) {
        Write-Host " Failed to download driver information. Please check your internet connection." -ForegroundColor Red
        Cleanup
        if (-not $AutoMode) {
            Write-Host "`n Press any key..."
            $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
        }
        Show-FinalCredits
        exit
    }

    Write-Host " Parsing driver information..." -ForegroundColor Green
    Write-Host ""

    # Parse .md files
    $wifiData   = if ($wifiLatestContent) { Parse-WiFiLatestMd -Content $wifiLatestContent }  else { $null }
    $btData     = if ($btLatestContent)   { Parse-BTLatestMd   -Content $btLatestContent }    else { $null }

    # ---- Match detected devices to database ----

    $wifiInfo = $null
    $btInfo   = $null

    if ($wifiDevice -and $wifiData) {
        $devEntry = $wifiData.Devices[$wifiDevice.DEV]
        if ($devEntry) {
            Write-Host " Found compatible device: Intel Wireless Wi-Fi (HWID: $($wifiDevice.DEV))" -ForegroundColor Green
            $wifiCurrentVersion = Get-CurrentDriverVersion -DeviceInstanceId $wifiDevice.InstanceId

            # Determine target version and date for this device
            $wifiDeviceVersion = $wifiData.LatestVersion
            $wifiDeviceDate    = $wifiData.ReleaseDate

            if ($devEntry.LatestVersion) {
                $wifiDeviceVersion = $devEntry.LatestVersion
                $wifiDeviceDate    = if ($devEntry.ReleaseDate) { $devEntry.ReleaseDate } else { $wifiData.ReleaseDate }
            }

            $wifiIsLegacy = ($wifiDeviceVersion -ne $wifiData.LatestVersion)

            # Try to get versioned download info
            $wifiDownloadBlock = $null
            if ($wifiDeviceVersion) {
                $versionedInfo = Get-VersionedWiFiDownloadInfo -Version $wifiDeviceVersion
                if ($versionedInfo) {
                    $wifiDownloadBlock = @{
                        DEVs    = [System.Collections.Generic.List[string]]::new()
                        SHA256  = $versionedInfo.SHA256
                        Link    = $versionedInfo.Link
                        Backup  = $versionedInfo.Backup
                        Version = $versionedInfo.Version
                        Date    = $versionedInfo.Date
                    }
                    $wifiDownloadBlock.DEVs.Add("DEV_$($wifiDevice.DEV)")
                    Write-DebugMessage "Using versioned Wi-Fi download info for version $wifiDeviceVersion"
                }
            }

            # If versioned info not available, log error
            if (-not $wifiDownloadBlock) {
                Write-DebugMessage "Versioned Wi-Fi download info not found for version $wifiDeviceVersion"
            }

            $wifiInfo = @{
                DEV                 = $wifiDevice.DEV
                InstanceId          = $wifiDevice.InstanceId
                Chipset             = $devEntry.Chipset
                Models              = $devEntry.Models
                Generation          = $devEntry.Generation
                LatestVersion       = $wifiDeviceVersion
                ReleaseDate         = $wifiDeviceDate
                GlobalLatestVersion = $wifiData.LatestVersion
                IsLegacy            = $wifiIsLegacy
                CurrentVersion      = $wifiCurrentVersion
                Block               = $wifiDownloadBlock
            }
        } else {
            Write-Host " [WARNING] Wi-Fi device DEV_$($wifiDevice.DEV) not found in database." -ForegroundColor Yellow
        }
    }

    if ($btDevice -and $btData) {
        $btId = $btDevice.PID   # For USB this is PID, for PCI this is DEV (both 4-hex)
        $pidEntry = $btData.Devices[$btId]
        if ($pidEntry) {
            Write-Host " Found compatible device: Intel Wireless Bluetooth ($($btDevice.Type) - ID: $btId)" -ForegroundColor Green
            $btCurrentVersion = Get-CurrentDriverVersion -DeviceInstanceId $btDevice.InstanceId

            # Determine target version and date for this device
            $btDeviceVersion = $btData.LatestVersion
            $btDeviceDate    = $btData.ReleaseDate

            if ($pidEntry.LatestVersion) {
                $btDeviceVersion = $pidEntry.LatestVersion
                $btDeviceDate    = if ($pidEntry.ReleaseDate) { $pidEntry.ReleaseDate } else { $btData.ReleaseDate }
            }

            $btIsLegacy = ($btDeviceVersion -ne $btData.LatestVersion) -and ($btDevice.Type -eq "USB")

            # Try to get versioned download info (use DeviceType to select correct file)
            $btDownloadBlock = $null
            if ($btDeviceVersion) {
                $versionedInfo = Get-VersionedBTDownloadInfo -Version $btDeviceVersion -BtPID $btId -DeviceType $btDevice.Type
                if ($versionedInfo) {
                    $btDownloadBlock = @{
                        HWIDs   = [System.Collections.Generic.List[string]]::new()
                        SHA256  = $versionedInfo.SHA256
                        Link    = $versionedInfo.Link
                        Backup  = $versionedInfo.Backup
                        Version = $versionedInfo.Version
                        Date    = $versionedInfo.Date
                    }
                    $btDownloadBlock.HWIDs.Add($btDevice.HardwareID)
                    Write-DebugMessage "Using versioned BT download info for $($btDevice.Type) (ID: $btId) version $btDeviceVersion"
                }
            }

            if (-not $btDownloadBlock) {
                Write-DebugMessage "Versioned BT download info not found for $($btDevice.Type) ID $btId version $btDeviceVersion"
            }

            $btInfo = @{
                PID                 = $btId
                Type                = $btDevice.Type
                InstanceId          = $btDevice.InstanceId
                Chipset             = $pidEntry.Chipset
                Generation          = $pidEntry.Generation
                Bluetooth           = $pidEntry.Bluetooth
                LatestVersion       = $btDeviceVersion
                ReleaseDate         = $btDeviceDate
                GlobalLatestVersion = $btData.LatestVersion
                IsLegacy            = $btIsLegacy
                CurrentVersion      = $btCurrentVersion
                Block               = $btDownloadBlock
            }
        } else {
            Write-Host " [WARNING] Bluetooth $($btDevice.Type) ID $btId not found in database." -ForegroundColor Yellow
        }
    }

    if (-not $wifiInfo -and -not $btInfo) {
        Write-Host "`n No compatible devices matched in the database." -ForegroundColor Yellow
        Cleanup
        if (-not $AutoMode) {
            Write-Host "`n Press any key..."
            $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
        }
        Show-FinalCredits
        exit
    }

    # ---- Platform Information display ----

    Write-Host ""
    Write-Host " =============== Platform Information ===============" -ForegroundColor Cyan
    Write-Host ""

    $wifiNeedsUpdate = $false
    $btNeedsUpdate   = $false

    if ($wifiInfo) {
        Write-Host " Chipset: Intel $($wifiInfo.Generation) $($wifiInfo.Chipset)" -ForegroundColor White
        Write-Host " Model: $($wifiInfo.Models)" -ForegroundColor Gray

        if ($wifiInfo.IsLegacy) {
            Write-Host " [LEGACY] Support ended - last available version: $($wifiInfo.LatestVersion) (current active: $($wifiInfo.GlobalLatestVersion))" -ForegroundColor DarkYellow
        }

        if ($wifiInfo.CurrentVersion) {
            Write-Host " Current Version: $($wifiInfo.CurrentVersion) ---> Latest Version: $($wifiInfo.LatestVersion)" -ForegroundColor Gray
        } else {
            Write-Host " Current Version: Unable to determine ---> Latest Version: $($wifiInfo.LatestVersion)" -ForegroundColor Gray
        }

        Write-Host " Driver Date: $($wifiInfo.ReleaseDate)" -ForegroundColor Yellow

        if ($wifiInfo.CurrentVersion) {
            try {
                $curVer    = [version]$wifiInfo.CurrentVersion
                $latestVer = [version]$wifiInfo.LatestVersion
                if ($curVer -lt $latestVer) {
                    Write-Host " Status: Update available - current: $($wifiInfo.CurrentVersion), latest: $($wifiInfo.LatestVersion)" -ForegroundColor Yellow
                    $wifiNeedsUpdate = $true
                } elseif ($curVer -gt $latestVer) {
                    Write-Host " Status: Newer version installed (may be a pre-release)." -ForegroundColor Cyan
                } else {
                    Write-Host " Status: Already on latest available version." -ForegroundColor Green
                }
            } catch {
                if ($wifiInfo.CurrentVersion -ne $wifiInfo.LatestVersion) {
                    Write-Host " Status: Update available - current: $($wifiInfo.CurrentVersion), latest: $($wifiInfo.LatestVersion)" -ForegroundColor Yellow
                    $wifiNeedsUpdate = $true
                } else {
                    Write-Host " Status: Already on latest available version." -ForegroundColor Green
                }
            }
        } else {
            Write-Host " Status: Driver will be installed." -ForegroundColor Yellow
            $wifiNeedsUpdate = $true
        }
        Write-Host ""
    }

    if ($btInfo) {
        if ($wifiInfo) {
            Write-Host " Chipset: Intel $($btInfo.Generation) $($btInfo.Chipset)" -ForegroundColor White
        } else {
            Write-Host " Chipset: Intel Standalone Bluetooth Adapter ($($btInfo.Type))" -ForegroundColor White
        }
        Write-Host " Device: Intel Wireless Bluetooth $($btInfo.Bluetooth)" -ForegroundColor Gray
        Write-Host " Interface: $($btInfo.Type)" -ForegroundColor Gray

        if ($btInfo.IsLegacy) {
            Write-Host " [LEGACY] Support ended - last available version: $($btInfo.LatestVersion) (current active: $($btInfo.GlobalLatestVersion))" -ForegroundColor DarkYellow
        }

        if ($btInfo.CurrentVersion) {
            Write-Host " Current Version: $($btInfo.CurrentVersion) ---> Latest Version: $($btInfo.LatestVersion)" -ForegroundColor Gray
        } else {
            Write-Host " Current Version: Unable to determine ---> Latest Version: $($btInfo.LatestVersion)" -ForegroundColor Gray
        }

        Write-Host " Driver Date: $($btInfo.ReleaseDate)" -ForegroundColor Yellow

        if ($btInfo.CurrentVersion) {
            try {
                $curVer    = [version]$btInfo.CurrentVersion
                $latestVer = [version]$btInfo.LatestVersion
                if ($curVer -lt $latestVer) {
                    Write-Host " Status: Update available - current: $($btInfo.CurrentVersion), latest: $($btInfo.LatestVersion)" -ForegroundColor Yellow
                    $btNeedsUpdate = $true
                } elseif ($curVer -gt $latestVer) {
                    Write-Host " Status: Newer version installed (may be a pre-release)." -ForegroundColor Cyan
                } else {
                    Write-Host " Status: Already on latest available version." -ForegroundColor Green
                }
            } catch {
                if ($btInfo.CurrentVersion -ne $btInfo.LatestVersion) {
                    Write-Host " Status: Update available - current: $($btInfo.CurrentVersion), latest: $($btInfo.LatestVersion)" -ForegroundColor Yellow
                    $btNeedsUpdate = $true
                } else {
                    Write-Host " Status: Already on latest available version." -ForegroundColor Green
                }
            }
        } else {
            Write-Host " Status: Driver will be installed." -ForegroundColor Yellow
            $btNeedsUpdate = $true
        }
        Write-Host ""
    }

    # ---- Update / reinstall prompt ----

    $updateCount = 0
    if ($wifiNeedsUpdate) { $updateCount++ }
    if ($btNeedsUpdate)   { $updateCount++ }

    if ($updateCount -gt 0) {
        $driverWord = if ($updateCount -gt 1) { "drivers" } else { "driver" }
        Write-Host " A newer version of the $driverWord is available." -ForegroundColor Green

        if ($AutoMode) {
            $response = "Y"
            Write-Host " Auto mode: automatically installing (Y)." -ForegroundColor Cyan
        } else {
            $response = Read-Host " Do you want to install the latest $driverWord? (Y/N)"
        }

        if (-not ($response -eq "Y" -or $response -eq "y")) {
            Write-Host "`n Installation cancelled." -ForegroundColor Yellow
            Cleanup
            if (-not $AutoMode) {
                Write-Host "`n Press any key..."
                $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
            }
            Show-FinalCredits
            exit
        }
    } else {
        # Both up to date - offer force reinstall
        Write-Host " All drivers are up to date." -ForegroundColor Green

        if ($AutoMode) {
            $response = "Y"
            Write-Host " Auto mode: automatically forcing reinstall (Y)." -ForegroundColor Cyan
        } else {
            $response = Read-Host " Do you want to force reinstall this driver(s) anyway? (Y/N)"
        }

        if ($response -eq "Y" -or $response -eq "y") {
            if ($wifiInfo) { $wifiNeedsUpdate = $true }
            if ($btInfo)   { $btNeedsUpdate   = $true }
        } else {
            Write-Host "`n Installation cancelled." -ForegroundColor Yellow
            Cleanup
            if (-not $AutoMode) {
                Write-Host "`n Press any key..."
                $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
            }
            Show-FinalCredits
            exit
        }
    }

    # ------------------------------------------
    $confirmResponse = Show-Screen3
    # ------------------------------------------

    if (-not ($confirmResponse -eq "Y" -or $confirmResponse -eq "y")) {
        Write-Host "`n Update cancelled." -ForegroundColor Yellow
        Cleanup
        if (-not $AutoMode) {
            Write-Host "`n Press any key..."
            $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
        }
        Show-FinalCredits
        exit
    }

    # System Restore Point
    Write-Host "`n Starting driver update process..." -ForegroundColor Green
    Write-Host " Creating system restore point..." -ForegroundColor Yellow

    try {
        try { $null = Enable-ComputerRestore -Drive "C:\" -ErrorAction SilentlyContinue } catch { }

        $restorePointDescription = "Before Intel Wi-Fi BT Driver Update - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
        $warningMessages = @()
        Checkpoint-Computer -Description $restorePointDescription -RestorePointType "MODIFY_SETTINGS" -WarningVariable warningMessages -WarningAction SilentlyContinue -ErrorAction Stop

        if ($warningMessages.Count -gt 0) {
            $warnText = $warningMessages -join " "
            if ($warnText -match "1440 minutes" -or $warnText -match "past.*minutes") {
                throw "RestorePointFrequencyLimit"
            }
        }

        Write-Host " System restore point created successfully." -ForegroundColor Green
        Write-Host " '$restorePointDescription'" -ForegroundColor Green
        Write-Host "`n Preparing for installation..." -ForegroundColor Yellow
        Start-Sleep -Seconds 5

    } catch {
        $errMsg = $_.Exception.Message
        if ($errMsg -match "RestorePointFrequencyLimit" -or $errMsg -match "1440 minutes") {
            Write-Host "`n IMPORTANT NOTICE:" -ForegroundColor Yellow
            Write-Host " Another restore point was created within the last 24 hours." -ForegroundColor Yellow
            Write-Host " Windows currently cannot create more restore points." -ForegroundColor Yellow
            Write-Host ""

            if ($AutoMode) {
                $continueResponse = "Y"
                Write-Host " Auto mode: automatically continuing without restore point (Y)." -ForegroundColor Cyan
            } else {
                $continueResponse = Read-Host " Do you want to continue without creating a restore point? (Y/N)"
            }

            if (-not ($continueResponse -eq "Y" -or $continueResponse -eq "y")) {
                Write-Host "`n Installation cancelled." -ForegroundColor Yellow
                Cleanup
                if (-not $AutoMode) {
                    Write-Host "`n Press any key..."
                    $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
                }
                Show-FinalCredits
                exit
            }
        } else {
            Write-Host " WARNING: Could not create system restore point. Continuing anyway..." -ForegroundColor Yellow
        }
        Write-Host "`n Preparing for installation..." -ForegroundColor Gray
        Start-Sleep -Seconds 5
    }

    # ------------------------------------------
    Show-Screen4
    # ------------------------------------------

    $successCount = 0

    # Install Wi-Fi driver
    if ($wifiNeedsUpdate -and $wifiInfo -and $wifiInfo.Block -and $wifiInfo.Block.Link) {
        $wifiResult = Install-DriverWithFallback `
            -PrimaryUrl       $wifiInfo.Block.Link `
            -BackupUrl        $wifiInfo.Block.Backup `
            -ExpectedHash     $wifiInfo.Block.SHA256 `
            -DeviceInstanceId $wifiInfo.InstanceId `
            -DeviceType       "Intel Wi-Fi" `
            -VersionLabel     $wifiInfo.LatestVersion

        if ($wifiResult) { $successCount++ }
    } elseif ($wifiNeedsUpdate) {
        Write-Host "`n ERROR: No download information found for Wi-Fi driver (DEV_$($wifiInfo.DEV))." -ForegroundColor Red
        Write-Host " Please check versioned release files (intel-wifi-<version>.txt in archive-wifi release)." -ForegroundColor Yellow
    }

    # Install Bluetooth driver
    if ($btNeedsUpdate -and $btInfo -and $btInfo.Block -and $btInfo.Block.Link) {
        $btResult = Install-DriverWithFallback `
            -PrimaryUrl      $btInfo.Block.Link `
            -BackupUrl       $btInfo.Block.Backup `
            -ExpectedHash    $btInfo.Block.SHA256 `
            -DeviceInstanceId $btInfo.InstanceId `
            -DeviceType      "Intel Bluetooth ($($btInfo.Type))" `
            -VersionLabel    $btInfo.LatestVersion

        if ($btResult) { $successCount++ }
    } elseif ($btNeedsUpdate) {
        Write-Host "`n ERROR: No download information found for Bluetooth driver (ID: $($btInfo.PID), Type: $($btInfo.Type))." -ForegroundColor Red
        Write-Host " Please check versioned release files (intel-bt-<version>_pid<PID>.txt or intel-bt-<version>_pci.txt in archive-bt release)." -ForegroundColor Yellow
    }

    # Summary
    if ($successCount -gt 0) {
        Write-Host "`n IMPORTANT NOTICE:" -ForegroundColor Yellow
        Write-Host " Computer restart may be required to complete driver installation!" -ForegroundColor Yellow
        $driverWord = if ($successCount -gt 1) { "drivers" } else { "driver" }
        Write-Host "`n Summary: Successfully installed $successCount $driverWord." -ForegroundColor Green
    } else {
        Write-Host "`n No drivers were successfully installed." -ForegroundColor Red
    }

    Cleanup

    Show-FinalSummary

    Write-Host "`n Driver update process completed." -ForegroundColor Cyan
    Write-Host " If you have any issues with this tool, please report them at:"
    Write-Host " https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater" -ForegroundColor Cyan

    if ($DebugMode) {
        Write-Host "`n [DEBUG MODE ENABLED - All debug messages were shown]" -ForegroundColor Magenta
    }

    if (-not $AutoMode) {
        Write-Host "`n Press any key to continue..." -ForegroundColor Gray
        $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
    }

    Show-FinalCredits
    exit 0

} catch {
    Write-Log "Unhandled error in main execution: $($_.Exception.Message)" -Type "ERROR"
    Write-Host " An unexpected error occurred. Please check the log file at $logFile for details." -ForegroundColor Red
    Cleanup
    if (-not $AutoMode) {
        Write-Host "`n Press any key..."
        $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
    }
    Show-FinalCredits
    exit 1
}