/**
 * desktop/src/tray.ts — the menubar/system-tray icon that keeps the app alive
 * after its window is hidden (the embedded server must keep running so remote
 * devices stay connected — the vibe-coding scenario).
 *
 * The context menu also hosts the D-1 host-picker (PLAN_NATIVE_TUNNEL /
 * C-Desktop): "This machine (local)" ↔ each configured remote tunnel host, as a
 * radio group, plus add/remove. The menu is rebuilt (never mutated) whenever the
 * host list or selection changes — call buildTrayMenu() and setContextMenu().
 *
 * Icon requirement: `iconPath` MUST point at an existing image. new Tray() with a
 * missing/invalid path can throw on some platforms; that failure surfaces to the
 * caller rather than being swallowed (a broken install should be visible, not
 * silently degrade). The caller owns whether to guard startup around it.
 */
import { Menu, Tray } from 'electron'
import type { MenuItemConstructorOptions } from 'electron'
import type { RemoteHost } from './types.js'

const TRAY_TOOLTIP = 'Web Terminal'
/** Label for the local (embedded server) entry — selectedHostId === null. */
const LOCAL_HOST_LABEL = 'This machine (local)'

export interface TrayHandlers {
  show(): void
  quit(): void
  /** Switch the active host; null → "This machine (local)". */
  selectHost(id: string | null): void
  /** Prompt for + add a new remote host. */
  addHost(): void
  /** Remove a configured remote host by id. */
  removeHost(id: string): void
}

/** The host-picker state the menu renders (the local entry is implicit). */
export interface TrayHostState {
  readonly remoteHosts: readonly RemoteHost[]
  /** Selected host id, or null → local. */
  readonly selectedHostId: string | null
}

/** Build the tray context menu for the given host state (pure construction). */
export function buildTrayMenu(state: TrayHostState, handlers: TrayHandlers): Menu {
  const localItem: MenuItemConstructorOptions = {
    label: LOCAL_HOST_LABEL,
    type: 'radio',
    checked: state.selectedHostId === null,
    click: () => handlers.selectHost(null),
  }

  const hostItems: MenuItemConstructorOptions[] = state.remoteHosts.map((host) => ({
    label: host.name,
    type: 'radio',
    checked: state.selectedHostId === host.id,
    click: () => handlers.selectHost(host.id),
  }))

  const selectedRemoteId =
    state.selectedHostId !== null &&
    state.remoteHosts.some((host) => host.id === state.selectedHostId)
      ? state.selectedHostId
      : null

  const template: MenuItemConstructorOptions[] = [
    { label: 'Host', enabled: false },
    localItem,
    ...hostItems,
    { type: 'separator' },
    { label: 'Add remote host…', click: () => handlers.addHost() },
    {
      label: 'Remove selected host',
      enabled: selectedRemoteId !== null,
      click: () => {
        if (selectedRemoteId !== null) handlers.removeHost(selectedRemoteId)
      },
    },
    { type: 'separator' },
    { label: 'Show Web Terminal', click: () => handlers.show() },
    { label: 'Quit', click: () => handlers.quit() },
  ]

  return Menu.buildFromTemplate(template)
}

export function createTray(
  iconPath: string,
  state: TrayHostState,
  handlers: TrayHandlers,
): Tray {
  const tray = new Tray(iconPath)
  tray.setToolTip(TRAY_TOOLTIP)
  tray.setContextMenu(buildTrayMenu(state, handlers))
  return tray
}
