Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$script:scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$script:serverExe = Join-Path $script:scriptDir "PlantUMLLocalServer.exe"
$script:testUrl = "http://127.0.0.1:5080/svg/Syp9J4vLqBLJSCfFibBmICt9oGS0"
$script:homeUrl = "http://127.0.0.1:5080"
$script:startedByTray = $false
$script:serverProcess = $null

function Test-ServerHealthy {
    try {
        $response = Invoke-WebRequest -UseBasicParsing -Uri $script:testUrl -TimeoutSec 2
        return ($response.StatusCode -eq 200 -and $response.Content -match "<svg")
    } catch {
        return $false
    }
}

function Update-StatusText {
    param([System.Windows.Forms.NotifyIcon]$NotifyIcon)

    if (Test-ServerHealthy) {
        $NotifyIcon.Icon = [System.Drawing.SystemIcons]::Information
        $NotifyIcon.Text = "PlantUML Local Server: Running"
        return
    }

    $NotifyIcon.Icon = [System.Drawing.SystemIcons]::Warning
    $NotifyIcon.Text = "PlantUML Local Server: Stopped"
}

function Start-Server {
    if (-not (Test-Path $script:serverExe)) {
        [System.Windows.Forms.MessageBox]::Show(
            "PlantUMLLocalServer.exe was not found. Keep tray script and server executable in the same folder.",
            "PlantUML Local Server",
            [System.Windows.Forms.MessageBoxButtons]::OK,
            [System.Windows.Forms.MessageBoxIcon]::Error
        ) | Out-Null
        return
    }

    if (Test-ServerHealthy) {
        return
    }

    $script:serverProcess = Start-Process -FilePath $script:serverExe -PassThru -WindowStyle Hidden
    $script:startedByTray = $true
}

function Stop-Server {
    if ($script:serverProcess -and -not $script:serverProcess.HasExited) {
        Stop-Process -Id $script:serverProcess.Id -Force -ErrorAction SilentlyContinue
        return
    }

    Get-Process -Name "PlantUMLLocalServer" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
}

$appContext = New-Object System.Windows.Forms.ApplicationContext
$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
$notifyIcon.Visible = $true
$notifyIcon.Icon = [System.Drawing.SystemIcons]::Application
$notifyIcon.Text = "PlantUML Local Server"

$menu = New-Object System.Windows.Forms.ContextMenuStrip

$openLocalItem = $menu.Items.Add("Open Local Test URL")
$openLocalItem.Add_Click({
    Start-Process $script:testUrl | Out-Null
})

$copyUrlItem = $menu.Items.Add("Copy Server URL")
$copyUrlItem.Add_Click({
    [System.Windows.Forms.Clipboard]::SetText("http://127.0.0.1:5080/")
})

$menu.Items.Add("-") | Out-Null

$startItem = $menu.Items.Add("Start Server")
$startItem.Add_Click({
    Start-Server
    Update-StatusText -NotifyIcon $notifyIcon
})

$stopItem = $menu.Items.Add("Stop Server")
$stopItem.Add_Click({
    Stop-Server
    Start-Sleep -Milliseconds 250
    Update-StatusText -NotifyIcon $notifyIcon
})

$restartItem = $menu.Items.Add("Restart Server")
$restartItem.Add_Click({
    Stop-Server
    Start-Sleep -Milliseconds 300
    Start-Server
    Update-StatusText -NotifyIcon $notifyIcon
})

$openHomeItem = $menu.Items.Add("Open Server Root")
$openHomeItem.Add_Click({
    Start-Process $script:homeUrl | Out-Null
})

$menu.Items.Add("-") | Out-Null

$exitItem = $menu.Items.Add("Exit")
$exitItem.Add_Click({
    if ($script:startedByTray) {
        Stop-Server
    }
    $notifyIcon.Visible = $false
    $statusTimer.Stop()
    $statusTimer.Dispose()
    $notifyIcon.Dispose()
    $menu.Dispose()
    $appContext.ExitThread()
})

$notifyIcon.ContextMenuStrip = $menu
$notifyIcon.Add_DoubleClick({
    Start-Process $script:testUrl | Out-Null
})

$statusTimer = New-Object System.Windows.Forms.Timer
$statusTimer.Interval = 3000
$statusTimer.Add_Tick({
    Update-StatusText -NotifyIcon $notifyIcon
})

Start-Server
Update-StatusText -NotifyIcon $notifyIcon
$statusTimer.Start()

[System.Windows.Forms.Application]::Run($appContext)
