<#
    Internoodle PDF Tool - installer.

    Per-user install: no administrator rights, no UAC prompt. Everything lands in
    %LOCALAPPDATA% and HKEY_CURRENT_USER, so it works for anyone who downloads it.

    What it does:
      1. copies the app to %LOCALAPPDATA%\Internoodle\PdfTool
      2. registers it with Windows as an app that opens .pdf
      3. Start Menu + Desktop shortcuts
      4. adds an entry to Settings > Apps (Add/Remove Programs)
      5. offers to open the screen where you make it your default PDF app

    Windows will not let any installer set the default PDF app for you - the
    choice is hash-protected on purpose, so nothing can hijack your file types.
    Step 5 opens the right screen; the final click is yours.
#>
param(
    # NOT under %LOCALAPPDATA%: on some machines Explorer refuses to read icon
    # resources out of AppData, which leaves every shortcut and the PDF file
    # icon blank. A folder in the user's profile needs no admin rights either.
    [string]$InstallRoot = (Join-Path $env:USERPROFILE 'Internoodle\PdfTool'),
    [string]$ProgId      = 'Internoodle.PdfTool.pdf',
    [string]$UninstallId = 'InternoodlePdfTool',
    [switch]$NoPrompt                                   # for unattended/test runs
)

$ErrorActionPreference = 'Stop'
$AppName = 'Internoodle PDF Tool'
$Version = '1.2.0'          # app shows this as "1.2 (Int-20260808-1)"
$here    = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }
$payload = Join-Path $here 'FilerApp.zip'
$exeName = 'Internoodle PDF Tool.exe'

function Say($text, $colour = 'Gray') { Write-Host $text -ForegroundColor $colour }

Say ""
Say "  $AppName  $Version" Cyan
Say "  ---------------------------------------------" DarkGray
Say ""

if (-not (Test-Path $payload)) {
    Say "  FilerApp.zip is missing - extract ALL the files from the download, then run this again." Red
    if (-not $NoPrompt) { Read-Host "  Press Enter to close" }
    exit 1
}

# 1. close a running copy -----------------------------------------------------
$running = Get-Process -Name ([IO.Path]::GetFileNameWithoutExtension($exeName)) -ErrorAction SilentlyContinue
if ($running) {
    Say "  Closing the copy that is already running..."
    $running | Stop-Process -Force -ErrorAction SilentlyContinue
    Start-Sleep -Milliseconds 700
}

# 2. copy the app -------------------------------------------------------------
Say "  1/5  Copying files to $InstallRoot"
if (Test-Path $InstallRoot) { Remove-Item $InstallRoot -Recurse -Force -ErrorAction SilentlyContinue }
New-Item -ItemType Directory -Path $InstallRoot -Force | Out-Null
Expand-Archive -Path $payload -DestinationPath $InstallRoot -Force

$exe = Join-Path $InstallRoot $exeName
if (-not (Test-Path $exe)) { throw "The copy did not produce $exe" }

$uninstallScript = Join-Path $here 'uninstall.ps1'
if (Test-Path $uninstallScript) { Copy-Item $uninstallScript $InstallRoot -Force }

# 3. register the file type ---------------------------------------------------
Say "  2/5  Registering with Windows"
$classes = 'HKCU:\Software\Classes'
$capKey  = 'HKCU:\Software\Internoodle\PdfTool\Capabilities'

function Set-Key($path, $values) {
    if (-not (Test-Path $path)) { New-Item -Path $path -Force | Out-Null }
    foreach ($name in $values.Keys) {
        New-ItemProperty -Path $path -Name $name -Value $values[$name] -PropertyType String -Force | Out-Null
    }
}

$iconSource = Join-Path $InstallRoot '_internal\pdfviewer.ico'
if (Test-Path $iconSource) { Copy-Item $iconSource (Join-Path $InstallRoot 'app.ico') -Force }
$pdfIcon = if (Test-Path (Join-Path $InstallRoot 'app.ico')) { "$InstallRoot\app.ico,0" } else { "$exe,0" }

