#Requires -RunAsAdministrator
<#
.SYNOPSIS
    Installation de private-server en service Windows (NSSM).

.DESCRIPTION
    Déploie le package (pnpm deploy — sauf archive pré-construite, qui est
    copiée telle quelle), l'installe dans C:\Program Files\private-server,
    crée le service Windows via NSSM (téléchargé automatiquement), puis lance
    l'assistant de premier lancement. Caddy est documenté mais non installé
    automatiquement (téléchargement manuel depuis caddyserver.com/download).

.PARAMETER Domain
    Domaine public (ex. photos.exemple.fr). Vide = accès direct par IP.

.PARAMETER AdminEmail
    Email du compte administrateur (obligatoire).

.PARAMETER AdminPassword
    Mot de passe admin. S'il est omis, un mot de passe aléatoire est généré
    et affiché UNE seule fois à la fin.

.EXAMPLE
    .\install.ps1 -Domain photos.exemple.fr -AdminEmail moi@exemple.fr
#>
param(
  [string]$Domain = "",
  [string]$AdminEmail = "",
  [string]$AdminPassword = "",
  [string]$Family = "Ma famille",
  [string]$AppDir = "$env:ProgramFiles\private-server",
  [string]$DataDir = "$env:ProgramData\private-server"
)

$ErrorActionPreference = "Stop"

if (-not $AdminEmail) {
  Write-Host "Usage : install.ps1 -Domain <domaine> -AdminEmail <email> [options]" -ForegroundColor Yellow
  exit 1
}

# ----------------------------------------------------------------------
# Prérequis
# ----------------------------------------------------------------------

$nodeMajor = (& node -p "process.versions.node.split('.')[0]") 2>$null
if (-not $nodeMajor -or [int]$nodeMajor -lt 24) {
  Write-Host "Node.js 24+ requis (nodejs.org). Version détectée : $nodeMajor" -ForegroundColor Red
  exit 1
}

$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$pkgSrc = Resolve-Path (Join-Path $scriptDir "..\..")
if (-not (Test-Path (Join-Path $pkgSrc "dist\index.js"))) {
  Write-Host "Build absent : exécutez « pnpm build » dans $pkgSrc d'abord." -ForegroundColor Red
  exit 1
}

# Archive pré-construite : node_modules RÉELS (répertoires, pas de symlinks
# workspace pnpm) à côté de dist/ → copie directe, pas de pnpm deploy.
$sharedPath = Join-Path $pkgSrc "node_modules\@familyalbum\shared"
$archiveMode = (Test-Path $sharedPath) -and ((Get-Item $sharedPath).LinkType -eq $null)

if (-not $archiveMode) {
  $pnpm = (Get-Command pnpm -ErrorAction SilentlyContinue)
  if (-not $pnpm) {
    Write-Host "pnpm requis (npm i -g pnpm) — sauf à utiliser l'archive pré-construite." -ForegroundColor Red
    exit 1
  }
}

# ----------------------------------------------------------------------
# Déploiement du package (dépendances réelles, pas de symlinks pnpm)
# ----------------------------------------------------------------------

$stage = Join-Path $env:TEMP ("private-server-deploy-" + [Guid]::NewGuid().ToString("N"))
try {
  if ($archiveMode) {
    Write-Host "→ Archive pré-construite détectée — copie directe (pas de pnpm deploy)"
    $src = $pkgSrc
  } else {
    Write-Host "→ Déploiement du package..."
    Push-Location $pkgSrc
    try { & pnpm deploy --prod $stage } finally { Pop-Location }
    $src = $stage
  }

  Write-Host "→ Copie vers $AppDir"
  New-Item -ItemType Directory -Force -Path $AppDir | Out-Null
  Copy-Item -Recurse -Force (Join-Path $src "*") $AppDir
  Remove-Item -Recurse -Force (Join-Path $AppDir "data"), (Join-Path $AppDir "data-test") -ErrorAction SilentlyContinue

  New-Item -ItemType Directory -Force -Path $DataDir | Out-Null
  New-Item -ItemType Directory -Force -Path (Join-Path $DataDir "logs") | Out-Null
} finally {
  if ($stage -and -not $archiveMode) {
    Remove-Item -Recurse -Force $stage -ErrorAction SilentlyContinue
  }
}

# ----------------------------------------------------------------------
# Service Windows via NSSM
# ----------------------------------------------------------------------

$nssmDir = Join-Path $env:ProgramData "private-server-tools"
$nssm = Join-Path $nssmDir "nssm.exe"
if (-not (Test-Path $nssm)) {
  Write-Host "→ Téléchargement de NSSM (gestionnaire de services)"
  New-Item -ItemType Directory -Force -Path $nssmDir | Out-Null
  $zip = Join-Path $nssmDir "nssm.zip"
  Invoke-WebRequest "https://nssm.cc/release/nssm-2.24.zip" -OutFile $zip
  Expand-Archive -Force $zip $nssmDir
  Copy-Item (Join-Path $nssmDir "nssm-2.24\win64\nssm.exe") $nssm -Force
  Remove-Item $zip
}

$nodeExe = (Get-Command node).Source
$entry = Join-Path $AppDir "dist\index.js"
$stdout = Join-Path $DataDir "logs\stdout.log"
$stderr = Join-Path $DataDir "logs\stderr.log"

if (Get-Service private-server -ErrorAction SilentlyContinue) {
  Write-Host "→ Service existant, mise à jour de la configuration"
} else {
  Write-Host "→ Création du service private-server"
  & $nssm install private-server $nodeExe $entry
}
& $nssm set private-server AppDirectory $AppDir
& $nssm set private-server AppEnvironmentExtra "DATA_DIR=$DataDir" "NODE_ENV=production" "PORT=4100"
& $nssm set private-server AppStdout $stdout
& $nssm set private-server AppStderr $stderr
& $nssm set private-server AppRotateFiles 1
& $nssm set private-server Start SERVICE_AUTO_START
& $nssm restart private-server

# ----------------------------------------------------------------------
# Assistant de premier lancement
# ----------------------------------------------------------------------

if (-not $AdminPassword) {
  $chars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
  $AdminPassword = -join (1..16 | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
  $Generated = $true
}

$env:DATA_DIR = $DataDir
Write-Host "→ Assistant de premier lancement"
& node (Join-Path $AppDir "dist\cli.js") setup `
  @("--domain=$Domain", "--email=$AdminEmail", "--password=$AdminPassword",
    "--family=$Family", "--yes", "--no-caddy") | ForEach-Object { $_ }
if ($LASTEXITCODE -ne 0) { throw "L'assistant de premier lancement a échoué." }
Remove-Item Env:DATA_DIR

# ----------------------------------------------------------------------
# Récapitulatif
# ----------------------------------------------------------------------

$url = if ($Domain) { "https://$Domain" } else { "http://<IP_de_cette_machine>:4100" }
Write-Host ""
Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "  private-server installé" -ForegroundColor Cyan
Write-Host ""
Write-Host "  URL            $url"
Write-Host "  Identifiant    $AdminEmail"
Write-Host "  Mot de passe   $AdminPassword  $(if ($Generated) { '(généré — notez-le !)' } else { '' })"
Write-Host "  Famille        $Family"
Write-Host ""
Write-Host "  Service        sc query private-server"
Write-Host "  Logs           $stdout"
Write-Host "  Données        $DataDir"
if ($Domain) {
  Write-Host ""
  Write-Host "  HTTPS : installez Caddy (caddyserver.com/download) puis :"
  Write-Host "    caddy start --config `"$DataDir\Caddyfile`""
}
Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan
