<#
.SYNOPSIS
    Removes orphaned VelaPanel-AutoBlock-* Windows Firewall rules that have no corresponding
    IsActive=1 row in the BlockedIps DB table.

    Root cause: IpBlockMiddleware previously deactivated expired BlockedIp rows (IsActive=0)
    without calling RemoveBlockRuleAsync, leaving OS-level block rules that were never cleaned up.
    This script performs a one-time reconciliation.

.NOTES
    Run once from an elevated PowerShell prompt AFTER deploying the fixed VelaPanel build.
    Uses Microsoft.Data.Sqlite.dll from the VelaPanel publish folder — no external tools needed.
    Safe to run while the panel is stopped or running.
#>

$dbPath      = "C:\velapanel.com\data\panel.db"
$publishDir  = "C:\velapanel.com\publish"
$sqliteDll   = Join-Path $publishDir "Microsoft.Data.Sqlite.dll"
$sqliteEDll  = Join-Path $publishDir "SQLitePCLRaw.core.dll"
$sqliteNDll  = Join-Path $publishDir "SQLitePCLRaw.provider.e_sqlite3.dll"

if (-not (Test-Path $dbPath))   { Write-Error "panel.db not found at $dbPath"; exit 1 }
if (-not (Test-Path $sqliteDll)) { Write-Error "Microsoft.Data.Sqlite.dll not found at $sqliteDll — ensure panel is published to $publishDir"; exit 1 }

# Load the SQLite assembly chain VelaPanel already ships
Add-Type -Path $sqliteEDll   -ErrorAction Stop
Add-Type -Path $sqliteNDll   -ErrorAction Stop
Add-Type -Path $sqliteDll    -ErrorAction Stop

# ── 1. Query active IPs from BlockedIps table ─────────────────────────────────
$activeIps = @()
try {
    $conn = [Microsoft.Data.Sqlite.SqliteConnection]::new("Data Source=$dbPath")
    $conn.Open()
    $cmd = $conn.CreateCommand()
    $cmd.CommandText = "SELECT IpAddress FROM BlockedIps WHERE IsActive=1"
    $reader = $cmd.ExecuteReader()
    while ($reader.Read()) { $activeIps += $reader.GetString(0).ToLower() }
    $reader.Close()
    $conn.Close()
} catch {
    Write-Error "Failed to query panel.db: $_"
    exit 1
}

Write-Host "Active BlockedIp rows in DB: $($activeIps.Count)"

# ── 2. Find all VelaPanel-AutoBlock-* rules in Windows Firewall ───────────────
$allRules = Get-NetFirewallRule -DisplayName "VelaPanel-AutoBlock-*" -ErrorAction SilentlyContinue
if (-not $allRules) {
    Write-Host "No VelaPanel-AutoBlock-* rules found in Windows Firewall. Nothing to do."
    exit 0
}
Write-Host "VelaPanel-AutoBlock-* rules in Windows Firewall: $($allRules.Count)"

# ── 3. Remove rules whose IP is NOT in the active DB set ─────────────────────
$removed = 0
foreach ($rule in $allRules) {
    $suffix   = $rule.DisplayName -replace '^VelaPanel-AutoBlock-', ''
    $segments = $suffix -split '-'
    # IPv4: exactly 4 all-digit segments → rejoin with dots
    # CIDR or IPv6: rejoin with colons
    $isIpv4 = ($segments.Count -eq 4 -and ($segments | Where-Object { $_ -match '^\d{1,3}$' }).Count -eq 4)
    $ip = if ($isIpv4) { $suffix -replace '-', '.' } else { $suffix -replace '-', ':' }
    $ip = $ip.ToLower()

    if ($activeIps -notcontains $ip) {
        Write-Host "  Removing orphaned: $($rule.DisplayName)  ($ip)"
        Remove-NetFirewallRule -Name $rule.Name -ErrorAction SilentlyContinue
        $removed++
    } else {
        Write-Host "  Keeping active:    $($rule.DisplayName)  ($ip)"
    }
}

Write-Host ""
Write-Host "Done. Removed $removed orphaned firewall block rule(s)."
