$ErrorActionPreference='Stop'
$packageRoot=Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
$oneDriveCandidates=@($env:OneDriveCommercial,$env:OneDrive,$env:OneDriveConsumer) | Where-Object { $_ -and (Test-Path $_) }
$defaultRoot=if($oneDriveCandidates.Count -gt 0){ Join-Path $oneDriveCandidates[0] 'PhUCKIT-Test' } else { Join-Path $env:LOCALAPPDATA 'PhUCKIT-Test' }
Write-Host "Suggested installation folder: $defaultRoot"
$answer=Read-Host 'Press Enter to accept or enter another full folder path'
$target=if([string]::IsNullOrWhiteSpace($answer)){$defaultRoot}else{$answer.Trim('"')}

$timestamp=Get-Date -Format 'yyyyMMdd-HHmmss'
$backupRoot=Join-Path $target "Backups\pre-update-$timestamp"
$preserveRelative=@(
  'App\data',
  'ClinicalReasoningDatabase\active',
  'ClinicalReasoningDatabase\exports',
  'ClinicalReasoningDatabase\research_cache',
  'ClinicalReasoningDatabase\research_exports',
  'ClinicalReasoningDatabase\owner-backups',
  'Logs'
)

if(Test-Path $target){
  New-Item -ItemType Directory -Force -Path $backupRoot | Out-Null
  foreach($relative in $preserveRelative){
    $source=Join-Path $target $relative
    if(Test-Path $source){
      $destination=Join-Path $backupRoot $relative
      New-Item -ItemType Directory -Force -Path (Split-Path -Parent $destination) | Out-Null
      Copy-Item $source $destination -Recurse -Force
      Write-Host "Preserved: $relative" -ForegroundColor Cyan
    }
  }
}
New-Item -ItemType Directory -Force -Path $target | Out-Null

# Application code is updated, but owner/runtime data is not blindly overwritten.
$packageRootResolved=[System.IO.Path]::GetFullPath($packageRoot).TrimEnd('\')
$targetResolved=[System.IO.Path]::GetFullPath($target).TrimEnd('\')
$inPlaceUpdate=$packageRootResolved.Equals($targetResolved,[System.StringComparison]::OrdinalIgnoreCase)

function Copy-SafeItem {
  param(
    [Parameter(Mandatory=$true)][string]$Source,
    [Parameter(Mandatory=$true)][string]$Destination,
    [switch]$Recurse
  )
  $sourceResolved=[System.IO.Path]::GetFullPath($Source).TrimEnd('\')
  $destinationResolved=[System.IO.Path]::GetFullPath($Destination).TrimEnd('\')

  if($sourceResolved.Equals($destinationResolved,[System.StringComparison]::OrdinalIgnoreCase)){
    Write-Host "Skipping self-copy: $sourceResolved" -ForegroundColor Yellow
    return
  }

  if($Recurse){
    Copy-Item -LiteralPath $Source -Destination $Destination -Recurse -Force
  } else {
    Copy-Item -LiteralPath $Source -Destination $Destination -Force
  }
}

if($inPlaceUpdate){
  Write-Host "In-place update detected. Existing application files will be retained and repaired without self-copying." -ForegroundColor Yellow
} else {
  $excludeTop=@('Runtime','Logs','Backups')
  Get-ChildItem $packageRoot -Force | Where-Object { $excludeTop -notcontains $_.Name -and $_.FullName -ne $target } | ForEach-Object {
    if($_.Name -eq 'App'){
      $appTarget=Join-Path $target 'App'
      New-Item -ItemType Directory -Force -Path $appTarget | Out-Null
      Get-ChildItem $_.FullName -Force | Where-Object { $_.Name -ne 'data' } | ForEach-Object {
        $dest=Join-Path $appTarget $_.Name
        Copy-SafeItem -Source $_.FullName -Destination $dest -Recurse
      }
      $packageData=Join-Path $_.FullName 'data'
      $targetData=Join-Path $appTarget 'data'
      if(!(Test-Path $targetData) -and (Test-Path $packageData)){
        Copy-SafeItem -Source $packageData -Destination $targetData -Recurse
      } elseif(Test-Path $packageData) {
        Get-ChildItem $packageData -Recurse -File | ForEach-Object {
          $relative=$_.FullName.Substring($packageData.Length).TrimStart('\')
          $dest=Join-Path $targetData $relative
          if(!(Test-Path $dest)){
            New-Item -ItemType Directory -Force -Path (Split-Path -Parent $dest) | Out-Null
            Copy-SafeItem -Source $_.FullName -Destination $dest
          }
        }
      }
    } elseif($_.Name -eq 'ClinicalReasoningDatabase'){
      $crdTarget=Join-Path $target 'ClinicalReasoningDatabase'
      New-Item -ItemType Directory -Force -Path $crdTarget | Out-Null
      Get-ChildItem $_.FullName -Force | Where-Object {
        @('active','exports','research_cache','research_exports','owner-backups') -notcontains $_.Name
      } | ForEach-Object {
        $dest=Join-Path $crdTarget $_.Name
        Copy-SafeItem -Source $_.FullName -Destination $dest -Recurse
      }
      foreach($preservedFolder in @('active','exports','research_cache','research_exports','owner-backups')){
        $packageFolder=Join-Path $_.FullName $preservedFolder
        $targetFolder=Join-Path $crdTarget $preservedFolder
        if(!(Test-Path $targetFolder) -and (Test-Path $packageFolder)){
          Copy-SafeItem -Source $packageFolder -Destination $targetFolder -Recurse
        }
      }
    } else {
      $dest=Join-Path $target $_.Name
      Copy-SafeItem -Source $_.FullName -Destination $dest -Recurse
    }
  }
}

New-Item -ItemType Directory -Force -Path (Join-Path $target 'Runtime'),(Join-Path $target 'Logs'),(Join-Path $target 'Backups') | Out-Null

& (Join-Path $target 'Installer\SETUP_RUNTIMES.ps1')

$wsh=New-Object -ComObject WScript.Shell
$desktop=[Environment]::GetFolderPath('Desktop')
$shortcut=$wsh.CreateShortcut((Join-Path $desktop 'PhUCKIT.lnk'))
$shortcut.TargetPath=Join-Path $target 'PHUCKIT_CONTROL_CENTER.cmd'
$shortcut.WorkingDirectory=$target
$shortcut.IconLocation='%SystemRoot%\System32\shell32.dll,14'
$shortcut.Description='PhUCKIT clinical utility and reasoning workbench'
$shortcut.Save()

$startup=Read-Host 'Start PhUCKIT automatically when you sign in? (Y/N)'
$startupPath=Join-Path ([Environment]::GetFolderPath('Startup')) 'PhUCKIT.lnk'
if($startup -match '^[Yy]'){
  Copy-Item (Join-Path $desktop 'PhUCKIT.lnk') $startupPath -Force
}else{ if(Test-Path $startupPath){Remove-Item $startupPath -Force} }

Set-Content -Path (Join-Path $env:LOCALAPPDATA 'PhUCKIT-Test.install-path.txt') -Value $target -Encoding UTF8
Write-Host ""
Write-Host "Installed/repaired at $target" -ForegroundColor Green
if(Test-Path $backupRoot){
  Write-Host "Pre-update preservation backup: $backupRoot" -ForegroundColor Green
}
Write-Host "Owner data and active runtime truth files were preserved." -ForegroundColor Green
Start-Process (Join-Path $target 'PHUCKIT_CONTROL_CENTER.cmd')
