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

<#PSScriptInfo
.VERSION 2026.03.0002
.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
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
v2026.03.0002 - Initial release aligned with Universal Intel Chipset Device Updater architecture
#>


<#
.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 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 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.03.0002"
# =============================================

$isSFX = $MyInvocation.ScriptName -like "$env:SystemRoot\Temp\universal-intel-wifi-bt-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"
$wifiDownloadUrl = $githubBaseUrl + "intel-wifi-drivers-download.txt"
$btDownloadUrl   = $githubBaseUrl + "intel-bt-drivers-download.txt"
$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
# =============================================
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 / www.firstever.tech " -NoNewline -ForegroundColor Green -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " This tool is not affiliated with Intel Corporation. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Drivers are sourced from official Intel/WU servers. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Use at your own risk. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Visit: GitHub.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater " -NoNewline -ForegroundColor White -BackgroundColor DarkBlue
    Write-Host "**" -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/WiFiBT-Updater-$latestVersion-Win10-Win11.exe"
                $downloadsFolder = Get-DownloadsFolder
                $outputPath = Join-Path $downloadsFolder "WiFiBT-Updater-$latestVersion-Win10-Win11.exe"

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

                try {
                    Invoke-WebRequest -Uri $downloadUrl -OutFile $outputPath -UseBasicParsing -ErrorAction Stop
                    Write-Host " Download completed. Please run the new version." -ForegroundColor Green
                } catch {
                    Write-Host " Download failed: $($_.Exception.Message)" -ForegroundColor Red
                    Write-Host " Please visit: https://github.com/FirstEverTech/Universal-Intel-WiFi-BT-Updater/releases" -ForegroundColor Cyan
                }
            }

            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) - UZUPEŁNIONE O NOWE ID Z BAZY
