#!/usr/bin/env pwsh
# Windows Installer Build Script
# Creates per-arch portable archives and a unified installer that auto-detects architecture.
# Supports single-arch (backward compat) and dual-arch builds.

param(
    [string]$OutputDir = ".",
    [string]$Version = "1.0.0",
    [string]$X64BuildDir,
    [string]$Arm64BuildDir
)

$ErrorActionPreference = "Stop"

Write-Host "Building Windows installer packages..." -ForegroundColor Cyan

# Ensure we're in the project root
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectRoot = Split-Path -Parent $ScriptDir
Set-Location $ProjectRoot

$ResolvedOutput = Resolve-Path $OutputDir

# Auto-detect build dirs from default Flutter output paths if not provided
if (-not $X64BuildDir -and (Test-Path "build\windows\x64\runner\Release")) {
    $X64BuildDir = "build\windows\x64\runner\Release"
}
if (-not $Arm64BuildDir -and (Test-Path "build\windows\arm64\runner\Release")) {
    $Arm64BuildDir = "build\windows\arm64\runner\Release"
}

$HasX64 = $X64BuildDir -and (Test-Path $X64BuildDir)
$HasArm64 = $Arm64BuildDir -and (Test-Path $Arm64BuildDir)

if (-not $HasX64 -and -not $HasArm64) {
    Write-Error "No build directories found. Provide -X64BuildDir and/or -Arm64BuildDir, or run 'flutter build windows --release' first."
    exit 1
}

Write-Host "Architectures found:" -ForegroundColor Green
if ($HasX64)   { Write-Host "  x64:   $X64BuildDir" }
if ($HasArm64) { Write-Host "  arm64: $Arm64BuildDir" }

# Check for 7-Zip
Write-Host "`nChecking for 7-Zip..." -ForegroundColor Cyan
if (-not (Get-Command 7z -ErrorAction SilentlyContinue)) {
    Write-Host "7-Zip not found in PATH. Installing via Chocolatey..." -ForegroundColor Yellow

    if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
        Write-Error "Chocolatey is not installed. Please install it from https://chocolatey.org/install"
        exit 1
    }

    choco install 7zip -y
    refreshenv

    if (-not (Get-Command 7z -ErrorAction SilentlyContinue)) {
        Write-Error "Failed to install 7-Zip"
        exit 1
    }
}

# Create Portable Archives
if ($HasX64) {
    Write-Host "`nCreating x64 portable archive..." -ForegroundColor Cyan
    $X64Portable = Join-Path $ResolvedOutput "plezy-windows-x64-portable.7z"
    Push-Location $X64BuildDir
    try {
        if (Test-Path $X64Portable) { Remove-Item $X64Portable -Force }
        7z a -mx=9 $X64Portable *
        Write-Host "Created: $X64Portable" -ForegroundColor Green
    } finally {
        Pop-Location
    }
}

if ($HasArm64) {
    Write-Host "`nCreating arm64 portable archive..." -ForegroundColor Cyan
    $Arm64Portable = Join-Path $ResolvedOutput "plezy-windows-arm64-portable.7z"
    Push-Location $Arm64BuildDir
    try {
        if (Test-Path $Arm64Portable) { Remove-Item $Arm64Portable -Force }
        7z a -mx=9 $Arm64Portable *
        Write-Host "Created: $Arm64Portable" -ForegroundColor Green
    } finally {
        Pop-Location
    }
}

# Stage files for Inno Setup
Write-Host "`nStaging files for installer..." -ForegroundColor Cyan
$StagingDir = "staging"
if (Test-Path $StagingDir) { Remove-Item $StagingDir -Recurse -Force }

if ($HasX64) {
    $X64Staging = Join-Path $StagingDir "x64"
    New-Item -ItemType Directory -Path $X64Staging -Force | Out-Null
    Copy-Item -Path "$X64BuildDir\*" -Destination $X64Staging -Recurse
}
if ($HasArm64) {
    $Arm64Staging = Join-Path $StagingDir "arm64"
    New-Item -ItemType Directory -Path $Arm64Staging -Force | Out-Null
    Copy-Item -Path "$Arm64BuildDir\*" -Destination $Arm64Staging -Recurse
}

# Generate Inno Setup Script
Write-Host "`nGenerating Inno Setup script..." -ForegroundColor Cyan
$SetupScript = "setup.iss"
$DualArch = $HasX64 -and $HasArm64

