import { getAssistantBridge } from "../../services/assistantBridge";
import {
  type ArtifactRepositoryPort,
  type AutomationRepositoryPort,
  type CaptureRepositoryPort,
  type RendererRepositories,
  type RuntimeRepositoryPort,
  type ReviewSampleRepositoryPort,
  type LearningRepositoryPort,
  type SnapshotRepositoryPort,
  type OverlayRepositoryPort,
  type ScanExportPort,
} from "./rendererBridgeRepositoryTypes";
import type { AppSnapshot } from "../../types/domain";
import type {
  ArtifactStoreLoadResult,
  ArtifactStoreSaveResult,
  LoadScannerLearningRulesResult,
  BooleanResult,
  CaptureSourceInfo,
  FocusGenshinResult,
  RuntimeInfo,
  SaveResultWithPath,
  ScrollResult,
  KeyPressResult,
  AutomationGuard,
  ClickResult,
  ReviewSampleListResult,
  SaveScannerLearningRulesResult,
  GoodImportFileResult,
  NativeScannerCatalogStatus,
  NativeScannerDataStatus,
  NativeScannerImageLoadStatus,
  NativeScannerPreflightStatus,
  NativeScannerProcessStatus,
  NativeScannerPromotionStatus,
  NativeScannerReviewStatus,
  NativeScannerResultsLoadStatus,
  NativeScannerRunStatus,
} from "../../types/global";

