param(
    [string]$InstallDir = ""
)

$ErrorActionPreference = "Stop"

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

function Get-DefaultInstallDir {
    if (-not [string]::IsNullOrWhiteSpace($env:LOCALAPPDATA)) {
        return (Join-Path $env:LOCALAPPDATA "Programs\Sura")
    }
    return (Join-Path $HOME ".sura")
}

function Get-PowerShellRunner {
    $pwsh = Get-Command pwsh -ErrorAction SilentlyContinue
    if ($pwsh) { return $pwsh.Source }
    $powershell = Get-Command powershell -ErrorAction SilentlyContinue
    if ($powershell) { return $powershell.Source }
    throw "PowerShell runner not found"
}

function Get-DirectoryByteSize {
    param([string]$Path)
    if (-not (Test-Path -LiteralPath $Path)) { return 0L }
    $total = 0L
    foreach ($file in Get-ChildItem -LiteralPath $Path -Recurse -File -ErrorAction SilentlyContinue) {
        $total += [int64]$file.Length
    }
    return $total
}

function Format-ByteSize {
    param([int64]$Bytes)
    if ($Bytes -ge 1GB) { return ("{0:N1} GB" -f ($Bytes / 1GB)) }
    if ($Bytes -ge 1MB) { return ("{0:N1} MB" -f ($Bytes / 1MB)) }
    if ($Bytes -ge 1KB) { return ("{0:N1} KB" -f ($Bytes / 1KB)) }
    return ("{0} bytes" -f $Bytes)
}

function Resolve-PayloadDir {
    foreach ($candidate in @(
        (Join-Path $PSScriptRoot "payload"),
        (Join-Path (Split-Path -Parent $PSScriptRoot) "payload")
    )) {
        if (Test-Path -LiteralPath $candidate) {
            return $candidate
        }
    }
    return (Join-Path $PSScriptRoot "payload")
}

function Resolve-SetupScript {
    foreach ($candidate in @(
        (Join-Path $PSScriptRoot "SuraSetup.ps1"),
        (Join-Path $PSScriptRoot "support\SuraSetup.ps1")
    )) {
        if (Test-Path -LiteralPath $candidate) {
            return $candidate
        }
    }
    return (Join-Path $PSScriptRoot "SuraSetup.ps1")
}

function Resolve-LogoPath {
    foreach ($candidate in @(
        (Join-Path $PSScriptRoot "SuraLogo.png"),
        (Join-Path $PSScriptRoot "support\SuraLogo.png")
    )) {
        if (Test-Path -LiteralPath $candidate) {
            return $candidate
        }
    }
    return ""
}

$setupScript = Resolve-SetupScript
if (-not (Test-Path -LiteralPath $setupScript)) {
    [System.Windows.Forms.MessageBox]::Show("SuraSetup.ps1 was not found next to this installer.", "Sura Language Setup", "OK", "Error") | Out-Null
    return
}
if ([string]::IsNullOrWhiteSpace($InstallDir)) {
    $InstallDir = Get-DefaultInstallDir
}
$payloadBytes = Get-DirectoryByteSize (Resolve-PayloadDir)
$estimatedInstallBytes = $payloadBytes + 1MB

$form = New-Object System.Windows.Forms.Form
$form.Text = "Sura Language Setup"
$form.StartPosition = "CenterScreen"
$form.FormBorderStyle = "FixedDialog"
$form.MaximizeBox = $false
$form.MinimizeBox = $false
$form.ClientSize = New-Object System.Drawing.Size(560, 462)
$form.Font = New-Object System.Drawing.Font("Segoe UI", 9)

$logoImage = $null
$logoPath = Resolve-LogoPath
if (-not [string]::IsNullOrWhiteSpace($logoPath)) {
    $logoImage = [System.Drawing.Image]::FromFile($logoPath)
    $logo = New-Object System.Windows.Forms.PictureBox
    $logo.Image = $logoImage
    $logo.SizeMode = "Zoom"
    $logo.Location = New-Object System.Drawing.Point(424, 18)
    $logo.Size = New-Object System.Drawing.Size(112, 112)
    $form.Controls.Add($logo)
    $form.Add_FormClosed({
        if ($null -ne $logoImage) {
            $logoImage.Dispose()
        }
    })
}

$title = New-Object System.Windows.Forms.Label
$title.Text = "Install Sura"
$title.Font = New-Object System.Drawing.Font("Segoe UI", 18, [System.Drawing.FontStyle]::Bold)
$title.Location = New-Object System.Drawing.Point(20, 18)
$title.Size = New-Object System.Drawing.Size(390, 36)
$form.Controls.Add($title)

$subtitle = New-Object System.Windows.Forms.Label
$subtitle.Text = "Set up Sura Language, its package manager, and command launchers."
$subtitle.Location = New-Object System.Drawing.Point(22, 58)
$subtitle.Size = New-Object System.Drawing.Size(390, 24)
$form.Controls.Add($subtitle)

$sizeInfo = New-Object System.Windows.Forms.Label
$sizeInfo.Text = "Required space: about $(Format-ByteSize $estimatedInstallBytes)  |  Package payload: $(Format-ByteSize $payloadBytes)"
$sizeInfo.Location = New-Object System.Drawing.Point(22, 92)
$sizeInfo.Size = New-Object System.Drawing.Size(390, 20)
$form.Controls.Add($sizeInfo)

