# Sets up the Humand frontend sandbox environment on Windows.
# Usage: powershell -ExecutionPolicy Bypass -File setup-env.ps1
# Output: writes ~/.humand/sandbox-installed.json and prints a JSON summary to stdout.
#
# nvm path:  nvm-windows → node
# mise path: mise (user-space, no admin) → node  [fallback when nvm not found]

$ErrorActionPreference = "Stop"
$NODE_VERSION = "24.11.1"
$HumandDir = Join-Path $HOME ".humand"
$RegistryFile = Join-Path $HumandDir "sandbox-installed.json"
$MiseBin = Join-Path $HOME ".local\bin\mise.exe"
$UsingMise = $false

# ── helpers ────────────────────────────────────────────────────────────────────

function Log($msg)  { Write-Host "▶ $msg" -ForegroundColor Cyan }
function Ok($msg)   { Write-Host "✓ $msg" -ForegroundColor Green }
function Fail($msg) { Write-Host "✗ $msg" -ForegroundColor Red }
function Warn($msg) { Write-Host "⚠ $msg" -ForegroundColor Yellow }

$RegistryTools = @{}

function Registry-Set($tool, $preexisting) {
  $RegistryTools[$tool] = @{ preexisting = $preexisting }
  $data = @{
    installedAt = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
    nodeVersion = $NODE_VERSION
    tools       = $RegistryTools
  }
  $data | ConvertTo-Json -Depth 5 | Set-Content -Path $RegistryFile -Encoding UTF8
}

function Command-Exists($name) {
  return [bool](Get-Command $name -ErrorAction SilentlyContinue)
}

function Install-Mise {
  if ((Test-Path $MiseBin) -or (Command-Exists mise)) {
    Ok "mise already installed"
    return
  }
  Log "Installing mise (user-space, no admin required)..."
  irm https://mise.run/install.ps1 | iex
  $env:PATH = (Join-Path $HOME ".local\bin") + ";" + $env:PATH
  Ok "mise installed"
}

function Get-MiseExe {
  if (Test-Path $MiseBin) { return $MiseBin }
  $found = Get-Command mise -ErrorAction SilentlyContinue
  if ($found) { return $found.Source }
  return $null
}

# ── pre-flight ─────────────────────────────────────────────────────────────────

New-Item -ItemType Directory -Force -Path $HumandDir | Out-Null

if (Test-Path $RegistryFile) {
  $existing = Get-Content $RegistryFile | ConvertFrom-Json
  if ($existing.tools) {
    $existing.tools.PSObject.Properties | ForEach-Object {
      $RegistryTools[$_.Name] = @{ preexisting = $_.Value.preexisting }
    }
  }
}

# ── nvm-windows OR mise ────────────────────────────────────────────────────────

Log "Checking nvm..."
if (Command-Exists nvm) {
  Ok "nvm already installed"
  Registry-Set "nvm" $true

  # ── Node (via nvm) ────────────────────────────────────────────────────────────
  Log "Checking Node $NODE_VERSION..."
  $currentNode = (node --version 2>$null) -replace "`n",""
  if ($currentNode -eq "v$NODE_VERSION") {
    Ok "Node $NODE_VERSION already active"
    Registry-Set "node" $true
  } else {
    Log "Installing Node $NODE_VERSION via nvm..."
    nvm install $NODE_VERSION
    nvm use $NODE_VERSION
    Ok "Node $NODE_VERSION installed and set as active"
    Registry-Set "node" $false
  }

} else {
  Warn "nvm not found — using mise to install Node (no admin required)."
  $UsingMise = $true
  Registry-Set "nvm_skipped" $true

  Install-Mise
  $miseExe = Get-MiseExe
  if (-not $miseExe) {
    Fail "mise could not be installed. Install Node manually from https://nodejs.org and re-run this script."
    exit 1
  }

  # Activate mise shims for this session
  $shimsPath = Join-Path $HOME ".local\share\mise\shims"
  $env:PATH = "$shimsPath;$env:PATH"

  Log "Checking Node $NODE_VERSION..."
  $currentNode = (node --version 2>$null) -replace "`n",""
  if ($currentNode -eq "v$NODE_VERSION") {
    Ok "Node $NODE_VERSION already active"
    Registry-Set "node" $true
  } else {
    Log "Installing Node $NODE_VERSION via mise..."
    & $miseExe use -g "node@$NODE_VERSION"
    Ok "Node $NODE_VERSION installed via mise"
    Registry-Set "node" $false
  }
}

# ── bun ────────────────────────────────────────────────────────────────────────

Log "Checking bun..."
if (Command-Exists bun) {
  Ok "bun already installed"
  Registry-Set "bun" $true
} else {
  Log "Installing bun..."
  powershell -c "irm bun.sh/install.ps1 | iex"
  $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "User") + ";" + $env:PATH
  if (-not (Command-Exists bun)) {
    Fail "bun installed but not found in PATH. Close and re-open the terminal, then re-run this script."
    exit 1
  }
  Ok "bun installed"
  Registry-Set "bun" $false
}

# ── git ────────────────────────────────────────────────────────────────────────

Log "Checking git..."
if (Command-Exists git) {
  Ok "git already installed"
  Registry-Set "git" $true
} else {
  Fail "git not found."
  Write-Host @"

  git requires a graphical installer and cannot be installed automatically.
  Please download and run the installer from:

    https://git-scm.com/download/win

  After installing, close this terminal, open a new one, and re-run this script.
"@ -ForegroundColor Yellow
  exit 1
}

# ── GitHub CLI ─────────────────────────────────────────────────────────────────

Log "Checking gh (GitHub CLI)..."
if (Command-Exists gh) {
  Ok "gh already installed"
  Registry-Set "gh" $true
} else {
  Fail "gh not found."
  Write-Host @"

  GitHub CLI requires a graphical installer and cannot be installed automatically.
  Please download and run the installer from:

    https://cli.github.com

  After installing, close this terminal, open a new one, and re-run this script.
"@ -ForegroundColor Yellow
  exit 1
}

# ── done ───────────────────────────────────────────────────────────────────────

if ($UsingMise) {
  Warn "nvm-windows no estaba instalado. Se usó mise para instalar Node."
}

Ok "All done. Registry saved to $RegistryFile"
Get-Content $RegistryFile
