@echo off
setlocal
title EuroTrans - Instalacion completa

echo ==========================================================
echo  EuroTrans - Instalacion completa (telemetria + launcher)
echo ==========================================================
echo.
echo Este programa va a:
echo   1. Instalar el plugin de telemetria de ETS2 (busca tu carpeta del
echo      juego, copia el plugin, configura el firewall y arranca el juego)
echo   2. Descargar e instalar el launcher de EuroTrans (Node.js si te
echo      falta, dependencias, y conectar tu wallet)
echo.
echo (Este archivo es autosuficiente: no necesita ningun otro archivo en la
echo  misma carpeta. Todo el script vive dentro de este .bat.)
echo.
pause

powershell -NoProfile -ExecutionPolicy Bypass -Command "& { $marker = 'REM ' + 'EUROTRANS_PS1_START'; $body = (Get-Content -Raw -LiteralPath '%~f0') -split [regex]::Escape($marker), 2; Invoke-Expression $body[1] }"

exit /b 0

REM EUROTRANS_PS1_START
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

function Write-Step($msg) { Write-Host "`n==> $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 "[ERROR] $msg" -ForegroundColor Red }

function Test-IsAdmin {
  $id = [Security.Principal.WindowsIdentity]::GetCurrent()
  $principal = New-Object Security.Principal.WindowsPrincipal($id)
  return $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

# ============================================================
# Parte 1: plugin de telemetria de ETS2
# ============================================================
function Install-TelemetryPlugin {
  $Ets2SteamAppId = "227300"
  $InstallDir     = "$env:LOCALAPPDATA\EuroTrans\ets2-telemetry-server"
  $TelemetryUrl   = "http://127.0.0.1:25555/api/ets2/telemetry"

  function Test-Telemetry {
    param([int]$TimeoutSec = 3)
    try {
      $res = Invoke-WebRequest -Uri $TelemetryUrl -TimeoutSec $TimeoutSec -UseBasicParsing
      $json = $res.Content | ConvertFrom-Json
      return [pscustomobject]@{ ServerUp = $true; Connected = [bool]$json.game.connected }
    } catch {
      return [pscustomobject]@{ ServerUp = $false; Connected = $false }
    }
  }

  function Test-IsEts2Folder {
    param([string]$Path)
    if (-not $Path -or -not (Test-Path $Path)) { return $false }
    return (Test-Path (Join-Path $Path "bin\win_x64\eurotrucks2.exe")) -or
           (Test-Path (Join-Path $Path "bin\win_x86\eurotrucks2.exe"))
  }

  function Get-Ets2Arch {
    param([string]$Path)
    if (Test-Path (Join-Path $Path "bin\win_x64\eurotrucks2.exe")) { return "win_x64" }
    return "win_x86"
  }

  function Find-Ets2Path {
    Write-Step "Buscando tu instalacion de Euro Truck Simulator 2..."

    $candidates = New-Object System.Collections.Generic.List[string]
    $candidates.Add("C:\Program Files (x86)\Steam\steamapps\common\Euro Truck Simulator 2")
    $candidates.Add("C:\Program Files\Steam\steamapps\common\Euro Truck Simulator 2")
    $candidates.Add("C:\Program Files (x86)\Euro Truck Simulator 2")

    $steamPaths = New-Object System.Collections.Generic.List[string]
    foreach ($regPath in @(
      "HKLM:\SOFTWARE\WOW6432Node\Valve\Steam",
      "HKLM:\SOFTWARE\Valve\Steam",
      "HKCU:\SOFTWARE\Valve\Steam"
    )) {
      try {
        $props = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue
        if ($props.InstallPath) { $steamPaths.Add($props.InstallPath) }
        if ($props.SteamPath)   { $steamPaths.Add($props.SteamPath) }
      } catch { }
    }

    if ($steamPaths.Count -eq 0) {
      Write-Host "  [diag] Steam no encontrado en el registro." -ForegroundColor DarkGray
    } else {
      Write-Host "  [diag] Steam en registro: $($steamPaths -join ', ')" -ForegroundColor DarkGray
    }

    foreach ($steamPath in ($steamPaths | Select-Object -Unique)) {
      $steamPath = $steamPath -replace '/', '\'
      $candidates.Add((Join-Path $steamPath "steamapps\common\Euro Truck Simulator 2"))

      $acfMain = Join-Path $steamPath "steamapps\appmanifest_227300.acf"
      if (Test-Path $acfMain) {
        try {
          $acfContent = Get-Content $acfMain -Raw
          $dirMatch = [regex]::Match($acfContent, '"installdir"\s+"([^"]+)"')
          if ($dirMatch.Success) {
            $candidates.Add((Join-Path $steamPath "steamapps\common\$($dirMatch.Groups[1].Value)"))
          }
        } catch { }
      }

      $vdf = Join-Path $steamPath "steamapps\libraryfolders.vdf"
      if (Test-Path $vdf) {
        try {
          $content = Get-Content $vdf -Raw -Encoding UTF8
          $libCount = 0
          $vdfMatches = [regex]::Matches($content, '"path"\s*"([^"]+)"')
          foreach ($m in $vdfMatches) {
            $lib = $m.Groups[1].Value -replace '\\\\', '\' -replace '/', '\'
            $candidates.Add((Join-Path $lib "steamapps\common\Euro Truck Simulator 2"))
            $acfLib = Join-Path $lib "steamapps\appmanifest_227300.acf"
            if (Test-Path $acfLib) {
              try {
                $acfLibContent = Get-Content $acfLib -Raw
                $dm = [regex]::Match($acfLibContent, '"installdir"\s+"([^"]+)"')
                if ($dm.Success) {
                  $candidates.Add((Join-Path $lib "steamapps\common\$($dm.Groups[1].Value)"))
                }
              } catch { }
            }
            $libCount++
          }
          $vdfMatches2 = [regex]::Matches($content, '"\d+"\s+"([A-Za-z]:[^"]+)"')
          foreach ($m in $vdfMatches2) {
            $lib = $m.Groups[1].Value -replace '\\\\', '\' -replace '/', '\'
            $candidates.Add((Join-Path $lib "steamapps\common\Euro Truck Simulator 2"))
            $libCount++
          }
          Write-Host "  [diag] VDF parseado OK: $libCount librerias encontradas" -ForegroundColor DarkGray
        } catch {
          Write-Host "  [diag] Error parseando VDF: $_" -ForegroundColor DarkGray
        }
      } else {
        Write-Host "  [diag] VDF no encontrado en: $vdf" -ForegroundColor DarkGray
      }
    }

    $found = $false
    foreach ($c in ($candidates | Select-Object -Unique)) {
      if (Test-IsEts2Folder $c) {
        Write-Ok "Encontrado automaticamente en: $c"
        $found = $true
        return $c
      }
    }
    if (-not $found) {
      Write-Host "  [diag] Candidatos probados ($($($candidates | Select-Object -Unique).Count) total, ninguno valido):" -ForegroundColor DarkGray
      foreach ($c in ($candidates | Select-Object -Unique)) {
        $carpeta = if (Test-Path $c) { "carpeta:SI" } else { "carpeta:NO" }
        $exe64   = if (Test-Path (Join-Path $c "bin\win_x64\eurotrucks2.exe")) { "exe64:SI" } else { "exe64:NO" }
        $exe86   = if (Test-Path (Join-Path $c "bin\win_x86\eurotrucks2.exe")) { "exe86:SI" } else { "exe86:NO" }
        Write-Host "    $carpeta $exe64 $exe86 : $c" -ForegroundColor DarkGray
      }
    }

    Write-Warn "No se pudo encontrar la carpeta de ETS2 automaticamente."
    for ($attempt = 1; $attempt -le 3; $attempt++) {
      $manual = Read-Host "Pega la ruta completa de la carpeta de instalacion de ETS2 (la que contiene la carpeta 'bin')"
      $manual = $manual.Trim('"').Trim()
      if (Test-IsEts2Folder $manual) {
        Write-Ok "Carpeta valida: $manual"
        return $manual
      }
      Write-Err "No se encontro bin\win_x64\eurotrucks2.exe (ni win_x86) dentro de '$manual'. Intento $attempt de 3."
    }
    return $null
  }

  function Install-FirewallAndUrlAcl {
    Write-Step "Configurando el firewall y el permiso de red de Windows (una sola vez)..."

    $setupScript = @'
$ruleName = "ETS2 TELEMETRY SERVER (PORT 25555)"
$existingRule = netsh advfirewall firewall show rule name="$ruleName" 2>&1
if ($LASTEXITCODE -ne 0 -or $existingRule -match "No rules match") {
  netsh advfirewall firewall add rule name="$ruleName" dir=in action=allow protocol=TCP localport=25555 profile=private,domain | Out-Null
}

$existingAcl = netsh http show urlacl url=http://+:25555/ 2>&1
if ($existingAcl -notmatch "Reserved URL") {
  netsh http add urlacl url=http://+:25555/ user=Everyone | Out-Null
}
'@

    if (Test-IsAdmin) {
      try { Invoke-Expression $setupScript } catch { Write-Warn "Aviso al configurar el firewall (no critico): $_" }
    } else {
      $tempScriptPath = Join-Path $env:TEMP "eurotrans-netsh-setup.ps1"
      Set-Content -Path $tempScriptPath -Value $setupScript -Encoding ASCII
      Write-Warn "Windows va a pedir permiso de Administrador para configurar el firewall - acepta esa ventana."
      try {
        Start-Process -FilePath "powershell" -ArgumentList "-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-WindowStyle","Hidden","-File",$tempScriptPath -Verb RunAs -Wait
      } catch {
        Write-Warn "No se pudo configurar el firewall automaticamente (puedes hacerlo despues si el servidor no responde): $_"
      }
      Remove-Item $tempScriptPath -ErrorAction SilentlyContinue
    }
    Write-Ok "Configuracion del firewall terminada."
  }

  function New-Ets2TelemetryShortcut {
    param([string]$ShortcutPath, [string]$TargetExe, [string]$IconSourceExe)
    $shell = New-Object -ComObject WScript.Shell
    $shortcut = $shell.CreateShortcut($ShortcutPath)
    $shortcut.TargetPath = $TargetExe
    $shortcut.WorkingDirectory = Split-Path $TargetExe
    $shortcut.Description = "Servidor de telemetria de EuroTrans para ETS2"
    if ($IconSourceExe -and (Test-Path $IconSourceExe)) {
      $shortcut.IconLocation = "$IconSourceExe,0"
    }
    $shortcut.Save()
  }

  Write-Step "Verificando si el plugin ya esta instalado y corriendo..."
  $already = Test-Telemetry -TimeoutSec 2
  if ($already.ServerUp) {
    Write-Ok "El servidor de telemetria ya esta corriendo. No hace falta reinstalar."
    if (-not $already.Connected) {
      Write-Warn "Recuerda abrir ETS2 y entrar a una partida para que se conecte."
    }
    return
  }

  $GamePath = Find-Ets2Path
  if (-not $GamePath -or -not (Test-IsEts2Folder $GamePath)) {
    Write-Warn "No se pudo determinar la carpeta de ETS2. Se omite el plugin de telemetria."
    Write-Warn "Puedes instalarlo despues desde ets2.lastgamestudio.fun/setup/manual/"
    return
  }

  $arch = Get-Ets2Arch -Path $GamePath
  Write-Ok "Version del juego detectada: $arch"

  $zipUrl = "https://github.com/Funbit/ets2-telemetry-server/archive/refs/heads/master.zip"
  $zipPath = Join-Path $env:TEMP "ets2-telemetry-server.zip"
  $extractRoot = Join-Path $env:TEMP "ets2-telemetry-server-extract"

  Write-Step "Descargando el plugin de telemetria..."
  try {
    Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath -UseBasicParsing -UserAgent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
  } catch {
    Write-Warn "No se pudo descargar el plugin de telemetria: $_"
    Write-Warn "Puedes instalarlo despues desde ets2.lastgamestudio.fun/setup/manual/"
    return
  }
  Write-Ok "Descargado."

  Write-Step "Extrayendo (solo la carpeta 'server', que es lo unico que usamos)..."
  # El ZIP trae el repositorio COMPLETO de Funbit, incluida una app movil
  # Cordova/iOS (source\Funbit.Ets.Telemetry.Mobile\...) totalmente ajena al
  # servidor de telemetria de Windows que necesitamos, con rutas de test tan
  # anidadas (...\cordova-plugin-splashscreen\tests\ios\CDVSplashScreenTest\
  # CDVSplashScreenTest.xcodeproj\project.xcworkspace\contents.xcworkspacedata)
  # que superan el limite de 260 caracteres de Windows (MAX_PATH) en muchas
  # instalaciones, y Expand-Archive fallaba con "no se pudo extraer el
  # plugin: ... ExtractToFile ...". Solucion: extraer selectivamente solo
  # las entradas bajo "server/" (lo unico que se usa mas abajo:
  # server\Ets2Telemetry.exe y server\Ets2Plugins\$arch\plugins\*.dll),
  # sin tocar nunca esas rutas problematicas.
  try {
    if (Test-Path $extractRoot) {
      # Restos de un intento anterior con rutas demasiado largas: Remove-Item
      # tambien falla ahi por el mismo motivo (MAX_PATH). robocopy /MIR si
      # soporta rutas largas nativamente y permite vaciar la carpeta antes
      # de poder borrarla.
      $emptyDir = Join-Path $env:TEMP "eurotrans-empty-$([guid]::NewGuid().ToString('N'))"
      New-Item -ItemType Directory -Path $emptyDir -Force | Out-Null
      robocopy $emptyDir $extractRoot /MIR /NFL /NDL /NJH /NJS /NC /NS /NP | Out-Null
      Remove-Item $emptyDir -Recurse -Force -ErrorAction SilentlyContinue
      Remove-Item $extractRoot -Recurse -Force -ErrorAction SilentlyContinue
    }
    New-Item -ItemType Directory -Path $extractRoot -Force | Out-Null

    Add-Type -AssemblyName System.IO.Compression.FileSystem
    $zipArchive = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
    try {
      $serverEntries = $zipArchive.Entries | Where-Object {
        $_.FullName -match '(^|/)server/' -and -not $_.FullName.EndsWith('/')
      }
      if (-not $serverEntries) { throw "el ZIP no contiene ninguna entrada bajo 'server/' (¿cambio la estructura del repositorio?)" }
      foreach ($entry in $serverEntries) {
        $destPath = Join-Path $extractRoot ($entry.FullName -replace '/', '\')
        New-Item -ItemType Directory -Path (Split-Path $destPath -Parent) -Force | Out-Null
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $destPath, $true)
      }
    } finally {
      $zipArchive.Dispose()
    }
  } catch {
    Write-Warn "No se pudo extraer el plugin: $_"
    return
  }

  $sourceDir = Get-ChildItem $extractRoot -Directory | Select-Object -First 1
  if (-not $sourceDir) {
    Write-Warn "No se encontro el contenido extraido del plugin. Se omite la instalacion de telemetria."
    return
  }

  try {
    if (Test-Path $InstallDir) { Remove-Item $InstallDir -Recurse -Force }
    New-Item -ItemType Directory -Path (Split-Path $InstallDir) -Force | Out-Null
    Move-Item $sourceDir.FullName $InstallDir
    Write-Ok "Servidor de telemetria instalado en $InstallDir"
  } catch {
    Write-Warn "No se pudo instalar el servidor de telemetria: $_"
    return
  }

  $dllSource = Join-Path $InstallDir "server\Ets2Plugins\$arch\plugins\ets2-telemetry-server.dll"
  if (-not (Test-Path $dllSource)) {
    Write-Warn "No se encontro el plugin ($dllSource). La estructura del paquete pudo haber cambiado."
    Write-Warn "Puedes instalarlo despues desde ets2.lastgamestudio.fun/setup/manual/"
    return
  }

  $pluginsDir = Join-Path $GamePath "bin\$arch\plugins"
  Write-Step "Copiando el plugin a $pluginsDir ..."
  try {
    New-Item -ItemType Directory -Path $pluginsDir -Force | Out-Null
    Copy-Item $dllSource (Join-Path $pluginsDir "ets2-telemetry-server.dll") -Force
    Write-Ok "Plugin copiado correctamente."
  } catch {
    Write-Warn "No se pudo copiar el plugin: $_"
    return
  }

  Install-FirewallAndUrlAcl

  $exePath = Join-Path $InstallDir "server\Ets2Telemetry.exe"
  Write-Step "Iniciando el servidor de telemetria..."
  Write-Warn "Puede aparecer una ventana del servidor preguntando por la carpeta de ATS (American Truck"
  Write-Warn "Simulator). Si no tienes ATS instalado, haz clic en 'Cancel' en esa ventana y listo."
  try {
    Start-Process -FilePath $exePath
  } catch {
    Write-Warn "No se pudo arrancar el servidor automaticamente: $_"
    Write-Warn "Abre manualmente: $exePath"
  }

  try {
    $startupDir = [Environment]::GetFolderPath("Startup")
    $shortcutPath = Join-Path $startupDir "EuroTrans - Servidor de Telemetria.lnk"
    $shell = New-Object -ComObject WScript.Shell
    $shortcut = $shell.CreateShortcut($shortcutPath)
    $shortcut.TargetPath = $exePath
    $shortcut.WorkingDirectory = Split-Path $exePath
    $shortcut.Description = "Servidor de telemetria de EuroTrans para ETS2"
    $shortcut.Save()
    Write-Ok "Inicio automatico configurado: el servidor arrancara con Windows."
  } catch {
    Write-Warn "No se pudo crear el acceso directo de inicio automatico (no es critico): $_"
  }

  Write-Step "Verificando que el servidor de telemetria este respondiendo..."
  $ok = $false
  for ($i = 1; $i -le 10; $i++) {
    Start-Sleep -Seconds 2
    $status = Test-Telemetry -TimeoutSec 3
    if ($status.ServerUp) { $ok = $true; break }
    Write-Host "  esperando... $i/10"
  }

  if ($ok) {
    Write-Ok "El servidor de telemetria esta corriendo correctamente."
  } else {
    Write-Warn "El plugin se copio pero el servidor aun no responde."
    Write-Warn "Abrelo manualmente si hace falta: $exePath"
  }

  # ---- Instalar mod EuroTrans (deshabilita mercado de trabajos original) ----
  Install-EuroTransMod -GamePath $GamePath
}

# ============================================================
# Mod ETS2: deshabilita el mercado de trabajos original
# ============================================================
function Install-EuroTransMod {
  $modUrl  = "https://ets2.lastgamestudio.fun/setup/downloads/eurotrans_override.scs"
  $modName = "eurotrans_override.scs"

  # ETS2 guarda los mods en Documentos del usuario (independiente del path de instalacion)
  $docsEts2 = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "Euro Truck Simulator 2\mod"

  Write-Step "Instalando mod EuroTrans (mercado de trabajos)..."

  try {
    New-Item -ItemType Directory -Path $docsEts2 -Force | Out-Null
  } catch {
    Write-Warn "No se pudo crear la carpeta de mods: $docsEts2"
    return
  }

  $modDest = Join-Path $docsEts2 $modName

  try {
    Invoke-WebRequest -Uri $modUrl -OutFile $modDest -UseBasicParsing
    Write-Ok "Mod instalado en: $modDest"
  } catch {
    Write-Warn "No se pudo descargar el mod: $_"
    Write-Warn "Descargalo manualmente desde ets2.lastgamestudio.fun/setup/downloads/$modName"
    Write-Warn "y copialo a: $docsEts2"
    return
  }

  # Activar el mod en config.cfg si existe
  $configPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "Euro Truck Simulator 2\config.cfg"
  if (Test-Path $configPath) {
    try {
      $cfg = Get-Content $configPath -Raw
      # Asegurar que la lista de mods activos incluye el nuestro
      if ($cfg -notmatch [regex]::Escape($modName)) {
        # Bloque active_mods existente: incrementar contador e insertar entrada
        $blockRe = '(?s)(active_mods\s*:\s*)(\d+)(\s*\{)([^}]*)(\})'
        if ($cfg -match $blockRe) {
          $count    = [int]$Matches[2]
          $newEntry = " active_mods[$count]: `"$modName`"`n"
          $cfg = $cfg -replace $blockRe, (
            $Matches[1] + ($count + 1) + $Matches[3] + $Matches[4] + $newEntry + $Matches[5]
          )
        } else {
          # No existe bloque, crearlo al final
          $cfg += "`nactive_mods : 1 {`n active_mods[0]: `"$modName`"`n}`n"
        }
        Set-Content -Path $configPath -Value $cfg -Encoding UTF8 -NoNewline
        Write-Ok "Mod activado automaticamente en config.cfg."
      } else {
        Write-Ok "El mod ya estaba activo en config.cfg."
      }
    } catch {
      Write-Warn "No se pudo actualizar config.cfg: $_ - activa el mod manualmente desde el gestor de mods de ETS2."
    }
  } else {
    # config.cfg aun no existe (primera ejecucion del juego despues de instalar)
    # Lo creamos con solo el bloque de mods; el juego anadira el resto al arrancar
    try {
      New-Item -ItemType File -Path $configPath -Force | Out-Null
      Set-Content -Path $configPath -Value "active_mods : 1 {`n active_mods[0]: `"$modName`"`n}`n" -Encoding UTF8
      Write-Ok "config.cfg creado con el mod activado."
    } catch {
      Write-Warn "No se pudo crear config.cfg: $_"
    }
  }
}

# ============================================================
# Parte 2: launcher de EuroTrans
# ============================================================
function Install-Launcher {
  $zipUrl    = "https://ets2.lastgamestudio.fun/setup/downloads/eurotrans-launcher.zip"
  $targetDir = "$env:LOCALAPPDATA\EuroTrans\launcher"
  $zipPath   = Join-Path $env:TEMP "eurotrans-launcher.zip"

  # Limpiar instalacion antigua en ProgramData si existe (silencioso si no hay permisos)
  $oldProgramData = "C:\ProgramData\EuroTrans"
  if (Test-Path $oldProgramData) {
    try { Remove-Item $oldProgramData -Recurse -Force -ErrorAction SilentlyContinue } catch { }
  }

  # --- 2a. Descargar ZIP ---
  Write-Step "Descargando el launcher de EuroTrans..."
  try {
    Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath -UseBasicParsing `
      -UserAgent "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
  } catch {
    Write-Err "No se pudo descargar el launcher: $_"
    return
  }
  Write-Ok "Descargado ($([Math]::Round((Get-Item $zipPath).Length/1KB)) KB)."

  # --- 2b. Extraer ZIP ---
  Write-Step "Extrayendo en $targetDir ..."
  # El acceso directo del escritorio lanza EuroTrans-Instalador.exe, que a su vez
  # abre una ventana cmd.exe titulada "EuroTrans" con "cmd /k npm start" y la deja
  # abierta indefinidamente (installer.nsi), con directorio de trabajo dentro de
  # $targetDir. Si solo se mata "node", esa ventana cmd.exe sigue viva y Windows
  # no libera el bloqueo del directorio aunque node.exe ya este muerto — por eso
  # Remove-Item fallaba con "no se puede quitar el elemento" incluso reintentando.
  # Coincidencia EXACTA (sin comodin): el propio instalador titula su consola
  # "EuroTrans - Instalacion completa" (ver "title" al inicio del .bat) y un
  # comodin "EuroTrans*" tambien la mataria a ella misma a mitad de ejecucion.
  taskkill /F /FI "WINDOWTITLE eq EuroTrans" /T 2>$null | Out-Null
  # Matar todos los procesos que puedan tener handles en la carpeta launcher
  foreach ($pname in @("node","scs-fine-bridge","Ets2Telemetry","EuroTrans","EuroTrans-Instalador")) {
    Get-Process -Name $pname -ErrorAction SilentlyContinue |
      Stop-Process -Force -ErrorAction SilentlyContinue
  }
  Start-Sleep -Milliseconds 1500
  # Nunca borrar $targetDir entero: en Windows, si CUALQUIER proceso (aunque ya
  # se haya intentado matar) todavia lo tiene como directorio de trabajo, borrar
  # o renombrar la carpeta falla siempre con "no se puede quitar el elemento",
  # sin reintento que valga. En vez de eso, se extrae a una carpeta temporal
  # (siempre libre, es nueva) y se copia archivo por archivo encima de
  # $targetDir — como mucho falla un archivo puntual que siga bloqueado, nunca
  # la carpeta completa.
  $tempExtract = Join-Path $env:TEMP "eurotrans-launcher-extract"
  try {
    if (Test-Path $tempExtract) { Remove-Item $tempExtract -Recurse -Force -ErrorAction SilentlyContinue }
    Expand-Archive -Path $zipPath -DestinationPath $tempExtract -Force
    New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
    Copy-Item -Path (Join-Path $tempExtract "*") -Destination $targetDir -Recurse -Force
    Remove-Item $tempExtract -Recurse -Force -ErrorAction SilentlyContinue
    Remove-Item $zipPath -ErrorAction SilentlyContinue
    Get-ChildItem -Path $targetDir -Recurse -File |
      ForEach-Object { Unblock-File -Path $_.FullName -ErrorAction SilentlyContinue }
    Write-Ok "Extraido correctamente."
  } catch {
    Write-Err "No se pudo extraer el ZIP: $_"
    Write-Warn "Cierra cualquier ventana de EuroTrans (o la consola 'npm start') y vuelve a ejecutar el instalador."
    Remove-Item $zipPath -ErrorAction SilentlyContinue
    return
  }

  # --- 2c. Comprobar / instalar Node.js ---
  $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" +
              [System.Environment]::GetEnvironmentVariable("PATH","User")
  $nodeCmd = Get-Command node -ErrorAction SilentlyContinue
  $nodeExe = if ($nodeCmd) { $nodeCmd.Source } else { "$env:ProgramFiles\nodejs\node.exe" }

  if (-not (Test-Path $nodeExe)) {
    Write-Step "Node.js no encontrado. Descargando e instalando Node.js 20 LTS..."
    $nodeMsi = Join-Path $env:TEMP "node-installer.msi"
    try {
      Invoke-WebRequest -Uri "https://nodejs.org/dist/v20.18.1/node-v20.18.1-x64.msi" `
        -OutFile $nodeMsi -UseBasicParsing -UserAgent "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
    } catch {
      Write-Err "No se pudo descargar Node.js: $_"
      Write-Err "Instala Node.js manualmente desde https://nodejs.org y vuelve a ejecutar este archivo."
      return
    }
    # El MSI de Node.js instala "para toda la maquina" (Program Files, PATH de
    # sistema), lo que requiere privilegios de administrador. msiexec.exe NO se
    # autoeleva por si solo cuando el .bat se ha lanzado con doble clic normal
    # (sin "Ejecutar como administrador") — a diferencia de netsh en
    # Install-FirewallAndUrlAcl, aqui hay que forzar la elevacion explicitamente
    # con -Verb RunAs o el instalador falla en silencio (ExitCode != 0) y Node
    # nunca queda instalado.
    $msiArgs = "/i `"$nodeMsi`" /quiet /norestart"
    try {
      if (Test-IsAdmin) {
        $proc = Start-Process "msiexec.exe" -ArgumentList $msiArgs -Wait -PassThru
      } else {
        Write-Warn "Windows va a pedir permiso de Administrador para instalar Node.js - acepta esa ventana."
        $proc = Start-Process "msiexec.exe" -ArgumentList $msiArgs -Verb RunAs -Wait -PassThru
      }
    } catch {
      Write-Err "No se pudo lanzar el instalador de Node.js (¿se rechazo el permiso de Administrador?): $_"
      Write-Err "Instala Node.js manualmente desde https://nodejs.org y vuelve a ejecutar este archivo."
      Remove-Item $nodeMsi -ErrorAction SilentlyContinue
      return
    }
    Remove-Item $nodeMsi -ErrorAction SilentlyContinue
    if ($proc.ExitCode -ne 0) {
      Write-Err "El instalador de Node.js fallo (codigo: $($proc.ExitCode))."
      Write-Err "Instala Node.js manualmente desde https://nodejs.org y vuelve a ejecutar este archivo."
      return
    }
    # Refrescar PATH tras instalar
    $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" +
                [System.Environment]::GetEnvironmentVariable("PATH","User")
    $nodeCmd = Get-Command node -ErrorAction SilentlyContinue
    $nodeExe = if ($nodeCmd) { $nodeCmd.Source } else { "$env:ProgramFiles\nodejs\node.exe" }
    Write-Ok "Node.js instalado: $nodeExe"
  } else {
    Write-Ok "Node.js encontrado: $nodeExe"
  }

  if (-not (Test-Path $nodeExe)) {
    Write-Err "node.exe no encontrado en $nodeExe - instala Node.js desde https://nodejs.org"
    return
  }

  # --- 2d. npm install (solo si no vienen los modulos ya en el ZIP) ---
  $nodeModules = Join-Path $targetDir "node_modules\dotenv"
  if (-not (Test-Path $nodeModules)) {
    Write-Step "Instalando dependencias npm..."
    $npmExe = Join-Path (Split-Path $nodeExe) "npm.cmd"
    if (-not (Test-Path $npmExe)) { $npmExe = "npm" }
    $proc = Start-Process "cmd.exe" -ArgumentList "/c cd /d `"$targetDir`" && `"$npmExe`" install --prefer-offline" -Wait -PassThru
    if ($proc.ExitCode -ne 0) {
      Write-Warn "npm install devolvio error $($proc.ExitCode) pero continuamos (los modulos podrian estar parcialmente instalados)."
    } else {
      Write-Ok "Dependencias instaladas."
    }
  } else {
    Write-Ok "Dependencias ya presentes (node_modules incluido en el paquete)."
  }

  # --- 2e. Arrancar launcher ---
  Write-Step "Arrancando el launcher en segundo plano..."
  $logFile = Join-Path $targetDir "launcher.log"
  $errFile = Join-Path $targetDir "launcher-err.log"
  Remove-Item $logFile -Force -ErrorAction SilentlyContinue
  Remove-Item $errFile -Force -ErrorAction SilentlyContinue
  Start-Process -FilePath $nodeExe -ArgumentList "src\index.js" `
    -WorkingDirectory $targetDir -WindowStyle Hidden `
    -RedirectStandardOutput $logFile -RedirectStandardError $errFile
  Write-Ok "Launcher arrancado. El navegador se abrira en unos segundos para conectar tu wallet."

  # --- 2f. Registrar protocolo eurotrans:// en el registro de Windows (HKCU, sin admin) ---
  try {
    $vbsPath    = Join-Path $targetDir "start-launcher.vbs"
    $wscriptExe = Join-Path $env:SystemRoot "System32\wscript.exe"
    # Escribir VBS linea a linea en ASCII puro (sin BOM) para que wscript.exe lo compile sin errores
    $lines = @(
      'Dim oShell, oFso, launcherDir, nodeExe, src',
      'Set oShell = CreateObject("WScript.Shell")',
      'Set oFso   = CreateObject("Scripting.FileSystemObject")',
      'launcherDir = oFso.GetParentFolderName(WScript.ScriptFullName)',
      'src = launcherDir & "\src\index.js"',
      "nodeExe = `"$nodeExe`"",
      'If Not oFso.FileExists(nodeExe) Then nodeExe = "node"',
      # oShell.Run NO fija el directorio de trabajo del proceso hijo al del
      # propio script VBS (usa el que herede wscript.exe, tipicamente
      # System32 cuando se lanza via el protocolo eurotrans://). Sin esto,
      # dotenv (config.js: require("dotenv").config()) no encuentra el .env
      # del launcher y EUROTRANS_API_URL cae en silencio al valor por
      # defecto http://127.0.0.1:4000, rompiendo login/telemetria/saldo en
      # todo relanzamiento que no pase por el instalador NSIS (que si fija
      # /D "$EXEDIR" al arrancar "npm start").
      'oShell.CurrentDirectory = launcherDir',
      'oShell.Run Chr(34) & nodeExe & Chr(34) & " " & Chr(34) & src & Chr(34), 1, False',
      'Dim wmi, procs',
      'Set wmi   = GetObject("winmgmts:\\.\root\cimv2")',
      'Set procs = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name=''eurotrucks2.exe''")',
      'If procs.Count = 0 Then oShell.Run "steam://rungameid/227300", 1, False'
    )
    [System.IO.File]::WriteAllLines($vbsPath, $lines, [System.Text.Encoding]::ASCII)
    $regBase = "HKCU:\SOFTWARE\Classes\eurotrans"
    $command = "`"$wscriptExe`" `"$vbsPath`" `"%1`""
    New-Item -Path $regBase -Force | Out-Null
    Set-ItemProperty -Path $regBase -Name "(Default)" -Value "URL:EuroTrans Protocol" -Force
    New-ItemProperty -Path $regBase -Name "URL Protocol" -Value "" -PropertyType String -Force | Out-Null
    New-Item -Path "$regBase\shell" -Force | Out-Null
    New-Item -Path "$regBase\shell\open" -Force | Out-Null
    New-Item -Path "$regBase\shell\open\command" -Force | Out-Null
    Set-ItemProperty -Path "$regBase\shell\open\command" -Name "(Default)" -Value $command -Force
    Write-Ok "Protocolo eurotrans:// registrado. El boton 'Iniciar EuroTrans' del dashboard ya puede abrir el launcher."
  } catch {
    Write-Warn "No se pudo registrar el protocolo eurotrans://: $_"
  }

  # --- 2g. Acceso directo en el escritorio ---
  try {
    $shell        = New-Object -ComObject WScript.Shell
    $shortcutPath = Join-Path ([System.Environment]::GetFolderPath("Desktop")) "EuroTrans.lnk"
    $shortcut     = $shell.CreateShortcut($shortcutPath)
    $shortcut.TargetPath       = Join-Path $targetDir "EuroTrans-Instalador.exe"
    $shortcut.WorkingDirectory = $targetDir
    $shortcut.Description      = "Lanzar EuroTrans para ETS2"
    $shortcut.Save()
    Write-Ok "Acceso directo 'EuroTrans' creado en el escritorio."
  } catch {
    Write-Warn "No se pudo crear el acceso directo: $_"
  }
}

# ============================================================
# Parte 3: esperar a que la wallet este conectada
# ============================================================
function Wait-WalletConnection {
  $flagFile = "$env:LOCALAPPDATA\EuroTrans\connected.json"
  $maxWaitSec = 300
  $waited = 0

  Write-Step "Esperando a que conectes tu wallet en el navegador..."
  Write-Host "  El navegador se ha abierto con la pagina de conexion." -ForegroundColor Yellow
  Write-Host "  Conecta con MetaMask o Immutable Passport." -ForegroundColor Yellow
  Write-Host "  Esta ventana continuara sola cuando detecte la conexion." -ForegroundColor Yellow

  while (-not (Test-Path $flagFile) -and $waited -lt $maxWaitSec) {
    Start-Sleep -Seconds 2
    $waited += 2
    Write-Host "`r  esperando... ${waited}s / ${maxWaitSec}s " -NoNewline
  }
  Write-Host ""

  if (Test-Path $flagFile) {
    try {
      $data = Get-Content $flagFile -Raw | ConvertFrom-Json
      Write-Ok "Wallet conectada: $($data.wallet)"
    } catch {
      Write-Ok "Wallet conectada correctamente."
    }
    return $true
  } else {
    Write-Warn "No se detecto la conexion de wallet tras ${maxWaitSec}s."
    Write-Warn "Si ya la conectaste, el juego se abrira de todas formas."
    Write-Warn "Si no, conecta la wallet antes de empezar a jugar."
    return $false
  }
}

# ============================================================
# Parte 4: abrir el juego
# ============================================================
function Open-Game {
  param([string]$SteamAppId = "227300")
  Write-Step "Abriendo Euro Truck Simulator 2..."
  try {
    Start-Process "steam://rungameid/$SteamAppId"
    Write-Host "  Esperando que aparezca la ventana del juego..." -ForegroundColor Yellow
    $wshell = New-Object -ComObject WScript.Shell
    $brought = $false
    for ($i = 0; $i -lt 20; $i++) {
      Start-Sleep -Seconds 3
      $proc = Get-Process -Name "eurotrucks2" -ErrorAction SilentlyContinue |
              Where-Object { $_.MainWindowHandle -ne [IntPtr]::Zero } |
              Select-Object -First 1
      if ($proc) {
        try { $wshell.AppActivate($proc.Id) } catch { }
        Write-Ok "ETS2 abierto y en primer plano."
        $brought = $true
        break
      }
    }
    if (-not $brought) {
      Write-Ok "Juego lanzado. Si no aparece en primer plano, hazle clic en la barra de tareas."
    }
  } catch {
    Write-Warn "No se pudo abrir el juego automaticamente: $_"
    Write-Warn "Abrelo manualmente desde Steam."
  }
}

# ============================================================
# Ejecucion principal
# ============================================================

# Borrar bandera de sesion anterior para que Wait-WalletConnection
# no la confunda con una conexion nueva.
$flagFile = "$env:LOCALAPPDATA\EuroTrans\connected.json"
Remove-Item $flagFile -ErrorAction SilentlyContinue

Write-Host ""
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "  PASO 1/4: Plugin de telemetria de ETS2" -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

try {
  Install-TelemetryPlugin
} catch {
  Write-Warn "La instalacion de telemetria encontro un problema: $_"
  Write-Warn "Continuando con la instalacion del launcher de todas formas..."
}

Write-Host ""
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "  PASO 2/4: Launcher de EuroTrans + conexion de wallet" -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

try {
  Install-Launcher
} catch {
  Write-Err "La instalacion del launcher encontro un problema: $_"
}

Wait-WalletConnection | Out-Null

Write-Host ""
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "  PASO 3/4: Mod EuroTrans (mercado de trabajos)" -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

try {
  Install-EuroTransMod
} catch {
  Write-Warn "La instalacion del mod encontro un problema: $_"
  Write-Warn "Puedes instalar el mod manualmente mas tarde."
}

Write-Host ""
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "  PASO 4/4: Abriendo Euro Truck Simulator 2" -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

Open-Game

Write-Step "Todo listo. El launcher esta corriendo y la wallet conectada."
Write-Host "  Panel de control: https://ets2.lastgamestudio.fun/dashboard/" -ForegroundColor Green
