export interface LinuxScreenShareAudioRoutingInfo {
  available: boolean;
  active: boolean;
  monitorCaptureSupported: boolean;
  screenShareSinkName: string;
  screenShareMonitorSourceName: string;
  voiceSinkName: string;
  reason?: string;
}

export interface LinuxScreenShareMonitorCaptureInfo {
  bitsPerSample: number;
  captureId: string;
  channelCount: number;
  sampleRate: number;
  sourceName: string;
}

export interface LinuxScreenShareMonitorAudioChunkPayload {
  captureId: string;
  chunk: Uint8Array;
}

export interface LinuxScreenShareMonitorAudioEndedPayload {
  captureId: string;
  reason?: string;
}

export interface ClipboardFilePayload {
  data: string;
  lastModified: number;
  mime: string;
  name: string;
  path?: string;
}

export type AutoUpdateMode = 'auto' | 'off' | 'version';

export type DesktopUpdateStatus =
  | 'idle'
  | 'disabled'
  | 'checking'
  | 'downloading'
  | 'up-to-date'
  | 'restart-required'
  | 'unsupported'
  | 'no-manifest'
  | 'target-unavailable'
  | 'target-older-than-installed'
  | 'error';

export type DesktopUpdateServerVersionStatus = 'unknown' | 'reported' | 'missing' | 'unavailable';

export interface DesktopUpdateServerContext {
  manifestUrls: string[];
  serverVersion: string | null;
  serverVersionStatus: DesktopUpdateServerVersionStatus;
}

export interface DesktopUpdateServerHealthSnapshot {
  manifestUrl: string | null;
  serverVersion: string | null;
  serverVersionStatus: DesktopUpdateServerVersionStatus;
}

export interface DesktopUpdateState {
  autoUpdateMode: AutoUpdateMode;
  availableVersions: string[];
  configuredManifestUrls: string[];
  currentVersion: string;
  defaultManifestUrls: string[];
  isSupported: boolean;
  lastCheckedAt: number | null;
  latestVersion: string | null;
  manifestUrl: string | null;
  manifestUrls: string[];
  minimumServerVersion: string | null;
  preferredVersion: string | null;
  restartRequired: boolean;
  serverBlocked: boolean;
  serverBlockMessage: string | null;
  serverVersion: string | null;
  serverVersionStatus: DesktopUpdateServerVersionStatus;
  status: DesktopUpdateStatus;
  statusMessage: string | null;
  targetVersion: string | null;
}

export interface DesktopSettingsSnapshot {
  autoUpdateMode: AutoUpdateMode;
  autoStart: boolean;
  closeToTray: boolean;
  hardwareAcceleration: boolean;
  localApi: LocalApiSettings;
  manifestUrls: string[];
  preferredVersion: string | null;
  runtimeHardwareAcceleration: boolean;
  restartRequired: boolean;
  vaapiVideoEncode: boolean;
}

export interface DesktopSettingsPatch {
  autoUpdateMode?: AutoUpdateMode;
  autoStart?: boolean;
  closeToTray?: boolean;
  hardwareAcceleration?: boolean;
  localApi?: Partial<LocalApiSettings>;
  manifestUrls?: string[];
  preferredVersion?: string | null;
  vaapiVideoEncode?: boolean;
}

export interface LocalApiSettings {
  enabled: boolean;
  port: number;
  exposeOnLan: boolean;
  scalarEnabled: boolean;
  docusaurusEnabled: boolean;
  allowedSignalingServers: string[];
}

export type LocalApiStatus = 'stopped' | 'starting' | 'running' | 'error';

export interface LocalApiSnapshot {
  status: LocalApiStatus;
  host: string | null;
  port: number | null;
  baseUrl: string | null;
  error: string | null;
  exposeOnLan: boolean;
  scalarEnabled: boolean;
  docusaurusEnabled: boolean;
}

export interface DesktopNotificationPayload {
  body: string;
  requestAttention: boolean;
  title: string;
}

export interface WindowStateSnapshot {
  isFocused: boolean;
  isMinimized: boolean;
}

