// Renderer-visible typing for the preload bridge. Referenced via tsconfig
// `include` so TS sees `window.electronAPI` without needing to import
// from `electron` or drag Node types into the renderer build. The
// ElectronAPI type mirrors the `api` object exported from preload.ts —
// keep them in sync when adding new methods.

import type {
  AudioLoopbackChunk,
  AudioLoopbackStartResult,
  FsPath,
  FsRenameArgs,
  FsWriteArgs,
  NotifyArgs,
  ScreenSource,
  SecureStoreHandle,
  SecureStoreOpenArgs,
  ShortcutEvent,
  ShortcutRegisterArgs,
  SqlExecuteResult,
  SqlSelectResult,
  UpdateCheckResult,
  UpdateProgress,
} from './ipc-types';

type Unsubscribe = () => void;

export interface ElectronAPI {
  /** Opaque runtime marker (value: 'electron-chatapp-v1'). */
  platform: string;
  osPlatform: NodeJS.Platform;
  appVersion: string;

  getScreenSources: () => Promise<ScreenSource[]>;
  getScreenThumbnail: (sourceId: string) => Promise<string | null>;
  setPendingShareSource: (sourceId: string | null) => Promise<void>;

  resolveLoopbackSource: () => Promise<{ sourceId: string } | null>;

  /** Native WASAPI process-loopback bridge — Windows only. `start`
   *  rejects on macOS/Linux or when the .node binary isn't shipped, so
   *  callers should catch and fall back to the getUserMedia path. */
  audioLoopback: {
    start: () => Promise<AudioLoopbackStartResult>;
    /** Window-share variant: capture only the picked window's process
     *  tree (INCLUDE_TARGET_PROCESS_TREE). hwnd is the decimal HWND
     *  parsed from desktopCapturer's `window:<HWND>:0` source id. */
    startForWindow: (hwnd: number) => Promise<AudioLoopbackStartResult>;
    stop: (captureId: number) => Promise<void>;
    onChunk: (cb: (payload: AudioLoopbackChunk) => void) => Unsubscribe;
  };

  registerShortcut: (args: ShortcutRegisterArgs) => Promise<boolean>;
  unregisterShortcut: (id: string) => Promise<void>;
  isShortcutRegistered: (id: string) => Promise<boolean>;
  onShortcutFired: (cb: (evt: ShortcutEvent) => void) => Unsubscribe;
  onShortcutReleased: (cb: (evt: ShortcutEvent) => void) => Unsubscribe;

  notify: (args: NotifyArgs) => Promise<void>;
  getNotificationPermission: () => Promise<'granted' | 'denied' | 'default'>;

  setTrayUnread: (count: number, badgeDataUrl?: string | null) => Promise<void>;

  secureStoreOpen: (args: SecureStoreOpenArgs) => Promise<SecureStoreHandle>;
  secureStoreGet: (handle: string, key: string) => Promise<string | null>;
  secureStoreSet: (handle: string, key: string, value: string) => Promise<void>;
  secureStoreRemove: (handle: string, key: string) => Promise<void>;
  secureStoreClose: (handle: string) => Promise<void>;

  fsRead: (p: FsPath) => Promise<string | null>;
  fsWrite: (args: FsWriteArgs) => Promise<void>;
  fsExists: (p: FsPath) => Promise<boolean>;
  fsMkdir: (p: FsPath) => Promise<void>;
  fsRename: (args: FsRenameArgs) => Promise<void>;
  fsRemove: (p: FsPath) => Promise<void>;
  fsAppLocalDataDir: () => Promise<string>;

  sqlLoad: (args: { name: string }) => Promise<string>;
  sqlExecute: (args: {
    handle: string;
    query: string;
    bindings?: unknown[];
  }) => Promise<SqlExecuteResult>;
  sqlSelect: (args: {
    handle: string;
    query: string;
    bindings?: unknown[];
  }) => Promise<SqlSelectResult>;
  sqlClose: (handle: string) => Promise<void>;

  checkForUpdate: () => Promise<UpdateCheckResult>;
  downloadInstallUpdate: () => Promise<void>;
  onUpdaterProgress: (cb: (p: UpdateProgress) => void) => Unsubscribe;

  isAutoStartEnabled: () => Promise<boolean>;
  setAutoStart: (enabled: boolean) => Promise<void>;

  setFullscreen: (enabled: boolean) => Promise<void>;
}

declare global {
  interface Window {
    electronAPI: ElectronAPI;
  }
}

export {};
