<#
.SYNOPSIS
  Apply Homestead V3 Family Hotfix v9 (NeoForge 1.21.1).

.DESCRIPTION
  Updates ONE mod -- the Homestead AI Assistant ("Atlas") jar -- to the
  version the server now runs. Backs up your current mods first.

  New in v9 (CUMULATIVE -- includes v6/v7/v8):
    - HOMESTEAD POPS: figurines of the FAMILY -- Drew, Cassie, Logan,
      Ayden, Aurora, Dante, and Freddy -- made from your real skins.
      Craft a Homestead Pop Box (cardboard + dyes + a cake in the
      middle), place it, right-click to crack it open: a random family
      member pops out. Collect the whole family!
    - Fix: JCSMP Pops used as Create stock keepers no longer lose
      their seat when chunks reload.
    - Everything from v7/v8: Dante (chat orders, expeditions,
      Clipboard, routes) + JCSMP Pops.

  Auto-detects common launcher instance paths (CurseForge, Prism, Modrinth
  App, ATLauncher). Override with -ModsFolder if your install is elsewhere.

.EXAMPLE
  .\Apply-FamilyHotfix-v9.ps1
  .\Apply-FamilyHotfix-v9.ps1 -ModsFolder "D:\Games\MC\Homestead\mods"
  .\Apply-FamilyHotfix-v9.ps1 -Force
#>
[CmdletBinding()]
param(
    [string]$ModsFolder,
    [switch]$Force
)

$ErrorActionPreference = 'Stop'
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$jarSource = Join-Path $scriptDir 'mods-add'

# ---- Expected jar + sha256 (verified at build time) ----
$expected = @{
    'minecraft-ai-assistant-2.0.0.jar' = '1f9d20da2893cdf84be14330987c4fe1e2fb04e429fdf85c6e02028701685f85'
    'jcsmp_pops-1.0.2.jar' = 'b91f273a15d5714a8a0e1d8599d1c249de88b2323f8f5f62b8f5c98f416e5560'
}