if ($DualArch) {
    # Dual-arch unified installer with architecture detection
    $IssContent = @"
#define Name "Plezy"
#define Version "$Version"
#define Publisher "edde746"
#define ExeName "plezy.exe"

[Setup]
AppId={{4213385e-f7be-4f2b-95f9-54082a28bb8f}
AppName={#Name}
AppVersion={#Version}
AppPublisher={#Publisher}
DefaultDirName={autopf}\{#Name}
DefaultGroupName={#Name}
AllowNoIcons=yes
OutputDir=.
OutputBaseFilename=plezy-windows-installer
Compression=lzma
SolidCompression=yes
WizardStyle=modern
PrivilegesRequired=lowest
ArchitecturesAllowed=x64compatible arm64
ArchitecturesInstallIn64BitMode=x64compatible arm64

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "staging\x64\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: IsX64
Source: "staging\arm64\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs solidbreak; Check: IsArm64

[Icons]
Name: "{group}\{#Name}"; Filename: "{app}\{#ExeName}"
Name: "{group}\{cm:UninstallProgram,{#Name}}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#Name}"; Filename: "{app}\{#ExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#ExeName}"; Description: "{cm:LaunchProgram,{#Name}}"; Flags: nowait postinstall; Check: not IsNoRun

[Code]
function IsNoRun: Boolean;
begin
  Result := ExpandConstant('{param:NORUN|0}') = '1';
end;

function IsX64: Boolean;
begin
  Result := not IsArm64;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  MarkerPath: String;
begin
  if CurStep = ssPostInstall then
  begin
    MarkerPath := ExpandConstant('{app}\.winget');
    if ExpandConstant('{param:WINGET|0}') = '1' then
      SaveStringToFile(MarkerPath, '', False)
    else
      DeleteFile(MarkerPath);
  end;
end;
"@
} else {
    # Single-arch installer (backward compatible, no Check: functions needed)
    if ($HasX64) {
        $ArchAllowed = "x64compatible"
        $StagingSource = "staging\x64\*"
    } else {
        $ArchAllowed = "arm64"
        $StagingSource = "staging\arm64\*"
    }

    $IssContent = @"
#define Name "Plezy"
#define Version "$Version"
#define Publisher "edde746"
#define ExeName "plezy.exe"

[Setup]
AppId={{4213385e-f7be-4f2b-95f9-54082a28bb8f}
AppName={#Name}
AppVersion={#Version}
AppPublisher={#Publisher}
DefaultDirName={autopf}\{#Name}
DefaultGroupName={#Name}
AllowNoIcons=yes
OutputDir=.
OutputBaseFilename=plezy-windows-installer
Compression=lzma
SolidCompression=yes
WizardStyle=modern
PrivilegesRequired=lowest
ArchitecturesAllowed=$ArchAllowed
ArchitecturesInstallIn64BitMode=$ArchAllowed

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "$StagingSource"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{group}\{#Name}"; Filename: "{app}\{#ExeName}"
Name: "{group}\{cm:UninstallProgram,{#Name}}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#Name}"; Filename: "{app}\{#ExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#ExeName}"; Description: "{cm:LaunchProgram,{#Name}}"; Flags: nowait postinstall; Check: not IsNoRun

[Code]
function IsNoRun: Boolean;
begin
  Result := ExpandConstant('{param:NORUN|0}') = '1';
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  MarkerPath: String;
begin
  if CurStep = ssPostInstall then
  begin
    MarkerPath := ExpandConstant('{app}\.winget');
    if ExpandConstant('{param:WINGET|0}') = '1' then
      SaveStringToFile(MarkerPath, '', False)
    else
      DeleteFile(MarkerPath);
  end;
end;
"@
}

$IssContent | Out-File -FilePath $SetupScript -Encoding ASCII
Write-Host "Created: $SetupScript" -ForegroundColor Green

# Check for Inno Setup
Write-Host "`nChecking for Inno Setup..." -ForegroundColor Cyan
$InnoSetupPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"

if (-not (Test-Path $InnoSetupPath)) {
    Write-Host "Inno Setup not found. Installing via Chocolatey..." -ForegroundColor Yellow

    if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
        Write-Error "Chocolatey is not installed. Please install it from https://chocolatey.org/install"
        exit 1
    }

    choco install innosetup -y

    if (-not (Test-Path $InnoSetupPath)) {
        Write-Error "Failed to install Inno Setup"
        exit 1
    }
}

# Build Installer
Write-Host "`nBuilding installer with Inno Setup..." -ForegroundColor Cyan
& $InnoSetupPath $SetupScript

if ($LASTEXITCODE -ne 0) {
    Write-Error "Inno Setup compilation failed"
    exit 1
}

# Clean up staging
Remove-Item $StagingDir -Recurse -Force -ErrorAction SilentlyContinue

# Summary
Write-Host "`nBuild complete!" -ForegroundColor Green
if ($HasX64)   { Write-Host "Portable (x64):   $X64Portable" -ForegroundColor White }
if ($HasArm64) { Write-Host "Portable (arm64): $Arm64Portable" -ForegroundColor White }
Write-Host "Installer:        $(Join-Path $ResolvedOutput 'plezy-windows-installer.exe')" -ForegroundColor White