const EMPTY_SNAPSHOT: AppSnapshot | null = null;
const EMPTY_CAPTURE_SOURCE_LIST: CaptureSourceInfo[] = [];
const EMPTY_SAVE_RESULT: SaveResultWithPath = { ok: false, path: "" };
const EMPTY_RUNTIME_INFO: RuntimeInfo = {
  ok: false,
  isElevated: false,
  platform: "unknown",
};
const EMPTY_ARTIFACT_STORE_LOAD_RESULT: ArtifactStoreLoadResult = {
  ok: false,
  artifacts: [],
  total: 0,
  path: "",
};
const EMPTY_ARTIFACT_STORE_SAVE_RESULT: ArtifactStoreSaveResult = {
  ok: false,
  added: 0,
  updated: 0,
  total: 0,
  path: "",
};
const EMPTY_REVIEW_SAMPLES_RESULT: ReviewSampleListResult = {
  ok: false,
  samples: [],
  total: 0,
  path: "",
};
const EMPTY_SCANNER_LEARNING_RULES_RESULT: LoadScannerLearningRulesResult = {
  ok: false,
  path: "",
  rules: {},
};
const EMPTY_SCAN_STATUS_RESULT: SaveResultWithPath = { ok: false, path: "" };
const EMPTY_SAVE_RULES_RESULT: SaveScannerLearningRulesResult = {
  ok: false,
  path: "",
  rules: {},
  total: 0,
};
const EMPTY_GOOD_IMPORT_FILE_RESULT: GoodImportFileResult = {
  ok: false,
  canceled: false,
  path: "",
  error: "Electron bridge unavailable.",
};
const EMPTY_NATIVE_SCANNER_DATA_STATUS: NativeScannerDataStatus = {
  directory: "",
  version: "",
  artifactSets: 0,
  artifactPieces: 0,
  weapons: 0,
  characters: 0,
  materials: 0,
  totalEntries: 0,
  categories: {
    artifacts: {
      file: "artifacts.json",
      setCount: 0,
      pieceCount: 0,
      supported: false,
      catalogAvailable: false,
      nativeCaptureSupported: false,
      scanStatus: "missing_data",
    },
    weapons: {
      file: "weapons.json",
      count: 0,
      supported: false,
      catalogAvailable: false,
      nativeCaptureSupported: false,
      scanStatus: "missing_data",
    },
    characters: {
      file: "characters.json",
      count: 0,
      supported: false,
      catalogAvailable: false,
      nativeCaptureSupported: false,
      scanStatus: "missing_data",
    },
    materials: {
      file: "materials.json",
      count: 0,
      supported: false,
      catalogAvailable: false,
      nativeCaptureSupported: false,
      scanStatus: "missing_data",
    },
  },
  missing: ["Electron bridge unavailable."],
  valid: false,
  source: "InventoryKamera inventorylists",
};
const EMPTY_NATIVE_SCANNER_PREFLIGHT_STATUS: NativeScannerPreflightStatus = {
  data: EMPTY_NATIVE_SCANNER_DATA_STATUS,
  category: "artifacts",
  supportedCategories: EMPTY_NATIVE_SCANNER_DATA_STATUS.categories,
  categoryReady: false,
  genshinFound: false,
  bounds: null,
  isSixteenNine: false,
  grid: { rows: 0, cols: 0, count: 0, anchorX: 0, anchorY: 0 },
  visual: {
    ready: false,
    samples: 0,
    whitePct: 0,
    darkPct: 0,
    colorPct: 0,
    lumaStdDev: 0,
    blockReason: "Electron bridge unavailable.",
  },
  ready: false,
  blockReason: "Electron bridge unavailable.",
};
const EMPTY_NATIVE_SCANNER_CATALOG_STATUS: NativeScannerCatalogStatus = {
  data: EMPTY_NATIVE_SCANNER_DATA_STATUS,
  artifacts: [],
  weapons: [],
  characters: [],
  materials: [],
};
const EMPTY_NATIVE_SCANNER_RUN_STATUS: NativeScannerRunStatus = {
  running: false,
  status: "blocked",
  runId: "",
  category: "artifacts",
  target: 0,
  captured: 0,
  queued: 0,
  clicked: 0,
  pages: 0,
  activeMs: 0,
  message: "Electron bridge unavailable.",
  outputRoot: "",
  runDir: "",
  manifestPath: "",
  jobsPath: "",
  statusPath: "",
  dataVersion: "",
  lastArtifactPath: "",
};
const EMPTY_NATIVE_SCANNER_PROCESS_STATUS: NativeScannerProcessStatus = {
  ok: false,
  runDir: "",
  jobsPath: "",
  reportPath: "",
  scanResultsPath: "",
  processed: 0,
  parsed: 0,
  review: 0,
  stored: 0,
  errors: 1,
  elapsedMs: 0,
  queueConcurrency: 0,
  persisted: false,
  error: "Electron bridge unavailable.",
  results: [],
};
const EMPTY_NATIVE_SCANNER_RESULTS_LOAD_STATUS: NativeScannerResultsLoadStatus = {
  ok: false,
  runDir: "",
  path: "",
  total: 0,
  results: [],
  error: "Electron bridge unavailable.",
};
const EMPTY_NATIVE_SCANNER_PROMOTION_STATUS: NativeScannerPromotionStatus = {
  ok: false,
  runDir: "",
  logPath: "",
  requested: 0,
  selected: 0,
  promoted: 0,
  alreadyStored: 0,
  review: 0,
  blocked: 0,
  added: 0,
  updated: 0,
  total: 0,
  promotedResultIds: [],
  error: "Electron bridge unavailable.",
};
const EMPTY_NATIVE_SCANNER_REVIEW_STATUS: NativeScannerReviewStatus = {
  ok: false,
  runDir: "",
  logPath: "",
  resultId: "",
  action: "approve",
  evalSampleSaved: false,
  correctedFields: [],
  error: "Electron bridge unavailable.",
};
const EMPTY_NATIVE_SCANNER_IMAGE_LOAD_STATUS: NativeScannerImageLoadStatus = {
  ok: false,
  runDir: "",
  path: "",
  dataUrl: "",
  width: 0,
  height: 0,
  error: "Electron bridge unavailable.",
};

