/**
 * @file Open-at-login integration (macOS Login Items + Windows startup).
 *
 * Both platforms go through Electron's first-party `app.*LoginItemSettings`
 * API — no third-party deps, no hand-rolled plist or registry edits:
 *   - macOS: wraps the modern `SMAppService` / `ServiceManagement` framework
 *     (macOS 13+), so the toggle appears in System Settings → General →
 *     Login Items where users expect to manage it.
 *   - Windows: writes an entry under the per-user
 *     `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` registry key (the
 *     standard startup location), which shows up in Task Manager → Startup.
 *
 * Linux has no Electron-supported equivalent, so the toggle is a no-op there.
 * @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
 */
/* =============================================================================
 * MODULE_GUIDE — extended in-file reference (comments only; safe to read, never executed)
 * =============================================================================
 * **Purpose:** Dashboard module consumed by the React client, MCP tools, or desktop shell depending on deployment mode.
 *
 * ## Design constraints
 * - Local-first: no telemetry leaves the machine unless the user configures webhooks.
 * - Fail-safe hooks path on the server must never block Claude Code; UI mirrors that
 *   philosophy by degrading gracefully (empty states, stale badges, reconnect loops).
 * - Destructive flows stay behind explicit confirmation modals and server-side gates.
 * - Internationalization: user-visible strings belong in i18n JSON, not literals here.
 *
 * ## Remote data & SSH
 * Remote Data Sources let operators aggregate multiple machines. SSH entries describe
 * how to reach a peer dashboard; the global data scope (`dataScope.ts`) narrows every
 * scoped GET via `?sources=`. Health checks and import history surface in Settings.
 *
 * ## Observability
 * Prometheus scrapes `GET /api/metrics` (see `monitoring/`). Grafana ships four
 * provisioned boards (overview, sessions, tools, alerts). Native npm scripts and
 * Docker Compose profiles are documented in `monitoring/README.md`.
 *
 * ## Public surface
 * - `isOpenAtLogin` — exported API; see TSDoc on the symbol for behavior.
 * - `setOpenAtLogin` — exported API; see TSDoc on the symbol for behavior.
 * - `toggleOpenAtLogin` — exported API; see TSDoc on the symbol for behavior.
 * - `launchedAtLogin` — exported API; see TSDoc on the symbol for behavior.
 *
 * ## Testing pointers
 * - Prefer colocated `__tests__` with Vitest + Testing Library for UI.
 * - Server contract changes require `npm run test:server` and OpenAPI sync.
 * - MCP edits: `npm run mcp:typecheck` and `npm run mcp:build`.
 *
 * ## Related docs
 * - `ARCHITECTURE.md` — hooks → API → SQLite → WebSocket → UI pipeline.
 * - `docs/API.md` — REST reference.
 * - `.claude/skills/file-headers/` — mandatory `@author` header policy.
 * ============================================================================= */
/* -----------------------------------------------------------------------------
 * EXPORT CATALOG — quick index of symbols defined below (documentation only).
 * -----------------------------------------------------------------------------
 * **isOpenAtLogin**
 *   Part of this module's public contract. Downstream imports should treat
 *   the signature and return type as stable unless release notes say otherwise.
 *   When behavior changes, update the `@file` overview and relevant tests.
 *
 * **setOpenAtLogin**
 *   Part of this module's public contract. Downstream imports should treat
 *   the signature and return type as stable unless release notes say otherwise.
 *   When behavior changes, update the `@file` overview and relevant tests.
 *
 * **toggleOpenAtLogin**
 *   Part of this module's public contract. Downstream imports should treat
 *   the signature and return type as stable unless release notes say otherwise.
 *   When behavior changes, update the `@file` overview and relevant tests.
 *
 * **launchedAtLogin**
 *   Part of this module's public contract. Downstream imports should treat
 *   the signature and return type as stable unless release notes say otherwise.
 *   When behavior changes, update the `@file` overview and relevant tests.
 *
 * ----------------------------------------------------------------------------- */

import { app } from "electron";

/**
 * CLI flag we register the Windows startup entry with, then look for in
 * `process.argv` to recognise a login-triggered launch (Windows has no
 * `wasOpenedAtLogin`). Harmless if it ever reaches another code path.
 */
const WIN_LAUNCH_FLAG = "--ccam-hidden";

/** True on macOS and Windows — the only platforms Electron can register an
 * auto-start entry for. Every exported function below is a no-op on Linux. */
function supported(): boolean {
  return process.platform === "darwin" || process.platform === "win32";
}

/**
 * Read the current auto-start state directly from the OS (macOS Login Items
 * or the Windows `Run` key), not from any value cached by this module — so it
 * stays correct even if the user disables the entry from outside the app
 * (e.g. macOS System Settings, or Windows Task Manager → Startup).
 */
export function isOpenAtLogin(): boolean {
  if (!supported()) return false;
  return app.getLoginItemSettings().openAtLogin;
}

/**
 * Enable or disable launching the app at login. Delegates entirely to
 * `app.setLoginItemSettings`, which picks the platform mechanism:
 *   - **Windows** — writes/removes the per-user
 *     `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` entry, tagged with
 *     `WIN_LAUNCH_FLAG` so a subsequent launch can be recognised as
 *     login-triggered (see `launchedAtLogin`).
 *   - **macOS** — registers via the modern `SMAppService` API and starts the
 *     app hidden (see the `openAsHidden` comment below).
 * No-op on Linux, where Electron has no supported mechanism.
 */
export function setOpenAtLogin(enabled: boolean): void {
  if (!supported()) return;
  if (process.platform === "win32") {
    app.setLoginItemSettings({
      openAtLogin: enabled,
      // Tag the registry Run entry so launchedAtLogin() can tell a login-time
      // start apart from the user double-clicking the app.
      args: [WIN_LAUNCH_FLAG],
    });
    return;
  }
  app.setLoginItemSettings({
    openAtLogin: enabled,
    // Start hidden — the user just logged in, they didn't ask for a window
    // to appear. The tray icon makes the app's presence obvious. (macOS only;
    // `openAsHidden` is ignored on other platforms.)
    openAsHidden: true,
  });
}

/**
 * Flip the auto-start setting and return the new state. Used by both the
 * tray "Open at Login" checkbox and the application menu item — each reads
 * `isOpenAtLogin()` to render its own checked state, then calls this on click.
 */
export function toggleOpenAtLogin(): boolean {
  const next = !isOpenAtLogin();
  setOpenAtLogin(next);
  return next;
}

/**
 * Returns true if the current process was launched at login (as opposed to the
 * user double-clicking the app). When true, we keep the window hidden and only
 * show the tray icon.
 *
 * macOS reports this directly via `wasOpenedAtLogin`. Windows has no such flag,
 * so we detect the marker argument we registered the startup entry with.
 */
export function launchedAtLogin(): boolean {
  if (process.platform === "darwin") {
    return app.getLoginItemSettings().wasOpenedAtLogin;
  }
  if (process.platform === "win32") {
    return process.argv.includes(WIN_LAUNCH_FLAG);
  }
  return false;
}
