# Migrate domains from *.huypham.vn to solutions.com.vn (Phase 6+ rebrand).
# Run on VPS with admin privilege. Idempotent - retry if fail mid-way.
#
# Workflow (3 IIS sites):
#   1. Add binding for new domain (port 80)
#   2. Run win-acme for Let's Encrypt cert via HTTP-01 challenge
#   3. Verify /health/ready + /health/live via new domain
#   4. Remove old binding (optional, via -RemoveOld)
#
# Usage:
#   .\migrate-domains.ps1                    # keep old binding, add new
#   .\migrate-domains.ps1 -RemoveOld         # remove old after verify
#   .\migrate-domains.ps1 -SkipCert          # skip win-acme step
#
# ASCII-only per gotcha #30 (PS 5.1 parser fail on UTF-8 diacritics).

[CmdletBinding()]
param(
    [string]$NewApi    = "api.solutions.com.vn",
    [string]$NewAdmin  = "admin.solutions.com.vn",
    [string]$NewUser   = "eoffice.solutions.com.vn",
    [string]$OldApi    = "api.huypham.vn",
    [string]$OldAdmin  = "admin.huypham.vn",
    [string]$OldUser   = "user.huypham.vn",
    [string]$AdminEmail = "admin@huypham.vn",
    [switch]$RemoveOld,
    [switch]$SkipCert
)

$ErrorActionPreference = 'Stop'
Import-Module WebAdministration

function Write-Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Write-OK($msg)   { Write-Host "  [OK] $msg" -ForegroundColor Green }
function Write-Warn2($msg){ Write-Host "  [!!] $msg" -ForegroundColor Yellow }

# ===================== 1. Pre-flight checks =====================
Write-Step "Pre-flight checks"

$vpsIp = "103.124.94.38"
try {
    $vpsIp = (Invoke-WebRequest -Uri "https://api.ipify.org" -UseBasicParsing -TimeoutSec 5).Content.Trim()
} catch {
    Write-Warn2 "Cannot detect public IP via ipify - fallback to hardcoded $vpsIp"
}
Write-Host "  VPS public IP: $vpsIp"

foreach ($d in @($NewApi, $NewAdmin, $NewUser)) {
    try {
        $resolved = (Resolve-DnsName -Name $d -Type A -ErrorAction Stop | Select-Object -First 1).IPAddress
        if ($resolved -eq $vpsIp) {
            Write-OK "DNS $d = $resolved"
        } else {
            Write-Warn2 "DNS $d = $resolved (not matching VPS IP $vpsIp) - Let's Encrypt may fail"
        }
    } catch {
        Write-Warn2 "DNS resolve FAIL for $d"
        exit 1
    }
}

$siteMap = @(
    @{ Site = "SolutionErp-Api";   Old = $OldApi;   New = $NewApi   },
    @{ Site = "SolutionErp-Admin"; Old = $OldAdmin; New = $NewAdmin },
    @{ Site = "SolutionErp-User";  Old = $OldUser;  New = $NewUser  }
)
foreach ($s in $siteMap) {
    if (-not (Test-Path "IIS:\Sites\$($s.Site)")) {
        Write-Error "Site '$($s.Site)' not found. Run setup-iis-sites.ps1 first."
        exit 1
    }
    Write-OK "IIS site $($s.Site) ready"
}

# ===================== 2. Add new bindings (keep old) =====================
Write-Step "Add HTTP binding for 3 new domains"

foreach ($s in $siteMap) {
    $site = $s.Site
    $new  = $s.New

    $existingHttp = Get-WebBinding -Name $site -Protocol http -HostHeader $new -ErrorAction SilentlyContinue
    if (-not $existingHttp) {
        New-WebBinding -Name $site -IPAddress "*" -Port 80 -HostHeader $new -Protocol http | Out-Null
        Write-OK "Add HTTP binding: $site *:80:$new"
    } else {
        Write-Host "  HTTP binding exists: $site *:80:$new"
    }
}