async function createBridgeSafeCall<TResult>(
  callback: () => Promise<TResult> | TResult | null | undefined,
  fallback: TResult,
): Promise<TResult> {
  try {
    const result = await callback();
    return result == null ? fallback : result;
  } catch {
    return fallback;
  }
}

function emptyAutomationGuard(): AutomationGuard {
  return { ok: false, escapePressed: false };
}

function emptyFocusGenshinResult(): FocusGenshinResult {
  return { focused: false, alreadyForeground: false };
}

function emptyClickResult(): ClickResult {
  return {
    ok: false,
    x: 0,
    y: 0,
    clicked: false,
    moved: false,
    focused: false,
    inputBlocked: false,
  };
}

function emptyScrollResult(): ScrollResult {
  return { ok: false, notchesSent: 0, inputBlocked: false };
}

function emptyKeyPressResult(key = ""): KeyPressResult {
  return { ok: false, key, inputBlocked: false, eventsSent: 0 };
}

function emptyBooleanResult(): BooleanResult {
  return { ok: false };
}

export function createRendererRepositories(): RendererRepositories | null {
  const bridge = getAssistantBridge();
  if (!bridge) return null;

  const artifactRepo: ArtifactRepositoryPort = {
    loadAll: () =>
      createBridgeSafeCall(
        () => bridge.loadArtifacts(),
        EMPTY_ARTIFACT_STORE_LOAD_RESULT,
      ),
    saveMany: (records) =>
      createBridgeSafeCall(
        () => bridge.saveArtifacts(records),
        EMPTY_ARTIFACT_STORE_SAVE_RESULT,
      ),
  };

  const captureRepo: CaptureRepositoryPort = {
    listSources: () => createBridgeSafeCall(() => bridge.listCaptureSources(), EMPTY_CAPTURE_SOURCE_LIST),
    captureSource: (sourceId, delayMs, focusGenshin, options) =>
      bridge.captureSource(sourceId, delayMs, focusGenshin, options),
  };

  const runtimeRepo: RuntimeRepositoryPort = {
    getRuntimeInfo: () =>
      createBridgeSafeCall(
        () => bridge.getRuntimeInfo(),
        EMPTY_RUNTIME_INFO,
      ),
  };

  const reviewSamplesRepo: ReviewSampleRepositoryPort = {
    loadSamples: (limit = 50) =>
      createBridgeSafeCall(
        () => bridge.loadReviewSamples(limit),
        EMPTY_REVIEW_SAMPLES_RESULT,
      ),
    saveSample: (sample) =>
      createBridgeSafeCall(
        () => bridge.saveReviewSample(sample),
        EMPTY_SCAN_STATUS_RESULT,
      ),
  };

  const learningRepo: LearningRepositoryPort = {
    loadRules: () =>
      createBridgeSafeCall(
        () => bridge.loadScannerLearningRules(),
        EMPTY_SCANNER_LEARNING_RULES_RESULT,
      ),
    saveRules: (rules) =>
      createBridgeSafeCall(
        () => bridge.saveScannerLearningRules(rules),
        EMPTY_SAVE_RULES_RESULT,
      ),
  };

  const snapshotRepo: SnapshotRepositoryPort = {
    load: () => createBridgeSafeCall(() => bridge.loadSnapshot(), EMPTY_SNAPSHOT),
    save: (snapshot) => createBridgeSafeCall(() => bridge.saveSnapshot(snapshot), EMPTY_SAVE_RESULT),
    runMockScan: () => createBridgeSafeCall(() => bridge.runMockScan(), EMPTY_SNAPSHOT),
    publishScannerStatus: (status) =>
      createBridgeSafeCall(() => bridge.publishScannerStatus(status), EMPTY_SCAN_STATUS_RESULT),
  };

  const automationRepo: AutomationRepositoryPort = {
    getAutomationGuard: () =>
      createBridgeSafeCall(
        () => bridge.getAutomationGuard(),
        emptyAutomationGuard(),
      ),
    focusGenshinForScanStart: () =>
      createBridgeSafeCall(
        () =>
          typeof bridge.focusGenshinForScanStart === "function"
            ? bridge.focusGenshinForScanStart()
            : bridge.focusGenshin(),
        emptyFocusGenshinResult(),
      ),
    focusGenshin: () =>
      createBridgeSafeCall(
        () => bridge.focusGenshin(),
        emptyFocusGenshinResult(),
      ),
    focusMainWindow: () => createBridgeSafeCall(() => bridge.focusMainWindow(), emptyBooleanResult()),
    clickScreen: (x, y) => createBridgeSafeCall(() => bridge.clickScreen(x, y), emptyClickResult()),
    scrollScreen: (notches, anchorX, anchorY) =>
      createBridgeSafeCall(() => bridge.scrollScreen(notches, anchorX, anchorY), emptyScrollResult()),
    keyPress: (key) => createBridgeSafeCall(() => bridge.keyPress(key), emptyKeyPressResult(key)),
    nativeScannerDataStatus: () =>
      createBridgeSafeCall(() => bridge.nativeScannerDataStatus(), EMPTY_NATIVE_SCANNER_DATA_STATUS),
    nativeScannerCatalog: () =>
      createBridgeSafeCall(() => bridge.nativeScannerCatalog(), EMPTY_NATIVE_SCANNER_CATALOG_STATUS),
    nativeScannerPreflight: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerPreflight(options), EMPTY_NATIVE_SCANNER_PREFLIGHT_STATUS),
    nativeScannerStart: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerStart(options), EMPTY_NATIVE_SCANNER_RUN_STATUS),
    nativeScannerStop: () =>
      createBridgeSafeCall(() => bridge.nativeScannerStop(), EMPTY_NATIVE_SCANNER_RUN_STATUS),
    nativeScannerStatus: () =>
      createBridgeSafeCall(() => bridge.nativeScannerStatus(), EMPTY_NATIVE_SCANNER_RUN_STATUS),
    nativeScannerProcessRun: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerProcessRun(options), EMPTY_NATIVE_SCANNER_PROCESS_STATUS),
    nativeScannerLoadResults: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerLoadResults(options), EMPTY_NATIVE_SCANNER_RESULTS_LOAD_STATUS),
    nativeScannerPromoteResults: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerPromoteResults(options), EMPTY_NATIVE_SCANNER_PROMOTION_STATUS),
    nativeScannerReviewResult: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerReviewResult(options), EMPTY_NATIVE_SCANNER_REVIEW_STATUS),
    nativeScannerLoadImage: (options) =>
      createBridgeSafeCall(() => bridge.nativeScannerLoadImage(options), EMPTY_NATIVE_SCANNER_IMAGE_LOAD_STATUS),
    onCommand: bridge.onScannerCommand,
  };

  const overlayRepo: OverlayRepositoryPort = {
    show: () => createBridgeSafeCall(() => bridge.showOverlay(), emptyBooleanResult()),
  };

  const exportRepo: ScanExportPort = {
    exportGood: (payload) => createBridgeSafeCall(() => bridge.exportGood(payload), EMPTY_SAVE_RESULT),
    importGoodFile: () => createBridgeSafeCall(() => bridge.importGoodFile(), EMPTY_GOOD_IMPORT_FILE_RESULT),
  };

  return {
    artifacts: artifactRepo,
    capture: captureRepo,
    runtime: runtimeRepo,
    reviewSamples: reviewSamplesRepo,
    learning: learningRepo,
    snapshot: snapshotRepo,
    automation: automationRepo,
    overlay: overlayRepo,
    export: exportRepo,
    canExportGood: bridge.canExportGood,
    canShowOverlay: bridge.canShowOverlay,
    canAutoScan: bridge.canAutoScan,
    canReviewSamples: bridge.canReviewSamples,
    isAvailable: true,
  };
}