export interface SavedThemeFileDescriptor {
  fileName: string;
  modifiedAt: number;
  path: string;
}

export interface LocalPluginManifestDescriptor {
  discoveredAt: number;
  entrypointPath?: string;
  pluginRootUrl: string;
  manifest: unknown;
  manifestPath: string;
  pluginRoot: string;
  readmePath?: string;
}

export interface LocalPluginDiscoveryError {
  manifestPath?: string;
  message: string;
  pluginRoot?: string;
}

export interface LocalPluginDiscoveryResult {
  errors: LocalPluginDiscoveryError[];
  plugins: LocalPluginManifestDescriptor[];
  pluginsPath: string;
}

export interface ExportUserDataResult {
  cancelled: boolean;
  exported: boolean;
  filePath?: string;
}

export interface ImportUserDataResult {
  backupPath?: string;
  cancelled: boolean;
  imported: boolean;
  restartRequired: boolean;
}

export interface EraseUserDataResult {
  erased: boolean;
  restartRequired: boolean;
}

export interface ElectronCommand {
  type: string;
  payload: unknown;
}

export interface ElectronQuery {
  type: string;
  payload: unknown;
}

export interface ContextMenuParams {
  posX: number;
  posY: number;
  isEditable: boolean;
  selectionText: string;
  linkURL: string;
  mediaType: string;
  srcURL: string;
  editFlags: {
    canCut: boolean;
    canCopy: boolean;
    canPaste: boolean;
    canSelectAll: boolean;
  };
}

export interface ActiveGameCandidate {
  processName: string;
  rawProcessName: string;
  executablePath?: string;
  windowTitle?: string;
  pid?: number;
  isFullscreen: boolean;
  bounds?: { width: number; height: number };
  confidence: number;
  source: 'foreground' | 'process-scan';
  reasons: string[];
}

export interface ActiveGameCandidateResult {
  candidate: ActiveGameCandidate | null;
  fallbackProcessNames: string[];
}

export interface ElectronAppMetricsProcess {
  pid: number;
  type: string;
  workingSetKb: number | null;
}

export interface ElectronAppMetricsSnapshot {
  collectedAt: number;
  processes: ElectronAppMetricsProcess[];
}

export interface ElectronPerfDiagEntry {
  collectedAt: number;
  source: 'main' | 'renderer';
  type: string;
  payload: Record<string, unknown>;
}

