import { ipcMain } from "electron";
import type {
  BooleanResult,
  FocusGenshinResult,
  NativeScannerCatalogStatus,
  NativeScannerDataStatus,
  NativeScannerImageLoadStatus,
  NativeScannerPreflightStatus,
  NativeScannerProcessStatus,
  NativeScannerPromotionStatus,
  NativeScannerReviewArtifactInput,
  NativeScannerReviewStatus,
  NativeScannerResultsLoadStatus,
  NativeScannerRunStatus,
  NativeScannerStartCategory,
  RuntimeInfo,
  SaveSnapshotResult,
  ScannerStatusPayload,
} from "../../src/types/global.js";
import type { AppSnapshot } from "../../src/types/domain.js";

interface AppCommandDependencies {
  focusMainWindow: () => BooleanResult;
  moveMainWindowOffGenshin: () => Promise<void>;
  focusGenshinForScanStart: () => Promise<FocusGenshinResult>;
  publishScannerStatus: (status: ScannerStatusPayload) => Promise<BooleanResult>;
  nativeScannerDataStatus: () => Promise<NativeScannerDataStatus>;
  nativeScannerCatalog: () => Promise<NativeScannerCatalogStatus>;
  nativeScannerPreflight: (options?: { category?: NativeScannerStartCategory | string }) => Promise<NativeScannerPreflightStatus>;
  nativeScannerStart: (options?: { limit?: number; category?: NativeScannerStartCategory }) => Promise<NativeScannerRunStatus>;
  nativeScannerStop: () => Promise<NativeScannerRunStatus>;
  nativeScannerStatus: () => Promise<NativeScannerRunStatus>;
  nativeScannerProcessRun: (options?: { runDir?: string; persist?: boolean; limit?: number }) => Promise<NativeScannerProcessStatus>;
  nativeScannerLoadResults: (options?: { runDir?: string; limit?: number }) => Promise<NativeScannerResultsLoadStatus>;
  nativeScannerPromoteResults: (options: { runDir?: string; resultIds: string[] }) => Promise<NativeScannerPromotionStatus>;
  nativeScannerReviewResult: (options: { runDir?: string; resultId: string; action: "approve" | "reject"; artifact?: NativeScannerReviewArtifactInput; note?: string }) => Promise<NativeScannerReviewStatus>;
  nativeScannerLoadImage: (options: { runDir?: string; imagePath: string }) => Promise<NativeScannerImageLoadStatus>;
  getRuntimeInfo: () => Promise<RuntimeInfo>;
  loadSnapshot: () => Promise<AppSnapshot | null>;
  saveSnapshot: (snapshot: AppSnapshot) => Promise<SaveSnapshotResult>;
  runMockScan: () => Promise<AppSnapshot | null>;
  showOverlay: () => Promise<BooleanResult>;
  hideOverlay: () => Promise<BooleanResult>;
}

export function registerAppHandlers({
  focusMainWindow,
  moveMainWindowOffGenshin,
  focusGenshinForScanStart,
  publishScannerStatus,
  nativeScannerDataStatus,
  nativeScannerCatalog,
  nativeScannerPreflight,
  nativeScannerStart,
  nativeScannerStop,
  nativeScannerStatus,
  nativeScannerProcessRun,
  nativeScannerLoadResults,
  nativeScannerPromoteResults,
  nativeScannerReviewResult,
  nativeScannerLoadImage,
  getRuntimeInfo,
  loadSnapshot,
  saveSnapshot,
  runMockScan,
  showOverlay,
  hideOverlay,
}: AppCommandDependencies) {
  ipcMain.handle("app:focusMainWindow", async () => focusMainWindow());
  ipcMain.handle("automation:focusGenshin", async () => {
    await moveMainWindowOffGenshin();
    return focusGenshinForScanStart();
  });
  ipcMain.handle("scanner:publishStatus", async (_event, status: ScannerStatusPayload) => {
    await publishScannerStatus(status);
    return { ok: true };
  });
  ipcMain.handle("scanner:nativeDataStatus", async () => nativeScannerDataStatus());
  ipcMain.handle("scanner:nativeCatalog", async () => nativeScannerCatalog());
  ipcMain.handle("scanner:nativePreflight", async (_event, options?: { category?: NativeScannerStartCategory | string }) => nativeScannerPreflight(options));
  ipcMain.handle("scanner:nativeStart", async (_event, options?: { limit?: number; category?: NativeScannerStartCategory }) => nativeScannerStart(options));
  ipcMain.handle("scanner:nativeStop", async () => nativeScannerStop());
  ipcMain.handle("scanner:nativeStatus", async () => nativeScannerStatus());
  ipcMain.handle("scanner:nativeProcessRun", async (_event, options?: { runDir?: string; persist?: boolean; limit?: number }) => nativeScannerProcessRun(options));
  ipcMain.handle("scanner:nativeLoadResults", async (_event, options?: { runDir?: string; limit?: number }) => nativeScannerLoadResults(options));
  ipcMain.handle("scanner:nativePromoteResults", async (_event, options: { runDir?: string; resultIds: string[] }) => nativeScannerPromoteResults(options));
  ipcMain.handle("scanner:nativeReviewResult", async (_event, options: { runDir?: string; resultId: string; action: "approve" | "reject"; artifact?: NativeScannerReviewArtifactInput; note?: string }) => nativeScannerReviewResult(options));
  ipcMain.handle("scanner:nativeLoadImage", async (_event, options: { runDir?: string; imagePath: string }) => nativeScannerLoadImage(options));
  ipcMain.handle("app:getRuntimeInfo", async () => getRuntimeInfo());
  ipcMain.handle("snapshot:load", async () => loadSnapshot());
  ipcMain.handle("snapshot:save", async (_event, snapshot: AppSnapshot) => saveSnapshot(snapshot));
  ipcMain.handle("scan:runMock", async () => runMockScan());
  ipcMain.handle("overlay:show", () => showOverlay());
  ipcMain.handle("overlay:hide", () => hideOverlay());
}