function Write-Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Write-Ok  ($msg) { Write-Host "    [OK] $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host "    [!]  $msg" -ForegroundColor Yellow }
function Write-Err ($msg) { Write-Host "    [X]  $msg" -ForegroundColor Red }

# ---- 0. Verify the bundled jar exists and matches hash ----
Write-Step "Verifying bundled mod jar"
if (-not (Test-Path $jarSource)) {
    Write-Err "Jar source folder missing: $jarSource"
    Write-Err "Make sure you extracted the ENTIRE hotfix zip -- not just this script."
    exit 1
}
$verifyFailed = $false
foreach ($name in $expected.Keys) {
    $path = Join-Path $jarSource $name
    if (-not (Test-Path $path)) { Write-Err "Missing: $name"; $verifyFailed = $true; continue }
    $hash = (Get-FileHash -Algorithm SHA256 -Path $path).Hash.ToLower()
    if ($hash -ne $expected[$name]) { Write-Err "Hash mismatch for $name (got $hash)"; $verifyFailed = $true }
    else { Write-Ok $name }
}
if ($verifyFailed) { Write-Err "Bundle integrity check failed. Re-download the hotfix zip."; exit 1 }

# ---- 1. Find the mods folder ----
Write-Step "Locating Minecraft mods folder"
if ($ModsFolder) {
    if (-not (Test-Path $ModsFolder)) { Write-Err "Specified -ModsFolder does not exist: $ModsFolder"; exit 1 }
    Write-Ok "Using -ModsFolder override: $ModsFolder"
} else {
    $candidates = New-Object System.Collections.Generic.List[string]
    $cfRoot = Join-Path $env:USERPROFILE 'curseforge\minecraft\Instances'
    if (Test-Path $cfRoot) { Get-ChildItem -Path $cfRoot -Directory -ErrorAction SilentlyContinue | ForEach-Object {
        $m = Join-Path $_.FullName 'mods'; if (Test-Path $m) { $candidates.Add($m) } } }
    $prismRoot = Join-Path $env:APPDATA 'PrismLauncher\instances'
    if (Test-Path $prismRoot) { Get-ChildItem -Path $prismRoot -Directory -ErrorAction SilentlyContinue | ForEach-Object {
        $m = Join-Path $_.FullName '.minecraft\mods'; if (Test-Path $m) { $candidates.Add($m) } } }
    $mrRoot = Join-Path $env:APPDATA 'com.modrinth.theseus\profiles'
    if (Test-Path $mrRoot) { Get-ChildItem -Path $mrRoot -Directory -ErrorAction SilentlyContinue | ForEach-Object {
        $m = Join-Path $_.FullName 'mods'; if (Test-Path $m) { $candidates.Add($m) } } }
    $atRoot = Join-Path $env:USERPROFILE 'ATLauncher\instances'
    if (Test-Path $atRoot) { Get-ChildItem -Path $atRoot -Directory -ErrorAction SilentlyContinue | ForEach-Object {
        $m = Join-Path $_.FullName 'mods'; if (Test-Path $m) { $candidates.Add($m) } } }
    $vanilla = Join-Path $env:APPDATA '.minecraft\mods'
    if (Test-Path $vanilla) { $candidates.Add($vanilla) }

    if ($candidates.Count -eq 0) {
        Write-Err "No mods folders found in standard launcher locations."
        Write-Err "Pass -ModsFolder C:\path\to\mods to specify manually."; exit 1
    }
    $scored = foreach ($c in $candidates) {
        $score = 0
        if ($c -match 'homestead') { $score += 100 }
        if ($c -match 'vanilla')   { $score += 40 }
        $jarCount = (Get-ChildItem -Path $c -Filter *.jar -ErrorAction SilentlyContinue).Count
        if (Get-ChildItem -Path $c -Filter 'create-1.21.1-*.jar' -ErrorAction SilentlyContinue) { $score += 80 }
        $score += [Math]::Min($jarCount, 50)
        [PSCustomObject]@{ Path = $c; Score = $score; Jars = $jarCount }
    }
    $scored = $scored | Sort-Object -Property Score -Descending
    if ($scored[0].Score -lt 80) {
        Write-Warn "Couldn't confidently find the Homestead instance. Found these:"
        $scored | ForEach-Object { Write-Host ("        [{0:D3} jars] {1}" -f $_.Jars, $_.Path) }
        Write-Err "Re-run with -ModsFolder to pick the right one."; exit 1
    }
    $ModsFolder = $scored[0].Path
    Write-Ok "Found Homestead instance: $ModsFolder"
    Write-Ok "Current mod count: $($scored[0].Jars)"
}

# ---- 2. Confirm ----
if (-not $Force) {
    Write-Host ""
    Write-Host "Will update the Atlas mod jar in:" -ForegroundColor White
    Write-Host "  $ModsFolder" -ForegroundColor White
    Write-Host "(Existing mods are backed up first.)" -ForegroundColor Gray
    Write-Host ""
    $resp = Read-Host "Proceed? [y/N]"
    if ($resp -notmatch '^[yY]') { Write-Host "Aborted." -ForegroundColor Yellow; exit 0 }
}

# ---- 3. Backup ----
Write-Step "Backing up current mods folder"
$instanceRoot = Split-Path -Parent $ModsFolder
$backupRoot   = Join-Path $instanceRoot 'mods-backups'
if (-not (Test-Path $backupRoot)) { New-Item -ItemType Directory -Path $backupRoot | Out-Null }
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$backupDir = Join-Path $backupRoot "pre-v9-$stamp"
Copy-Item -Path $ModsFolder -Destination $backupDir -Recurse
Write-Ok "Backed up $((Get-ChildItem -Path $backupDir -Filter *.jar).Count) jars to: $backupDir"

# ---- 4. Remove older versions of the Atlas mod ----
Write-Step "Removing older versions of the Atlas mod (if any)"
$removed = 0
Get-ChildItem -Path $ModsFolder -Include "minecraft-ai-assistant*.jar","jcsmp_pops*.jar" -Recurse -Depth 0 -ErrorAction SilentlyContinue | ForEach-Object {
    if (-not $expected.ContainsKey($_.Name)) {
        Remove-Item -Path $_.FullName -Force; Write-Warn "Removed older: $($_.Name)"; $script:removed++
    }
}
if ($removed -eq 0) { Write-Ok "No older versions found." }

# ---- 5. Copy / overwrite the updated jar ----
Write-Step "Installing updated Atlas jar"
$copied = 0; $skipped = 0
foreach ($name in $expected.Keys) {
    $dst = Join-Path $ModsFolder $name
    if (Test-Path $dst) {
        $h = (Get-FileHash -Algorithm SHA256 -Path $dst).Hash.ToLower()
        if ($h -eq $expected[$name]) { Write-Ok "Already up to date: $name"; $skipped++; continue }
    }
    Copy-Item -Path (Join-Path $jarSource $name) -Destination $dst -Force
    Write-Ok "Updated: $name"; $copied++
}

# ---- 6. Done ----
Write-Host ""
Write-Step "Done"
Write-Host "  Updated: $copied" -ForegroundColor Green
Write-Host "  Skipped: $skipped (already up to date)" -ForegroundColor Gray
Write-Host "  Removed: $removed older versions" -ForegroundColor Gray
Write-Host "  Backup:  $backupDir" -ForegroundColor Gray
Write-Host ""
Write-Host "Restart your Minecraft launcher and reconnect to homestead.fritzytech.com (44.220.107.36)." -ForegroundColor White
Write-Host "If the game crashes on load, restore by copying jars back from the backup folder." -ForegroundColor Gray