export interface ElectronApi {
  linuxDisplayServer: string;
  minimizeWindow: () => void;
  maximizeWindow: () => void;
  closeWindow: () => void;
  openExternal: (url: string) => Promise<boolean>;
  getSources: () => Promise<{ id: string; name: string; thumbnail: string }[]>;
  getRunningProcessNames: () => Promise<string[]>;
  getActiveGameCandidate?: () => Promise<ActiveGameCandidateResult>;
  getIgnoredGameProcesses?: () => Promise<string[]>;
  setIgnoredGameProcesses?: (list: string[]) => Promise<string[]>;
  prepareLinuxScreenShareAudioRouting: () => Promise<LinuxScreenShareAudioRoutingInfo>;
  activateLinuxScreenShareAudioRouting: () => Promise<LinuxScreenShareAudioRoutingInfo>;
  deactivateLinuxScreenShareAudioRouting: () => Promise<boolean>;
  startLinuxScreenShareMonitorCapture: () => Promise<LinuxScreenShareMonitorCaptureInfo>;
  stopLinuxScreenShareMonitorCapture: (captureId?: string) => Promise<boolean>;
  onLinuxScreenShareMonitorAudioChunk: (listener: (payload: LinuxScreenShareMonitorAudioChunkPayload) => void) => () => void;
  onLinuxScreenShareMonitorAudioEnded: (listener: (payload: LinuxScreenShareMonitorAudioEndedPayload) => void) => () => void;
  getAppMetrics: () => Promise<ElectronAppMetricsSnapshot>;
  isPerfDiagEnabled?: () => Promise<boolean>;
  reportPerfDiagSample?: (entry: ElectronPerfDiagEntry) => Promise<boolean>;
  getAppDataPath: () => Promise<string>;
  openCurrentDataFolder: () => Promise<boolean>;
  exportUserData: () => Promise<ExportUserDataResult>;
  importUserData: () => Promise<ImportUserDataResult>;
  eraseUserData: () => Promise<EraseUserDataResult>;
  getSavedThemesPath: () => Promise<string>;
  getLocalPluginsPath: () => Promise<string>;
  listLocalPluginManifests: () => Promise<LocalPluginDiscoveryResult>;
  listSavedThemes: () => Promise<SavedThemeFileDescriptor[]>;
  readSavedTheme: (fileName: string) => Promise<string>;
  writeSavedTheme: (fileName: string, text: string) => Promise<boolean>;
  deleteSavedTheme: (fileName: string) => Promise<boolean>;
  consumePendingDeepLink: () => Promise<string | null>;
  getDesktopSettings: () => Promise<DesktopSettingsSnapshot>;
  showDesktopNotification: (payload: DesktopNotificationPayload) => Promise<boolean>;
  requestWindowAttention: () => Promise<boolean>;
  clearWindowAttention: () => Promise<boolean>;
  onWindowStateChanged: (listener: (state: WindowStateSnapshot) => void) => () => void;
  getAutoUpdateState: () => Promise<DesktopUpdateState>;
  getAutoUpdateServerHealth: (serverUrl: string) => Promise<DesktopUpdateServerHealthSnapshot>;
  configureAutoUpdateContext: (context: Partial<DesktopUpdateServerContext>) => Promise<DesktopUpdateState>;
  checkForAppUpdates: () => Promise<DesktopUpdateState>;
  restartToApplyUpdate: () => Promise<boolean>;
  onAutoUpdateStateChanged: (listener: (state: DesktopUpdateState) => void) => () => void;
  setDesktopSettings: (patch: DesktopSettingsPatch) => Promise<DesktopSettingsSnapshot>;
  getLocalApiStatus: () => Promise<LocalApiSnapshot>;
  openLocalApiDocs: () => Promise<{ opened: boolean; reason?: string }>;
  openDocusaurusDocs: () => Promise<{ opened: boolean; reason?: string }>;
  relaunchApp: () => Promise<boolean>;
  onDeepLinkReceived: (listener: (url: string) => void) => () => void;
  readClipboardFiles: () => Promise<ClipboardFilePayload[]>;
  readFile: (filePath: string) => Promise<string | null>;
  readFileChunk: (filePath: string, start: number, end: number) => Promise<string | null>;
  getFileSize: (filePath: string) => Promise<number | null>;
  grantPluginReadRoot?: (rootPath: string) => Promise<boolean>;
  writeFile: (filePath: string, data: string) => Promise<boolean>;
  appendFile: (filePath: string, data: string) => Promise<boolean>;
  saveFileAs: (defaultFileName: string, data: string) => Promise<{ saved: boolean; cancelled: boolean }>;
  saveExistingFileAs?: (sourceFilePath: string, defaultFileName: string) => Promise<{ saved: boolean; cancelled: boolean }>;
  openFilePath?: (filePath: string) => Promise<{ opened: boolean; reason?: string }>;
  copyFile: (sourceFilePath: string, destinationFilePath: string) => Promise<boolean>;
  getPathForFile: (file: File) => string;
  fileExists: (filePath: string) => Promise<boolean>;
  getFileUrl: (filePath: string) => Promise<string | null>;
  deleteFile: (filePath: string) => Promise<boolean>;
  ensureDir: (dirPath: string) => Promise<boolean>;
  onContextMenu: (listener: (params: ContextMenuParams) => void) => () => void;
  contextMenuCommand: (command: string) => Promise<void>;
  copyImageToClipboard: (srcURL: string) => Promise<boolean>;
  command: <T = unknown>(command: ElectronCommand) => Promise<T>;
  query: <T = unknown>(query: ElectronQuery) => Promise<T>;
  storeProvisionSecret?: (homeUserId: string, secret: string) => Promise<boolean>;
  getProvisionSecret?: (homeUserId: string) => Promise<string | null>;
}

export type ElectronWindow = Window & {
  electronAPI?: ElectronApi;
};
