/**
 * mixone IPC contract type definitions (shared by both sides).
 *
 * - Main process: register ipcMain.handle via `registerMixoneIpc()` in main.ts
 * - Preload: inject this API into renderer via `contextBridge.exposeInMainWorld('{{bridgeGlobal}}', ...)`
 * - Renderer (recommended): `import { dialog, fs, clipboard, shell, app } from '#mixone/ipc'`
 *   Types are inferred from this file, IDE jump-to-definition and signature checks are all available.
 *
 * Security principle:
 *   All methods go through ipcRenderer.invoke to main process; renderer has NO Node access.
 *   fs only exposes read + write to user-selected paths (dialog.showSaveFile). No arbitrary path access.
 */

// === Dialog ===
export interface FileFilter {
  name: string
  extensions: string[]
}

export interface OpenFileOptions {
  title?: string
  defaultPath?: string
  /** Select file / Select directory */
  properties?: Array<'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles'>
  filters?: FileFilter[]
}

export interface OpenFileResult {
  /** Empty array when user cancels; string[] when openFile + multiSelections */
  filePaths: string[]
  canceled: boolean
  bookmarks?: string[]
}

export interface SaveFileOptions {
  title?: string
  defaultPath?: string
  filters?: FileFilter[]
}

export interface SaveFileResult {
  filePath: string | null
  canceled: boolean
}

export interface MessageBoxOptions {
  type?: 'none' | 'info' | 'error' | 'question' | 'warning'
  title?: string
  message: string
  detail?: string
  buttons?: string[]
  defaultId?: number
  cancelId?: number
}

export interface MessageBoxResult {
  response: number
  checkboxResponse: boolean
  canceled: boolean
}

export interface MixoneDialogApi {
  openFile: (options?: OpenFileOptions) => Promise<OpenFileResult>
  saveFile: (options?: SaveFileOptions) => Promise<SaveFileResult>
  messageBox: (options: MessageBoxOptions) => Promise<MessageBoxResult>
}

// === FS (restricted: read-only + write to user-selected paths) ===
export interface ReadTextOptions {
  /** default utf-8 */
  encoding?: BufferEncoding
}

export interface ReadTextResult {
  content: string
  /** bytes */
  size: number
}

export interface WriteTextOptions {
  encoding?: BufferEncoding
}

export interface FsStats {
  size: number
  isFile: boolean
  isDirectory: boolean
  mtime: number
}

export interface DirEntry {
  name: string
  isFile: boolean
  isDirectory: boolean
  isSymbolicLink: boolean
}

export interface ReadDirResult {
  entries: DirEntry[]
  error?: string
}

export interface MixoneFsApi {
  /** Read file content */
  readText: (filePath: string, options?: ReadTextOptions) => Promise<ReadTextResult>
  /** Write file (overwrite) */
  writeText: (filePath: string, content: string, options?: WriteTextOptions) => Promise<{ bytesWritten: number }>
  exists: (filePath: string) => Promise<boolean>
  stat: (filePath: string) => Promise<FsStats>
  /** Safely delete file */
  unlinkSafe: (filePath: string) => Promise<{ success: boolean }>
  /** Read directory contents */
  readDir: (dirPath: string) => Promise<ReadDirResult>
  /** Create directory */
  mkdir: (dirPath: string, options?: { recursive?: boolean }) => Promise<{ success: boolean; error?: string }>
  /** Rename / move file */
  rename: (oldPath: string, newPath: string) => Promise<{ success: boolean; error?: string }>
  /** Copy file */
  copyFile: (src: string, dest: string) => Promise<{ success: boolean; error?: string }>
  /** Append text to file */
  appendText: (filePath: string, content: string, options?: WriteTextOptions) => Promise<{ success: boolean; error?: string }>
  /** Read JSON file and parse */
  readJson: (filePath: string) => Promise<{ data: any; error: string | null }>
  /** Write data to JSON file */
  writeJson: (filePath: string, data: any, options?: { space?: number }) => Promise<{ success: boolean; error?: string }>
}

// === Clipboard ===
export interface ClipboardImageInfo {
  empty: boolean
  size: { width: number; height: number } | null
}

export interface MixoneClipboardApi {
  readText: () => Promise<string>
  writeText: (text: string) => Promise<{ success: true }>
  /** Read clipboard HTML content */
  readHtml: () => Promise<string>
  /** Write HTML to clipboard */
  writeHtml: (html: string) => Promise<{ success: true }>
  /** Read clipboard image info (does not transfer image data, only dimensions) */
  readImage: () => Promise<ClipboardImageInfo>
  clear: () => Promise<{ success: true }>
}

// === Shell ===
export interface MixoneShellApi {
  /** Open URL / file path with system default program */
  openExternal: (url: string, options?: { activate?: boolean }) => Promise<{ success: true }>
  /** Show and select file in file manager */
  showItemInFolder: (fullPath: string) => Promise<{ success: true }>
  /** Open local file with system default program, returns error string (empty = success) */
  openPath: (path: string) => Promise<string>
  /** System beep */
  beep: () => Promise<{ success: true }>
}

// === App ===
export interface AppInfoResult {
  name: string
  version: string
  electron: string
  node: string
  chrome: string
  platform: NodeJS.Platform
  /** Main process cwd */
  cwd: string
}

export interface MixoneAppApi {
  info: () => Promise<AppInfoResult>
  relaunch: () => Promise<{ success: true }>
  quit: () => Promise<{ success: true }>
}

// === Bridge ===
export interface MixoneIpcApi {
  platform: NodeJS.Platform
  version: string
  node: string
  chrome: string
  isDesktop: true
  window: import('./window-api').MixoneWindowApi
  dialog: MixoneDialogApi
  fs: MixoneFsApi
  clipboard: MixoneClipboardApi
  shell: MixoneShellApi
  app: MixoneAppApi
}