<#
.SYNOPSIS
    SiteKings tray helper for Windows 7 era desktops.

    User actions are signaled with files in ProgramData so the SYSTEM agent or
    watchdog can pick them up without requiring user elevation.
#>

$ErrorActionPreference = "SilentlyContinue"

$mutex = New-Object System.Threading.Mutex($false, "Global\SiteKingsLegacyTray")
if (-not $mutex.WaitOne(0, $false)) { exit 0 }

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

function Get-ConfigDir {
    foreach ($candidate in @("$env:ProgramData\SiteKings", "$env:ProgramData\LCL")) {
        if (Test-Path (Join-Path $candidate "config.json")) { return $candidate }
    }
    return "$env:ProgramData\SiteKings"
}

$Script:ConfigDir = Get-ConfigDir
$Script:StatusFile = Join-Path $Script:ConfigDir "status.json"
$Script:ConfigFile = Join-Path $Script:ConfigDir "config.json"
$Script:LogDir = Join-Path $Script:ConfigDir "logs"
$Script:SyncFlag = Join-Path $Script:ConfigDir "sync-now.flag"
$Script:UpdateFlag = Join-Path $Script:ConfigDir "update-flag.txt"
$Script:RestartFlag = Join-Path $Script:ConfigDir "restart-agent.flag"
$Script:RefreshMs = 15000

if (-not (Test-Path $Script:ConfigDir)) { New-Item -ItemType Directory -Path $Script:ConfigDir -Force | Out-Null }

function Get-JsonValue {
    param([string]$Path, [string]$Name)
    if (-not (Test-Path $Path)) { return "" }
    $raw = [IO.File]::ReadAllText($Path)
    $pattern = '"' + [Regex]::Escape($Name) + '"\s*:\s*"([^"]*)"'
    $match = [Regex]::Match($raw, $pattern, "IgnoreCase")
    if ($match.Success) { return $match.Groups[1].Value }
    return ""
}

function Get-ConfigValue {
    param([string[]]$Names)
    foreach ($name in $Names) {
        $value = Get-JsonValue $Script:ConfigFile $name
        if ($value) { return $value }
    }
    return ""
}

function Get-Status {
    $state = Get-JsonValue $Script:StatusFile "state"
    if (-not $state) { $state = "unknown" }
    $lastSync = Get-JsonValue $Script:StatusFile "lastSync"
    if (-not $lastSync) { $lastSync = "Never" }
    $version = Get-JsonValue $Script:StatusFile "version"
    if (-not $version) { $version = "?" }
    return @{ State = $state; LastSync = $lastSync; Version = $version; Hostname = $env:COMPUTERNAME }
}

function New-TrayIcon {
    param([string]$ColorName)
    $bitmap = New-Object System.Drawing.Bitmap(16, 16)
    $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
    $graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
    $graphics.Clear([System.Drawing.Color]::Transparent)
    $color = [System.Drawing.Color]::Gray
    if ($ColorName -eq "Green") { $color = [System.Drawing.Color]::FromArgb(70, 167, 88) }
    if ($ColorName -eq "Yellow") { $color = [System.Drawing.Color]::FromArgb(245, 166, 35) }
    if ($ColorName -eq "Red") { $color = [System.Drawing.Color]::FromArgb(229, 72, 77) }
    $brush = New-Object System.Drawing.SolidBrush($color)
    $graphics.FillEllipse($brush, 2, 2, 12, 12)
    $graphics.Dispose()
    return [System.Drawing.Icon]::FromHandle($bitmap.GetHicon())
}

$Script:TrayIcons = @{
    Green = New-TrayIcon "Green"
    Yellow = New-TrayIcon "Yellow"
    Red = New-TrayIcon "Red"
    Gray = New-TrayIcon "Gray"
}

function Set-TrayIcon {
    param([string]$ColorName)
    if (-not $Script:TrayIcons.ContainsKey($ColorName)) { $ColorName = "Gray" }
    $notifyIcon.Icon = $Script:TrayIcons[$ColorName]
}

function Dispose-TrayIcons {
    foreach ($icon in $Script:TrayIcons.Values) {
        try { $icon.Dispose() } catch { }
    }
}

function Get-IconColor {
    param($Status)
    if ($Status.State -eq "idle") { return "Green" }
    if ($Status.State -eq "syncing") { return "Yellow" }
    if ($Status.State -eq "error") { return "Red" }
    return "Gray"
}

function Get-ServerUrl {
    $serverUrl = Get-JsonValue $Script:ConfigFile "server_url"
    if (-not $serverUrl) { $serverUrl = Get-JsonValue $Script:ConfigFile "ServerUrl" }
    if (-not $serverUrl) { $serverUrl = "https://rmm.sitekings.net" }
    return $serverUrl.TrimEnd("/")
}

function Queue-SyncNow {
    "sync_requested $(Get-Date -Format o)" | Set-Content $Script:SyncFlag -Force
    $notifyIcon.ShowBalloonTip(3000, "SiteKings Sync Agent", "Sync requested.", [System.Windows.Forms.ToolTipIcon]::Info)
}

