import type {
  CaptureOptions,
  CaptureResult,
  CaptureSourceInfo,
  ArtifactStoreLoadResult,
  ArtifactStoreSaveResult,
  BooleanResult,
  ReviewSampleListResult,
  ReviewSamplePayload,
  SaveResultWithPath,
  FocusGenshinResult,
  LoadScannerLearningRulesResult,
  ScrollResult,
  RuntimeInfo,
  SaveScannerLearningRulesResult,
  SaveSnapshotResult,
  GoodDatabase,
  GoodImportFileResult,
  NativeScannerCatalogStatus,
  NativeScannerDataStatus,
  NativeScannerImageLoadStatus,
  NativeScannerPreflightStatus,
  NativeScannerProcessStatus,
  NativeScannerPromotionStatus,
  NativeScannerReviewArtifactInput,
  NativeScannerReviewStatus,
  NativeScannerResultsLoadStatus,
  NativeScannerRunStatus,
  NativeScannerStartCategory,
  ScannerCommand,
  ScannerStatusPayload,
  ScannerLearningRulePayload,
  KeyPressResult,
} from "../types/global";
import type { AppSnapshot } from "../types/domain";
import type { StoredArtifactRecord } from "../types/storage";
import type { AutomationGuard, ClickResult } from "../types/global";

export interface AssistantBridge {
  isAvailable: boolean;
  canExportGood: boolean;
  canShowOverlay: boolean;
  canAutoScan: boolean;
  canReviewSamples: boolean;
  loadSnapshot: () => Promise<AppSnapshot | null>;
  saveSnapshot: (snapshot: AppSnapshot) => Promise<SaveSnapshotResult>;
  runMockScan: () => Promise<AppSnapshot | null>;
  listCaptureSources: () => Promise<CaptureSourceInfo[]>;
  captureSource: (
    sourceId: string,
    delayMs?: number,
    focusGenshin?: boolean,
    options?: CaptureOptions,
  ) => Promise<CaptureResult>;
  exportGood: (payload: GoodDatabase) => Promise<SaveResultWithPath>;
  importGoodFile: () => Promise<GoodImportFileResult>;
  showOverlay: () => Promise<BooleanResult>;
  loadArtifacts: () => Promise<ArtifactStoreLoadResult>;
  saveArtifacts: (records: StoredArtifactRecord[]) => Promise<ArtifactStoreSaveResult>;
  loadReviewSamples: (limit?: number) => Promise<ReviewSampleListResult>;
  saveReviewSample: (sample: ReviewSamplePayload) => Promise<SaveResultWithPath>;
  loadScannerLearningRules: () => Promise<LoadScannerLearningRulesResult>;
  saveScannerLearningRules: (rules: ScannerLearningRulePayload) => Promise<SaveScannerLearningRulesResult>;
  getRuntimeInfo: () => Promise<RuntimeInfo>;
  getAutomationGuard: () => Promise<AutomationGuard>;
  publishScannerStatus: (status: ScannerStatusPayload) => Promise<BooleanResult>;
  nativeScannerDataStatus: () => Promise<NativeScannerDataStatus>;
  nativeScannerCatalog: () => Promise<NativeScannerCatalogStatus>;
  nativeScannerPreflight: (options?: { category?: NativeScannerStartCategory }) => 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>;
  focusMainWindow: () => Promise<BooleanResult>;
  focusGenshin: () => Promise<FocusGenshinResult>;
  focusGenshinForScanStart: () => Promise<FocusGenshinResult>;
  clickScreen: (x: number, y: number) => Promise<ClickResult>;
  scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => Promise<ScrollResult>;
  keyPress: (key: string) => Promise<KeyPressResult>;
  onScannerCommand: (callback: (command: ScannerCommand) => void) => () => void;
}

function hasFunction(api: Record<string, unknown>, key: string): boolean {
  return typeof api[key] === "function";
}

export function getAssistantBridge(): AssistantBridge | null {
  const api = window.assistantApi;
  if (!api) return null;
  const apiRecord = api as unknown as Record<string, unknown>;
  const hasNativeScanner = hasFunction(apiRecord, "nativeScannerStart") && hasFunction(apiRecord, "nativeScannerStatus") && hasFunction(apiRecord, "nativeScannerStop");
  const canAutoScan = hasNativeScanner || (hasFunction(apiRecord, "clickScreen") && hasFunction(apiRecord, "scrollScreen"));
  const canReviewSamples = hasFunction(apiRecord, "loadReviewSamples") && hasFunction(apiRecord, "saveReviewSample");
  const hasFocusGenshinForScanStart = hasFunction(apiRecord, "focusGenshinForScanStart");

  return {
    isAvailable: true,
    canExportGood: Boolean(api.exportGood),
    canShowOverlay: Boolean(api.showOverlay),
    canAutoScan,
    canReviewSamples,
    loadSnapshot: () => api.loadSnapshot(),
    saveSnapshot: (snapshot: AppSnapshot) => api.saveSnapshot(snapshot),
    runMockScan: () => api.runMockScan(),
    listCaptureSources: () => api.listCaptureSources(),
    captureSource: (sourceId, delayMs, focusGenshin, options) => api.captureSource(sourceId, delayMs, focusGenshin, options),
    exportGood: (payload) => api.exportGood(payload),
    importGoodFile: () => api.importGoodFile(),
    loadArtifacts: () => api.loadArtifacts(),
    saveArtifacts: (records) => api.saveArtifacts(records),
    loadReviewSamples: (limit = 50) => api.loadReviewSamples(limit),
    saveReviewSample: (sample) => api.saveReviewSample(sample),
    loadScannerLearningRules: () => api.loadScannerLearningRules(),
    saveScannerLearningRules: (rules) => api.saveScannerLearningRules(rules),
    getRuntimeInfo: () => api.getRuntimeInfo(),
    getAutomationGuard: () => api.getAutomationGuard(),
    publishScannerStatus: (status) => api.publishScannerStatus(status),
    nativeScannerDataStatus: () => api.nativeScannerDataStatus(),
    nativeScannerCatalog: () => api.nativeScannerCatalog(),
    nativeScannerPreflight: (options) => api.nativeScannerPreflight(options),
    nativeScannerStart: (options) => api.nativeScannerStart(options),
    nativeScannerStop: () => api.nativeScannerStop(),
    nativeScannerStatus: () => api.nativeScannerStatus(),
    nativeScannerProcessRun: (options) => api.nativeScannerProcessRun(options),
    nativeScannerLoadResults: (options) => api.nativeScannerLoadResults(options),
    nativeScannerPromoteResults: (options) => api.nativeScannerPromoteResults(options),
    nativeScannerReviewResult: (options) => api.nativeScannerReviewResult(options),
    nativeScannerLoadImage: (options) => api.nativeScannerLoadImage(options),
    focusMainWindow: () => api.focusMainWindow(),
    focusGenshin: () => api.focusGenshin(),
    focusGenshinForScanStart: () => (hasFocusGenshinForScanStart ? api.focusGenshinForScanStart() : api.focusGenshin()),
    clickScreen: (x: number, y: number) => api.clickScreen(x, y),
    scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => api.scrollScreen(notches, anchorX, anchorY),
    keyPress: (key: string) => api.keyPress(key),
    showOverlay: () => api.showOverlay(),
    onScannerCommand: (callback) => api.onScannerCommand(callback),
  };
}
