import { contextBridge, ipcRenderer, webUtils } from "electron";
import { IPC_CHANNELS } from "../shared/ipc-channels";

const beatos = {
  getApiBase: (): Promise<string> => ipcRenderer.invoke(IPC_CHANNELS.GET_API_BASE),
  openFolderDialog: (): Promise<string | null> =>
    ipcRenderer.invoke(IPC_CHANNELS.DIALOG_OPEN_FOLDER),
  openFileDialog: (filters: { name: string; extensions: string[] }[]): Promise<string | null> =>
    ipcRenderer.invoke(IPC_CHANNELS.DIALOG_OPEN_FILE, filters),
  revealInFinder: (path: string): Promise<void> =>
    ipcRenderer.invoke(IPC_CHANNELS.SHELL_REVEAL_IN_FINDER, path),
  /** Open a folder (or file) with the OS default handler. Resolves to "" on
   *  success or a non-empty error string on failure (electron shell.openPath). */
  openPath: (path: string): Promise<string> =>
    ipcRenderer.invoke(IPC_CHANNELS.SHELL_OPEN_PATH, path),
  openExternal: (url: string): Promise<void> =>
    ipcRenderer.invoke(IPC_CHANNELS.SHELL_OPEN_EXTERNAL, url),
  quitApp: (): Promise<void> => ipcRenderer.invoke(IPC_CHANNELS.APP_QUIT),
  getHomePath: (): Promise<string> => ipcRenderer.invoke(IPC_CHANNELS.PATH_HOME),
  ensureDir: (dir: string): Promise<string> =>
    ipcRenderer.invoke(IPC_CHANNELS.PATH_ENSURE_DIR, dir),
  getDbPath: (): Promise<string> => ipcRenderer.invoke(IPC_CHANNELS.STORAGE_GET_DB_PATH),
  getRepoRoot: (): Promise<string> => ipcRenderer.invoke(IPC_CHANNELS.STORAGE_GET_REPO_ROOT),
  setDbPath: (p: string): Promise<{ restartRequired: boolean }> =>
    ipcRenderer.invoke(IPC_CHANNELS.STORAGE_SET_DB_PATH, p),
  pickFolder: (): Promise<string | null> => ipcRenderer.invoke(IPC_CHANNELS.STORAGE_PICK_FOLDER),
  testMcpConnection: (): Promise<
    { ok: true; toolsCount: number; version: string } | { ok: false; error: string }
  > => ipcRenderer.invoke(IPC_CHANNELS.MCP_TEST_CONNECTION),
  onSidecarCrashed: (
    cb: (info: { code: number | null; signal: string | null }) => void,
  ): (() => void) => {
    const handler = (
      _e: Electron.IpcRendererEvent,
      info: { code: number | null; signal: string | null },
    ) => cb(info);
    ipcRenderer.on(IPC_CHANNELS.SIDECAR_CRASHED, handler);
    return () => ipcRenderer.removeListener(IPC_CHANNELS.SIDECAR_CRASHED, handler);
  },
  startDragFile: (absPath: string): void => {
    ipcRenderer.send(IPC_CHANNELS.DRAG_OUT_FILE, { absPath });
  },
  /** Returns the absolute filesystem path for a File from a drop / file input. */
  getPathForFile: (file: File): string => webUtils.getPathForFile(file),
  /** Test harness signal: when BEATOS_AUDIO_MUTED=1 is set in the main env,
   *  smoke / diagnose runs against a real audio file without producing sound.
   *  Renderer uses this to force `audio.muted = true` on every audio element. */
  isAudioForceMuted: (): boolean => process.env.BEATOS_AUDIO_MUTED === "1",
};

contextBridge.exposeInMainWorld("beatos", beatos);

export type BeatosAPI = typeof beatos;