$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 PID IDs (USB VID_8087)
$supportedBTPIDs = @("0025", "0AAA", "0026", "0032", "0033", "0036", "0037", "0038")

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 {
        # Try Bluetooth class first
        $devices = Get-PnpDevice -Class "Bluetooth" -ErrorAction SilentlyContinue |
            Where-Object { $_.Status -eq "OK" }

        # Fall back to USB class if nothing found
        if (-not $devices -or $devices.Count -eq 0) {
            $devices = Get-PnpDevice -ErrorAction SilentlyContinue |
                Where-Object { $_.Status -eq "OK" -and $_.HardwareID -like "*VID_8087*" }
        }

        foreach ($device in $devices) {
            foreach ($hwid in $device.HardwareID) {
                if ($hwid -match 'USB\\VID_8087&PID_([0-9A-F]{4})') {
                    $btPid = $matches[1].ToUpper()
                    if ($supportedBTPIDs -contains $btPid) {
                        Write-DebugMessage "Found Intel BT device: PID=$btPid ($($device.FriendlyName))"
                        return [PSCustomObject]@{
                            PID          = $btPid
                            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
    }
}

# =============================================
# DATA PARSING FUNCTIONS
# =============================================

# POPRAWIONA FUNKCJA PARSUJĄCA nowy format (4 kolumny)
function Parse-WiFiLatestMd {
    param([string]$Content)

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

    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: $($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()
                $result.Devices[$devId] = @{
                    Chipset    = $chipset
                    Models     = $models
                    Generation = $gen
                }
                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       = @{}   # PID (4 hex) -> @{ Chipset, Generation, Bluetooth }
    }

    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: $($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*\|') {
                $btPid   = $matches[1].ToUpper()
                $chipset = $matches[2].Trim()
                $gen     = $matches[3].Trim()
                $bt      = $matches[4].Trim()
                $result.Devices[$btPid] = @{ Chipset = $chipset; Generation = $gen; Bluetooth = $bt }
                Write-DebugMessage "BT device parsed: $btPid -> $chipset BT $bt"
            }
        }
    } catch {
        Write-Log "BT MD parsing failed: $($_.Exception.Message)" -Type "ERROR"
    }

    return $result
}

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

    $result = @{
        Name    = $null
        Version = $null
        Date    = $null
        SHA256  = $null
        Link    = $null
        Backup  = $null
    }

    try {
        $lines = $Content -split "`n" | ForEach-Object { $_.Trim() }
        foreach ($line in $lines) {
            if     ($line -match '^Name\s*=\s*(.+)')                              { $result.Name    = $matches[1].Trim() }
            elseif ($line -match '^DriverVer\s*=\s*([^,]+),\s*([0-9.]+)')        { $result.Date    = $matches[1].Trim(); $result.Version = $matches[2].Trim() }
            elseif ($line -match '^SHA256\s*=\s*([A-Fa-f0-9]{64})')              { $result.SHA256  = $matches[1].ToUpper() }
            elseif ($line -match '^Link\s*=\s*(https?://.+)')                    { $result.Link    = $matches[1].Trim() }
            elseif ($line -match '^Backup\s*=\s*(https?://.+)')                  { $result.Backup  = $matches[1].Trim() }
        }
        Write-DebugMessage "WiFi download list parsed: Version=$($result.Version)"
    } catch {
        Write-Log "WiFi download list parsing failed: $($_.Exception.Message)" -Type "ERROR"
    }

    return $result
}

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

    # Returns @{ Version, Date, Blocks: [ @{ HWIDs, SHA256, Link, Backup } ] }
    $result = @{
        Version = $null
        Date    = $null
        Blocks  = [System.Collections.Generic.List[hashtable]]::new()
    }

    try {
        $blocks = $Content -split "`n`n" | Where-Object { $_.Trim() }

        foreach ($block in $blocks) {
            $lines = $block -split "`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ }

            $hasDriverVer = $lines | Where-Object { $_ -match '^DriverVer\s*=' }
            $hasHWID      = $lines | Where-Object { $_ -match '^USB\\VID_' }

            # Parse global header (Name + DriverVer)
            if ($hasDriverVer) {
                foreach ($line in $lines) {
                    if ($line -match '^DriverVer\s*=\s*([^,]+),\s*([0-9.]+)') {
                        $result.Date    = $matches[1].Trim()
                        $result.Version = $matches[2].Trim()
                        Write-DebugMessage "BT download list version: $($result.Version)"
                    }
                }
            }

            # Parse per-PID data blocks
            if ($hasHWID) {
                $blockData = @{
                    HWIDs  = [System.Collections.Generic.List[string]]::new()
                    SHA256 = $null
                    Link   = $null
                    Backup = $null
                }

                foreach ($line in $lines) {
                    if     ($line -match '^USB\\VID_[0-9A-Fa-f]+&PID_([0-9A-Fa-f]{4})') { $blockData.HWIDs.Add($line) }
                    elseif ($line -match '^SHA256\s*=\s*([A-Fa-f0-9]{64})')              { $blockData.SHA256 = $matches[1].ToUpper() }
                    elseif ($line -match '^Link\s*=\s*(https?://.+)')                    { $blockData.Link   = $matches[1].Trim() }
                    elseif ($line -match '^Backup\s*=\s*(https?://.+)')                  { $blockData.Backup = $matches[1].Trim() }
                }

                if ($blockData.HWIDs.Count -gt 0 -and $blockData.Link) {
                    $result.Blocks.Add($blockData)
                    Write-DebugMessage "BT block parsed: PIDs=$($blockData.HWIDs -join ', '), Link=$($blockData.Link)"
                }
            }
        }
    } catch {
        Write-Log "BT download list parsing failed: $($_.Exception.Message)" -Type "ERROR"
    }

    return $result
}

function Get-BTBlockForDevice {
    param([string]$DevicePID, [object]$BTDownloadData)

    foreach ($block in $BTDownloadData.Blocks) {
        foreach ($hwid in $block.HWIDs) {
            if ($hwid -match "PID_([0-9A-Fa-f]{4})") {
                if ($matches[1].ToUpper() -eq $DevicePID.ToUpper()) {
                    return $block
                }
            }
        }
    }
    return $null
}

# =============================================
# 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
    }
}