$licenseLabel = New-Object System.Windows.Forms.Label
$licenseLabel.Text = "Installation actions"
$licenseLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold)
$licenseLabel.Location = New-Object System.Drawing.Point(22, 136)
$licenseLabel.Size = New-Object System.Drawing.Size(200, 22)
$form.Controls.Add($licenseLabel)

$license = New-Object System.Windows.Forms.TextBox
$license.Multiline = $true
$license.ReadOnly = $true
$license.ScrollBars = "Vertical"
$license.Location = New-Object System.Drawing.Point(24, 160)
$license.Size = New-Object System.Drawing.Size(512, 108)
$license.Text = "Sura Language is installed as a per-user runtime. The installer copies the language engine and package manager, creates sura and surapkg command launchers, and can add the bin directory to your user PATH. You can uninstall it from this package with SuraSetup.ps1 -Uninstall."
$form.Controls.Add($license)

$accept = New-Object System.Windows.Forms.CheckBox
$accept.Text = "I reviewed these installation actions"
$accept.Location = New-Object System.Drawing.Point(24, 282)
$accept.Size = New-Object System.Drawing.Size(300, 24)
$form.Controls.Add($accept)

$pathLabel = New-Object System.Windows.Forms.Label
$pathLabel.Text = "Install location"
$pathLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold)
$pathLabel.Location = New-Object System.Drawing.Point(22, 318)
$pathLabel.Size = New-Object System.Drawing.Size(200, 22)
$form.Controls.Add($pathLabel)

$pathBox = New-Object System.Windows.Forms.TextBox
$pathBox.Location = New-Object System.Drawing.Point(24, 342)
$pathBox.Size = New-Object System.Drawing.Size(410, 24)
$pathBox.Text = [System.IO.Path]::GetFullPath($InstallDir)
$form.Controls.Add($pathBox)

$browse = New-Object System.Windows.Forms.Button
$browse.Text = "Browse..."
$browse.Location = New-Object System.Drawing.Point(444, 341)
$browse.Size = New-Object System.Drawing.Size(92, 26)
$form.Controls.Add($browse)

$addPath = New-Object System.Windows.Forms.CheckBox
$addPath.Text = "Add Sura Language to my user PATH"
$addPath.Checked = $true
$addPath.Location = New-Object System.Drawing.Point(24, 376)
$addPath.Size = New-Object System.Drawing.Size(260, 24)
$form.Controls.Add($addPath)

$status = New-Object System.Windows.Forms.Label
$status.Text = "Ready."
$status.Location = New-Object System.Drawing.Point(24, 408)
$status.Size = New-Object System.Drawing.Size(320, 24)
$form.Controls.Add($status)

$install = New-Object System.Windows.Forms.Button
$install.Text = "Install"
$install.Enabled = $false
$install.Location = New-Object System.Drawing.Point(350, 406)
$install.Size = New-Object System.Drawing.Size(86, 30)
$form.Controls.Add($install)

$cancel = New-Object System.Windows.Forms.Button
$cancel.Text = "Cancel"
$cancel.Location = New-Object System.Drawing.Point(450, 406)
$cancel.Size = New-Object System.Drawing.Size(86, 30)
$form.Controls.Add($cancel)

$accept.Add_CheckedChanged({
    $install.Enabled = $accept.Checked
})

$browse.Add_Click({
    $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $dialog.Description = "Choose where Sura Language should be installed"
    $dialog.SelectedPath = $pathBox.Text
    if ($dialog.ShowDialog($form) -eq [System.Windows.Forms.DialogResult]::OK) {
        $pathBox.Text = $dialog.SelectedPath
    }
})

$cancel.Add_Click({
    $form.Close()
})

$install.Add_Click({
    try {
        $chosen = [System.IO.Path]::GetFullPath($pathBox.Text)
        $install.Enabled = $false
        $browse.Enabled = $false
        $cancel.Enabled = $false
        $accept.Enabled = $false
        $addPath.Enabled = $false
        $status.Text = "Installing..."
        $form.Refresh()

        $runner = Get-PowerShellRunner
        $args = @("-NoProfile", "-ExecutionPolicy", "Bypass", "-File", $setupScript, "-InstallDir", $chosen, "-Quiet")
        if (-not $addPath.Checked) { $args += "-NoPath" }
        $previousErrorActionPreference = $ErrorActionPreference
        try {
            $ErrorActionPreference = "Continue"
            $installerOutput = @(& $runner @args 2>&1 | ForEach-Object { "$_" })
            $installerExitCode = $LASTEXITCODE
        } finally {
            $ErrorActionPreference = $previousErrorActionPreference
        }
        if ($installerExitCode -ne 0) {
            $detail = ($installerOutput | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) -join [Environment]::NewLine
            if ([string]::IsNullOrWhiteSpace($detail)) { $detail = "Installer exited with code $installerExitCode." }
            throw $detail
        }

        $status.Text = "Installed."
        [System.Windows.Forms.MessageBox]::Show("Sura Language was installed successfully. Open a new terminal before using the sura command.", "Sura Language Setup", "OK", "Information") | Out-Null
        $form.Close()
    } catch {
        $status.Text = "Install failed."
        [System.Windows.Forms.MessageBox]::Show($_.Exception.Message, "Sura Language Setup", "OK", "Error") | Out-Null
        $install.Enabled = $accept.Checked
        $browse.Enabled = $true
        $cancel.Enabled = $true
        $accept.Enabled = $true
        $addPath.Enabled = $true
    }
})

[void]$form.ShowDialog()