Set-Key "$classes\$ProgId"                    @{ '(default)' = 'PDF Document'; 'FriendlyTypeName' = 'PDF Document' }
Set-Key "$classes\$ProgId\DefaultIcon"        @{ '(default)' = $pdfIcon }
Set-Key "$classes\$ProgId\shell\open\command" @{ '(default)' = "`"$exe`" `"%1`"" }
Set-Key "$classes\.pdf\OpenWithProgids"       @{ $ProgId = '' }
Set-Key "$classes\Applications\$exeName"                    @{ 'FriendlyAppName' = $AppName }
Set-Key "$classes\Applications\$exeName\shell\open\command" @{ '(default)' = "`"$exe`" `"%1`"" }
Set-Key "$classes\Applications\$exeName\SupportedTypes"     @{ '.pdf' = '' }
Set-Key $capKey @{
    'ApplicationName'        = $AppName
    'ApplicationDescription' = 'Opens a PDF, then files, prints or saves it.'
    'ApplicationIcon'        = "$exe,0"
}
Set-Key "$capKey\FileAssociations" @{ '.pdf' = $ProgId }
Set-Key 'HKCU:\Software\RegisteredApplications' @{ $AppName = 'Software\Internoodle\PdfTool\Capabilities' }

# 4. shortcuts ----------------------------------------------------------------
Say "  3/5  Adding shortcuts"
$shell = New-Object -ComObject WScript.Shell
# Point at the .ico rather than the .exe: Explorer caches icons per path, and a
# reinstall replaces the .exe underneath any shortcut that already existed,
# which leaves it showing a blank page until the cache is rebuilt.
$iconFile = Join-Path $InstallRoot 'app.ico'
$bundled  = Join-Path $InstallRoot '_internal\pdfviewer.ico'
if (Test-Path $bundled) { Copy-Item $bundled $iconFile -Force }
$iconRef  = if (Test-Path $iconFile) { "$iconFile,0" } else { "$exe,0" }
foreach ($dir in @([Environment]::GetFolderPath('Programs'), [Environment]::GetFolderPath('Desktop'))) {
    if (-not $dir) { continue }
    $lnk = $shell.CreateShortcut((Join-Path $dir "$AppName.lnk"))
    $lnk.TargetPath       = $exe
    $lnk.WorkingDirectory = $InstallRoot
    $lnk.IconLocation     = $iconRef
    $lnk.Description      = 'Open a PDF, then file, print or save it.'
    $lnk.Save()
}

# 4b. Toolbar Menu -------------------------------------------------------------
# Only on machines that have the Internoodle/AdvisorCRM Toolbar Menu installed;
# everywhere else this is skipped silently. Safe to run again - it checks first.
$toolbarMenu = 'C:\Scripts\Toolbar\Toolbar Menu.ps1'
if (Test-Path $toolbarMenu) {
    $launcher = 'C:\Scripts\Toolbar\pdffiler.ps1'
    @"
# Opens the Internoodle PDF Tool from the Toolbar Menu.
# Path is resolved at run time, so this survives updates. Written by the installer.
`$exe = Join-Path `$env:USERPROFILE 'Internoodle\PdfTool\Internoodle PDF Tool.exe'
if (Test-Path -LiteralPath `$exe) {
    Start-Process -FilePath `$exe
} else {
    Add-Type -AssemblyName System.Windows.Forms
    [void][System.Windows.Forms.MessageBox]::Show("Not installed for this user.``n``n`$exe", 'PDF Tool', 'OK', 'Warning')
}
"@ | Set-Content -LiteralPath $launcher -Encoding UTF8

    $menuText = Get-Content -LiteralPath $toolbarMenu -Raw
    if ($menuText -notmatch 'pdffiler\.ps1') {
        $anchor = "[void](Add-Launch `$menu 'Open File Directory...'"
        $line   = "[void](Add-Launch `$menu 'PDF Tool'                             'C:\Scripts\Toolbar\pdffiler.ps1')"
        $lines  = Get-Content -LiteralPath $toolbarMenu
        $at     = ($lines | Select-String -SimpleMatch $anchor | Select-Object -First 1).LineNumber
        if ($at) { $lines = $lines[0..($at-1)] + $line + $lines[$at..($lines.Count-1)] }
        else     { $lines = $lines + $line }          # no anchor: append at the end
        Set-Content -LiteralPath $toolbarMenu -Value $lines -Encoding UTF8
        Say "  4b/5 Added it to your Toolbar Menu"
    } else {
        Say "  4b/5 Already in your Toolbar Menu"
    }
}

# 4c. browsers ------------------------------------------------------------------
# Chrome and Edge open PDFs in their own built-in viewer, so a PDF clicked on a
# website never reaches Windows - and never reaches this app. This flips them to
# "download the PDF and let Windows open it". Only works with the browser closed:
# it rewrites its preferences file on exit and would undo the change.
function Set-PdfHandoff($label, $userData, $processName) {
    if (-not (Test-Path $userData)) { return }
    if (Get-Process -Name $processName -ErrorAction SilentlyContinue) {
        Say "       $label is open - close it, then run this installer again to set it" Yellow
        return
    }
    $profiles = Get-ChildItem $userData -Directory -ErrorAction SilentlyContinue |
                Where-Object { $_.Name -eq 'Default' -or $_.Name -like 'Profile *' }
    foreach ($prof in $profiles) {
        $pref = Join-Path $prof.FullName 'Preferences'
        if (-not (Test-Path $pref)) { continue }
        $backup = "$pref.internoodle-backup"
        try {
            Copy-Item $pref $backup -Force
            $original = [IO.File]::ReadAllText($pref)
            $json = $original | ConvertFrom-Json
            if ($null -eq $json.plugins) {
                $json | Add-Member -NotePropertyName plugins -NotePropertyValue ([pscustomobject]@{}) -Force
            }
            $json.plugins | Add-Member -NotePropertyName always_open_pdf_externally -NotePropertyValue $true -Force
            $out = $json | ConvertTo-Json -Depth 100 -Compress
            if ($out.Length -lt ($original.Length / 2)) { throw "rewrite looks truncated" }
            [IO.File]::WriteAllText($pref, $out, (New-Object Text.UTF8Encoding $false))
            $null = [IO.File]::ReadAllText($pref) | ConvertFrom-Json      # must still parse
            Say "       $label ($($prof.Name)): PDFs will open in $AppName"
        } catch {
            if (Test-Path $backup) { Copy-Item $backup $pref -Force }
            Say "       $label ($($prof.Name)): left unchanged ($($_.Exception.Message))" Yellow
        }
    }
}

Say "  4c/5 Setting browsers to hand PDFs over"
Set-PdfHandoff 'Chrome' "$env:LOCALAPPDATA\Google\Chrome\User Data" 'chrome'
Set-PdfHandoff 'Edge'   "$env:LOCALAPPDATA\Microsoft\Edge\User Data" 'msedge'

# 5. Add/Remove Programs ------------------------------------------------------
Say "  4/5  Adding an uninstall entry"
$size = [math]::Round((Get-ChildItem $InstallRoot -Recurse -File | Measure-Object Length -Sum).Sum / 1KB)
$unKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\$UninstallId"
Set-Key $unKey @{
    'DisplayName'     = $AppName
    'DisplayVersion'  = $Version
    'Publisher'       = 'Internoodle'
    'DisplayIcon'     = "$exe,0"
    'InstallLocation' = $InstallRoot
    'UninstallString' = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$InstallRoot\uninstall.ps1`""
}
New-ItemProperty -Path $unKey -Name 'EstimatedSize' -Value $size -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $unKey -Name 'NoModify' -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $unKey -Name 'NoRepair' -Value 1 -PropertyType DWord -Force | Out-Null

# 6. done ---------------------------------------------------------------------
# NOTE: no "make it your default PDF app" prompt here on purpose - it confused
# first-time users. The app itself offers that as a dismissible bar on launch,
# so the install stays simple.
Say "  5/5  Done." Green
Say ""
Say "  Installed to $InstallRoot" DarkGray
Say "  A Desktop shortcut was added. Open it to get started." DarkGray
Say ""

if (-not $NoPrompt) {
    Read-Host "  Press Enter to close"
}
