param(
    [ValidateSet("x64", "arm64")]
    [string]$Arch = "",
    [switch]$SkipPipInstall,
    [switch]$IncludeOptionalDeps = $true,
    [switch]$UpgradePip
)

$ErrorActionPreference = "Stop"

Set-Location (Join-Path $PSScriptRoot "..")

function Get-NormalizedPythonArch {
    $machine = (& python -c "import platform; print(platform.machine().lower())").Trim().ToLower()
    if ($machine -in @("amd64", "x86_64")) {
        return "x64"
    }
    if ($machine -in @("arm64", "aarch64")) {
        return "arm64"
    }
    throw "Unsupported Python architecture: '$machine'"
}

if ([string]::IsNullOrWhiteSpace($Arch)) {
    $Arch = Get-NormalizedPythonArch
} else {
    $detectedArch = Get-NormalizedPythonArch
    if ($detectedArch -ne $Arch) {
        throw "Python architecture is '$detectedArch', but -Arch '$Arch' was requested. Use matching Python for this target."
    }
}

$venvDir = ".venv-win-$Arch"
$pythonExe = Join-Path $venvDir "Scripts\python.exe"
$pyinstallerExe = Join-Path $venvDir "Scripts\pyinstaller.exe"

if (-not (Test-Path $venvDir)) {
    & python -m venv $venvDir
}

if (-not $SkipPipInstall) {
    if ($UpgradePip) {
        & $pythonExe -m pip install --upgrade pip
    }
    & $pythonExe -m pip install -r requirements.txt
    if ($IncludeOptionalDeps) {
        & $pythonExe -m pip install -r requirements-optional.txt
    } else {
        Write-Host "Skipping requirements-optional.txt (-IncludeOptionalDeps:`$false)."
    }
    & $pythonExe -m pip install -r requirements-packaging.txt
} else {
    Write-Host "Skipping pip install (-SkipPipInstall)."
}

if (-not (Test-Path $pyinstallerExe)) {
    throw "pyinstaller not found in $venvDir. Install dependencies or rerun without -SkipPipInstall."
}

if (-not $env:PYINSTALLER_CONFIG_DIR) {
    $env:PYINSTALLER_CONFIG_DIR = Join-Path (Get-Location) ".pyinstaller"
}
New-Item -ItemType Directory -Path $env:PYINSTALLER_CONFIG_DIR -Force | Out-Null

$appStageDir = "packaging/pyinstaller/app"
if (Test-Path $appStageDir) {
    Remove-Item $appStageDir -Recurse -Force
}
New-Item -ItemType Directory -Path $appStageDir -Force | Out-Null

$items = @(
    "VERSION",
    "Main.py",
    "ask.py",
    "build_index.py",
    "chunk_note.py",
    "fetch_text_from_selected_onenote_url.py",
    "llm_provider.py",
    "requirements.txt",
    "requirements-optional.txt",
    ".env.example",
    "DEPLOYMENT.md",
    "PACKAGING_ROADMAP.md",
    "scripts",
    "server"
)

foreach ($item in $items) {
    if (Test-Path $item) {
        Copy-Item $item -Destination $appStageDir -Recurse -Force
    } else {
        Write-Host "[WARN] Missing item (skipped): $item"
    }
}

$serverDataDir = Join-Path $appStageDir "server/data"
if (Test-Path $serverDataDir) {
    Remove-Item $serverDataDir -Recurse -Force
}

Get-ChildItem -Path $appStageDir -Recurse -Directory -Filter "__pycache__" | ForEach-Object {
    Remove-Item $_.FullName -Recurse -Force
}
Get-ChildItem -Path $appStageDir -Recurse -File | Where-Object {
    $_.Name.EndsWith(".pyc") -or $_.Name.EndsWith(".pyo") -or $_.Name -eq ".DS_Store"
} | ForEach-Object {
    Remove-Item $_.FullName -Force
}

& $pyinstallerExe --noconfirm --clean packaging/pyinstaller/eksamenapp.spec
Write-Host "Desktop bundle ready: dist/ATHENODE-desktop"

$stamp = Get-Date -Format "yyyyMMdd_HHmmss"
$packageName = "athenode_desktop_windows_${Arch}_${stamp}"
New-Item -ItemType Directory -Path "dist" -Force | Out-Null
$zipPath = Join-Path "dist" "${packageName}.zip"
if (Test-Path $zipPath) {
    Remove-Item $zipPath -Force
}

Compress-Archive -Path "dist/ATHENODE-desktop" -DestinationPath $zipPath -CompressionLevel Optimal

$checksumPath = "${zipPath}.sha256"
$hash = (Get-FileHash -Path $zipPath -Algorithm SHA256).Hash.ToLower()
$filename = [System.IO.Path]::GetFileName($zipPath)
Set-Content -Path $checksumPath -Value "$hash  $filename"

Write-Host "Created desktop release zip: $zipPath"
Write-Host "Created checksum: $checksumPath"