# ===================== 3. Request cert via win-acme =====================
if (-not $SkipCert) {
    Write-Step "Request Let's Encrypt cert for 3 new domains"

    $WacsExe = "C:\Program Files\win-acme\wacs.exe"
    if (-not (Test-Path $WacsExe)) {
        Write-Error "win-acme not installed. Run setup-ssl.ps1 first, or use -SkipCert."
        exit 1
    }

    foreach ($s in $siteMap) {
        Write-Host ""
        Write-Host "==> Cert for $($s.New)" -ForegroundColor Cyan

        $siteId = (Get-Website $s.Site).Id
        $wacsArgs = @(
            "--target", "manual",
            "--host", $s.New,
            "--store", "certificatestore",
            "--installation", "iis",
            "--installationsiteid", $siteId,
            "--accepttos",
            "--emailaddress", $AdminEmail
        )
        & $WacsExe @wacsArgs
        if ($LASTEXITCODE -ne 0) {
            Write-Warn2 "Cert $($s.New) FAIL exit $LASTEXITCODE - check:"
            Write-Warn2 "  1. Port 80 internet -> VPS open?"
            Write-Warn2 "  2. DNS $($s.New) -> $vpsIp?"
            Write-Warn2 "  3. HTTP binding created?"
        } else {
            Write-OK "Cert $($s.New) installed (HTTPS binding + http->https)"
        }
    }
} else {
    Write-Host "==> SkipCert flag - bypass win-acme" -ForegroundColor Yellow
}

# ===================== 4. Verify new endpoints =====================
Write-Step "Verify new endpoints"

Start-Sleep -Seconds 3

function Test-Endpoint($url) {
    try {
        $r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 10 -SkipCertificateCheck
        if ($r.StatusCode -eq 200) { Write-OK "$url = 200 OK"; return $true }
        Write-Warn2 "$url = $($r.StatusCode) (expected 200)"; return $false
    } catch {
        Write-Warn2 "$url FAIL"
        return $false
    }
}

$apiLive  = Test-Endpoint "https://$NewApi/health/live"
$apiReady = Test-Endpoint "https://$NewApi/health/ready"
$adminOk  = Test-Endpoint "https://$NewAdmin"
$userOk   = Test-Endpoint "https://$NewUser"

$allOk = $apiLive -and $apiReady -and $adminOk -and $userOk

# ===================== 5. Remove old bindings (optional) =====================
if ($RemoveOld) {
    if (-not $allOk) {
        Write-Warn2 "New endpoints not verified OK - skip removing old (keep fallback)"
    } else {
        Write-Step "Remove old bindings (huypham.vn)"
        foreach ($s in $siteMap) {
            $site = $s.Site
            $old  = $s.Old

            $httpOld = Get-WebBinding -Name $site -Protocol http -HostHeader $old -ErrorAction SilentlyContinue
            if ($httpOld) {
                Remove-WebBinding -Name $site -Protocol http -HostHeader $old -Port 80
                Write-OK "Removed HTTP *:80:$old from $site"
            }

            $httpsOld = Get-WebBinding -Name $site -Protocol https -HostHeader $old -ErrorAction SilentlyContinue
            if ($httpsOld) {
                Remove-WebBinding -Name $site -Protocol https -HostHeader $old -Port 443
                Write-OK "Removed HTTPS *:443:$old from $site"
            }
        }
    }
} else {
    Write-Host ""
    Write-Host "[INFO] Old bindings (*.huypham.vn) still active. Run with -RemoveOld after verify." -ForegroundColor Yellow
}

# ===================== 6. Summary =====================
Write-Host ""
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host " MIGRATION DONE" -ForegroundColor Cyan
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host ""
Write-Host "3 new domains:"
$statusApi   = if ($apiLive)  { "[OK]" } else { "[FAIL]" }
$statusReady = if ($apiReady) { "[OK]" } else { "[FAIL]" }
$statusAdmin = if ($adminOk)  { "[OK]" } else { "[FAIL]" }
$statusUser  = if ($userOk)   { "[OK]" } else { "[FAIL]" }
Write-Host "  - https://$NewApi/health/live    $statusApi"
Write-Host "  - https://$NewApi/health/ready   $statusReady"
Write-Host "  - https://$NewAdmin              $statusAdmin"
Write-Host "  - https://$NewUser               $statusUser"
Write-Host ""
Write-Host "Next:"
Write-Host "  1. Trigger CI/CD redeploy (push empty commit)"
Write-Host "     - BE rebuild with new CORS"
Write-Host "     - FE rebuild with VITE_API_BASE_URL=https://$NewApi"
Write-Host "  2. Test login via browser"
Write-Host "  3. After 1-2 days verify stable: .\migrate-domains.ps1 -RemoveOld -SkipCert"
Write-Host ""
if (-not $allOk) {
    Write-Warn2 "Some endpoints failed - check Event Log and IIS log before proceed."
    exit 1
}