function Queue-Update {
    "repair_requested $(Get-Date -Format o)" | Set-Content $Script:UpdateFlag -Force
    "repair_requested $(Get-Date -Format o)" | Set-Content $Script:RestartFlag -Force
    $notifyIcon.ShowBalloonTip(3000, "SiteKings Sync Agent", "Repair requested.", [System.Windows.Forms.ToolTipIcon]::Info)
}

function Open-Dashboard {
    try { Start-Process ((Get-ServerUrl) + "/dashboard") } catch { }
}

function New-SupportChatUrl {
    $serverUrl = Get-ServerUrl
    $query = @(
        "support=1",
        "hostname=$([uri]::EscapeDataString($env:COMPUTERNAME))"
    )
    $endpointUserID = Get-ConfigValue @("EndpointUserID", "endpoint_user_id")
    $displayName = Get-ConfigValue @("DisplayName", "display_name")
    $orgID = Get-ConfigValue @("OrgID", "org_id")
    $groupIDs = Get-ConfigValue @("GroupIDs", "group_ids")
    $role = Get-ConfigValue @("Role", "role")
    if ($endpointUserID) { $query += "endpoint_user_id=$([uri]::EscapeDataString($endpointUserID))" }
    if ($displayName) { $query += "display_name=$([uri]::EscapeDataString($displayName))" }
    if ($orgID) { $query += "org_id=$([uri]::EscapeDataString($orgID))" }
    if ($groupIDs) { $query += "group_ids=$([uri]::EscapeDataString($groupIDs))" }
    if ($role) { $query += "role=$([uri]::EscapeDataString($role))" }
    return "$serverUrl/messenger?$($query -join '&')"
}

function Open-SupportChat {
    try {
        Start-Process (New-SupportChatUrl)
    } catch {
        [System.Windows.Forms.MessageBox]::Show("Could not open Chat with IT: $($_.Exception.Message)", "SiteKings Sync Agent", "OK", "Warning")
    }
}

function Open-Logs {
    if (Test-Path $Script:LogDir) { Start-Process $Script:LogDir }
}

$form = New-Object System.Windows.Forms.Form
$form.ShowInTaskbar = $false
$form.WindowState = [System.Windows.Forms.FormWindowState]::Minimized
$form.Visible = $false

$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
$notifyIcon.Icon = $Script:TrayIcons["Gray"]
$notifyIcon.Text = "SiteKings Sync Agent"
$notifyIcon.Visible = $true

$menu = New-Object System.Windows.Forms.ContextMenuStrip
$statusItem = New-Object System.Windows.Forms.ToolStripMenuItem
$statusItem.Enabled = $false
$menu.Items.Add($statusItem) | Out-Null
$menu.Items.Add("-") | Out-Null

$syncItem = New-Object System.Windows.Forms.ToolStripMenuItem
$syncItem.Text = "Sync Now"
$syncItem.Add_Click({ Queue-SyncNow })
$menu.Items.Add($syncItem) | Out-Null

$updateItem = New-Object System.Windows.Forms.ToolStripMenuItem
$updateItem.Text = "Repair Agent"
$updateItem.Add_Click({ Queue-Update })
$menu.Items.Add($updateItem) | Out-Null

$dashboardItem = New-Object System.Windows.Forms.ToolStripMenuItem
$dashboardItem.Text = "Open Dashboard"
$dashboardItem.Add_Click({ Open-Dashboard })
$menu.Items.Add($dashboardItem) | Out-Null

$chatItem = New-Object System.Windows.Forms.ToolStripMenuItem
$chatItem.Text = "Chat with IT"
$chatItem.Add_Click({ Open-SupportChat })
$menu.Items.Add($chatItem) | Out-Null

$logsItem = New-Object System.Windows.Forms.ToolStripMenuItem
$logsItem.Text = "View Logs"
$logsItem.Add_Click({ Open-Logs })
$menu.Items.Add($logsItem) | Out-Null

$menu.Items.Add("-") | Out-Null
$exitItem = New-Object System.Windows.Forms.ToolStripMenuItem
$exitItem.Text = "Exit"
$exitItem.Add_Click({
    $notifyIcon.Visible = $false
    $notifyIcon.Dispose()
    Dispose-TrayIcons
    $form.Close()
})
$menu.Items.Add($exitItem) | Out-Null
$notifyIcon.ContextMenuStrip = $menu

$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = $Script:RefreshMs
$timer.Add_Tick({
    $status = Get-Status
    $statusItem.Text = "Status: $($status.State)    Last sync: $($status.LastSync)"
    Set-TrayIcon (Get-IconColor $status)
    $text = "SiteKings Sync Agent`n$($status.Hostname) - $($status.State)`nLast sync: $($status.LastSync)"
    if ($text.Length -gt 63) { $text = $text.Substring(0, 63) }
    $notifyIcon.Text = $text
})
$timer.Start()
$timer_Tick = $timer.GetType().GetEvent("Tick")
$status = Get-Status
$statusItem.Text = "Status: $($status.State)    Last sync: $($status.LastSync)"
Set-TrayIcon (Get-IconColor $status)

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