# =============================================
# 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 " 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 ($DeviceInstanceId) {
            Write-Host " Updating $DeviceType device driver..." -ForegroundColor Yellow
            $updateOut = pnputil /update-device "$DeviceInstanceId" /install 2>&1
            Write-DebugMessage "pnputil /update-device: $updateOut"
        }

        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 / www.firstever.tech " -NoNewline -ForegroundColor Green -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " This tool is not affiliated with Intel Corporation. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Drivers are sourced from official Intel/WU servers. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " Use at your own risk. " -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** --------------------------------------------------------------------- **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "** **" -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host "**" -NoNewline -ForegroundColor Gray -BackgroundColor DarkBlue
    Write-Host " GitHub: FirstEverTech/Universal-Intel-WiFi-BT-Updater " -NoNewline -ForegroundColor White -BackgroundColor DarkBlue
    Write-Host "**" -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
        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
    $wifiDlContent     = $null
    $btDlContent       = $null

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

    if (($wifiDevice -and (-not $wifiLatestContent -or -not $wifiDlContent)) -or
        ($btDevice   -and (-not $btLatestContent   -or -not $btDlContent))) {
        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 databases
    $wifiData   = if ($wifiLatestContent) { Parse-WiFiLatestMd -Content $wifiLatestContent }  else { $null }
    $btData     = if ($btLatestContent)   { Parse-BTLatestMd   -Content $btLatestContent }    else { $null }
    $wifiDlData = if ($wifiDlContent)     { Parse-WiFiDownloadList -Content $wifiDlContent }   else { $null }
    $btDlData   = if ($btDlContent)       { Parse-BTDownloadList   -Content $btDlContent }     else { $null }

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

    $wifiInfo = $null
    $btInfo   = $null

    if ($wifiDevice -and $wifiData -and $wifiDlData) {
        $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
            $wifiInfo = @{
                DEV            = $wifiDevice.DEV
                InstanceId     = $wifiDevice.InstanceId
                Chipset        = $devEntry.Chipset
                Models         = $devEntry.Models
                Generation     = $devEntry.Generation
                LatestVersion  = $wifiData.LatestVersion
                ReleaseDate    = $wifiData.ReleaseDate
                CurrentVersion = $wifiCurrentVersion
                DlData         = $wifiDlData
            }
        } else {
            Write-Host " [WARNING] Wi-Fi device DEV_$($wifiDevice.DEV) not found in database." -ForegroundColor Yellow
        }
    }

    if ($btDevice -and $btData -and $btDlData) {
        $pidEntry = $btData.Devices[$btDevice.PID]
        if ($pidEntry) {
            Write-Host " Found compatible device: Intel Wireless Bluetooth (PID: $($btDevice.PID))" -ForegroundColor Green
            $btCurrentVersion = Get-CurrentDriverVersion -DeviceInstanceId $btDevice.InstanceId
            $btBlock = Get-BTBlockForDevice -DevicePID $btDevice.PID -BTDownloadData $btDlData
            $btInfo = @{
                PID            = $btDevice.PID
                InstanceId     = $btDevice.InstanceId
                Chipset        = $pidEntry.Chipset
                Generation     = $pidEntry.Generation
                Bluetooth      = $pidEntry.Bluetooth
                LatestVersion  = $btData.LatestVersion
                ReleaseDate    = $btData.ReleaseDate
                CurrentVersion = $btCurrentVersion
                Block          = $btBlock
            }
        } else {
            Write-Host " [WARNING] Bluetooth PID $($btDevice.PID) 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) {
        # Wyświetlanie Wi-Fi
        Write-Host " Chipset: Intel $($wifiInfo.Generation) $($wifiInfo.Chipset)" -ForegroundColor White
        Write-Host " Model: $($wifiInfo.Models)" -ForegroundColor Gray

        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 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 version." -ForegroundColor Green
                }
            }
        } else {
            Write-Host " Status: Driver will be installed." -ForegroundColor Yellow
            $wifiNeedsUpdate = $true
        }
        Write-Host ""
    }

    if ($btInfo) {
        # Wyświetlanie Bluetooth
        if ($wifiInfo) {
            Write-Host " Chipset: Intel $($btInfo.Generation) $($btInfo.Chipset)" -ForegroundColor White
        } else {
            Write-Host " Chipset: Intel Standalone USB Bluetooth Adapter" -ForegroundColor White
        }
        Write-Host " Device: Intel Wireless Bluetooth $($btInfo.Bluetooth)" -ForegroundColor Gray

        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 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 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.DlData.Link) {
        $wifiResult = Install-DriverWithFallback `
            -PrimaryUrl      $wifiInfo.DlData.Link `
            -BackupUrl       $wifiInfo.DlData.Backup `
            -ExpectedHash    $wifiInfo.DlData.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." -ForegroundColor Red
        Write-Host " Please check intel-wifi-drivers-download.txt for missing entries." -ForegroundColor Yellow
    }

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

        if ($btResult) { $successCount++ }
    } elseif ($btNeedsUpdate) {
        Write-Host "`n ERROR: No download information found for Bluetooth driver (PID: $($btInfo.PID))." -ForegroundColor Red
        Write-Host " Please check intel-bt-drivers-download.txt for missing entries." -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
}