import type {
  CaptureOptions,
  CaptureResult,
  CaptureSourceInfo,
  ArtifactStoreLoadResult,
  ArtifactStoreSaveResult,
  BooleanResult,
  ReviewSampleListResult,
  ReviewSamplePayload,
  SaveResultWithPath,
  FocusGenshinResult,
  LoadScannerLearningRulesResult,
  ScrollResult,
  RuntimeInfo,
  SaveScannerLearningRulesResult,
  SaveSnapshotResult,
  GoodDatabase,
  ScannerStatusPayload,
  ScannerLearningRulePayload,
} 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>;
  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>;
  focusMainWindow: () => Promise<BooleanResult>;
  focusGenshin: () => Promise<FocusGenshinResult>;
  clickScreen: (x: number, y: number) => Promise<ClickResult>;
  scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => Promise<ScrollResult>;
  onScannerCommand: (callback: (command: "start-auto" | "stop") => 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 canAutoScan = hasFunction(apiRecord, "clickScreen") && hasFunction(apiRecord, "scrollScreen");
  const canReviewSamples = hasFunction(apiRecord, "loadReviewSamples") && hasFunction(apiRecord, "saveReviewSample");

  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),
    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),
    focusMainWindow: () => api.focusMainWindow(),
    focusGenshin: () => api.focusGenshin(),
    clickScreen: (x: number, y: number) => api.clickScreen(x, y),
    scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => api.scrollScreen(notches, anchorX, anchorY),
    showOverlay: () => api.showOverlay(),
    onScannerCommand: (callback) => api.onScannerCommand(callback),
  };
}
