import { vi } from 'vitest'

const localStorageMock = (() => {
  let store: Record<string, string> = {}
  return {
    getItem: (key: string) => store[key] ?? null,
    setItem: (key: string, value: string) => { store[key] = value },
    removeItem: (key: string) => { delete store[key] },
    clear: () => { store = {} },
    get length() { return Object.keys(store).length },
    key: (index: number) => Object.keys(store)[index] ?? null,
  }
})()

Object.defineProperty(globalThis, 'localStorage', { value: localStorageMock, writable: true, configurable: true })

// ── window.electronAPI mock (prevents unhandled rejections in tests that import runtime modules) ──
const mockElectronAPI = {
  getAppInfo: () => Promise.resolve({ first_launch: false, version: '2.1.0' }),
  getInstallInfo: () => Promise.resolve({ first_launch: false, build_date: "2026-06-23", git_commit: "test" }),
  exit: () => Promise.resolve(),
  restart: () => Promise.resolve(),
  getAppPaths: () => Promise.resolve({ home: '/tmp', appData: '/tmp/appdata', config: '/tmp/config', cache: '/tmp/cache' }),
  saveLayout: () => Promise.resolve(),
  loadLayout: () => Promise.resolve(null),
  readTextFile: () => Promise.resolve(''),
  writeTextFile: () => Promise.resolve(),
  readBinaryFile: () => Promise.resolve(''),
  writeBinaryFile: () => Promise.resolve(),
  fileExists: () => Promise.resolve(true),
  createDirectory: () => Promise.resolve(),
  deleteFile: () => Promise.resolve(),
  renameFile: () => Promise.resolve(),
  getFileStats: () => Promise.resolve({}),
  readDirectory: () => Promise.resolve([]),
  listDirectory: () => Promise.resolve([]),
  startFileWatcher: () => Promise.resolve(),
  stopFileWatcher: () => Promise.resolve(),
  workspaceListFiles: () => Promise.resolve([]),
  workspaceOpenFolder: () => Promise.resolve(null),
  workspaceOpenWorkspace: () => Promise.resolve(null),
  workspaceGetTree: () => Promise.resolve([]),
  workspaceReadFile: () => Promise.resolve(''),
  workspaceWriteFile: () => Promise.resolve(),
  workspaceCreateFile: () => Promise.resolve(true),
  workspaceCreateDirectory: () => Promise.resolve(true),
  workspaceRename: () => Promise.resolve(),
  workspaceDelete: () => Promise.resolve(),
  workspaceStartWatcher: () => Promise.resolve(),
  workspaceStopWatcher: () => Promise.resolve(),
  workspaceGetRecent: () => Promise.resolve([]),
  workspaceAddRecent: () => Promise.resolve(),
  workspaceRemoveRecent: () => Promise.resolve(),
  workspacePinRecent: () => Promise.resolve(),
  workspaceSearchFiles: () => Promise.resolve([]),
  workspaceListDirectory: () => Promise.resolve([]),
  gitStatus: () => Promise.resolve([]),
  gitLog: () => Promise.resolve([]),
  gitDiff: () => Promise.resolve(''),
  gitCommit: () => Promise.resolve(true),
  gitRestore: () => Promise.resolve(true),
  gitInit: () => Promise.resolve(true),
  gitPush: () => Promise.resolve(true),
  gitPull: () => Promise.resolve(true),
  gitBranchList: () => Promise.resolve([]),
  gitCheckout: () => Promise.resolve(true),
  gitAdd: () => Promise.resolve(true),
  dialogOpen: () => Promise.resolve(null),
  dialogSave: () => Promise.resolve(null),
  dialogMessage: () => Promise.resolve({}),
  clipboardReadText: () => Promise.resolve(''),
  clipboardWriteText: () => Promise.resolve(),
  notificationShow: () => Promise.resolve(true),
  notificationIsSupported: () => Promise.resolve(true),
  openExternal: () => Promise.resolve(),
  browserLaunch: () => Promise.resolve({ id: 'mock' }),
  browserClose: () => Promise.resolve(),
  browserNavigate: () => Promise.resolve(),
  browserNewTab: () => Promise.resolve(),
  browserCloseTab: () => Promise.resolve(),
  browserListTabs: () => Promise.resolve([]),
  browserReload: () => Promise.resolve(),
  browserDoubleClick: () => Promise.resolve(),
  browserHover: () => Promise.resolve(),
  browserPressKey: () => Promise.resolve(),
  browserWaitElement: () => Promise.resolve(),
  browserGetConsoleLogs: () => Promise.resolve([]),
  browserSaveState: () => Promise.resolve(),
  browserLoadState: () => Promise.resolve([]),
  browserClick: () => Promise.resolve(),
  browserType: () => Promise.resolve(),
  browserScreenshot: () => Promise.resolve(''),
  browserGetText: () => Promise.resolve(''),
  browserGetUrl: () => Promise.resolve('about:blank'),
  browserGetTitle: () => Promise.resolve(''),
  browserGetContent: () => Promise.resolve(''),
  browserExecuteJs: () => Promise.resolve(''),
  browserDetect: () => Promise.resolve([]),
  browserShowSession: () => Promise.resolve(),
  viewportCreate: () => Promise.resolve(),
  viewportResize: () => Promise.resolve(),
  viewportDestroy: () => Promise.resolve(),
  viewportNavigate: () => Promise.resolve(true),
  viewportReload: () => Promise.resolve(true),
  viewportGoBack: () => Promise.resolve(true),
  viewportGoForward: () => Promise.resolve(true),
  viewportClick: () => Promise.resolve({ success: true }),
  viewportType: () => Promise.resolve({ success: true }),
  viewportPressKey: () => Promise.resolve({ success: true }),
  viewportScreenshot: () => Promise.resolve(null),
  viewportExecuteJs: () => Promise.resolve({ success: true }),
  viewportGetConsoleLogs: () => Promise.resolve([]),
  viewportInjectAnnotations: () => Promise.resolve(true),
  viewportGetAnnotations: () => Promise.resolve([]),
  viewportGetState: () => Promise.resolve({ url: '', title: '', isLoading: false, canGoBack: false, canGoForward: false }),
  viewportGetNetworkLogs: () => Promise.resolve([]),
  extensionList: () => Promise.resolve([]),
  extensionLoad: () => Promise.resolve(),
  extensionUnload: () => Promise.resolve(),
  pluginBrowserNavigate: () => Promise.resolve(),
  pluginBrowserClick: () => Promise.resolve(),
  pluginBrowserType: () => Promise.resolve(),
  pluginBrowserScreenshot: () => Promise.resolve(''),
  pluginBrowserExecuteJs: () => Promise.resolve(''),
  pluginBrowserGetDom: () => Promise.resolve(''),
  pluginBrowserGetText: () => Promise.resolve(''),
  pluginBrowserGetUrl: () => Promise.resolve(''),
  pluginBrowserGetTitle: () => Promise.resolve(''),
  terminalCreate: () => Promise.resolve('mock-terminal-1'),
  terminalWrite: () => Promise.resolve(),
  terminalResize: () => Promise.resolve(),
  terminalKill: () => Promise.resolve(),
  terminalList: () => Promise.resolve([]),
  runCommand: () => Promise.resolve(''),
  runCommandStream: () => Promise.resolve(0),
  killCommand: () => Promise.resolve(),
  stdinInput: () => Promise.resolve(),
  stdinEnd: () => Promise.resolve(),
  uninstallDetectData: () => Promise.resolve({ hasData: false }),
  uninstallPerform: () => Promise.resolve(),
  uninstallOpenSystem: () => Promise.resolve(),
  uninstallSelf: () => Promise.resolve(),
  uninstallSetAutoLaunch: () => Promise.resolve(),
  checkForUpdates: () => Promise.resolve(null),
  downloadUpdate: () => Promise.resolve(),
  installUpdate: () => Promise.resolve(),
  getResourceDataUrl: () => Promise.resolve(''),
  safeStorageEncrypt: () => Promise.resolve(''),
  safeStorageDecrypt: () => Promise.resolve(''),
  proxyHttpRequest: () => Promise.resolve({ status: 200, body: '', headers: {} }),
  proxyHttpStreamStart: () => Promise.resolve(),
  proxyHttpStreamAbort: () => Promise.resolve(),
  replayInit: () => Promise.resolve({ sessionCount: 0, orphanedCount: 0 }),
  replayAppendEvent: () => Promise.resolve(),
  replayAppendBatch: () => Promise.resolve(),
  replayReadSession: () => Promise.resolve(null),
  replaySessionExists: () => Promise.resolve(false),
  replayDeleteSession: () => Promise.resolve(),
  replayListSessions: () => Promise.resolve({}),
  replayUpdateSessionMeta: () => Promise.resolve(),
  replayGetSessionMeta: () => Promise.resolve(null),
  replayClearAll: () => Promise.resolve(),
  replayGetStats: () => Promise.resolve({ totalSessions: 0, totalEvents: 0, storagePath: '' }),
  replayApplyRetention: () => Promise.resolve({ deletedCount: 0, remainingCount: 0 }),
  verificationRunCommand: () => Promise.resolve({ code: 0, stdout: '', stderr: '' }),
  verificationRunBenchmarks: () => Promise.resolve({}),
  verificationSecurityScan: () => Promise.resolve({ issues: [] }),
  verificationRegressionScan: () => Promise.resolve({ passed: true }),
  verificationVerifyChanges: () => Promise.resolve({ passed: true }),
  verificationRunStage: () => Promise.resolve({ success: true }),
  verificationAutoFix: () => Promise.resolve({ fixed: 0 }),
  getPathForFile: () => null,
  on: () => () => {},
}

// ── window + electronAPI mock (prevents unhandled rejections in tests that import runtime modules) ──
// Using vi.stubGlobal ensures the mock survives across test contexts in all vitest environments.
const windowMock = {
  electronAPI: mockElectronAPI,
  addEventListener: () => {},
  removeEventListener: () => {},
  matchMedia: () => ({ matches: false, addEventListener: () => {}, removeEventListener: () => {} }),
  document: {
    createElement: () => ({ style: {} }),
    documentElement: { style: {} },
    addEventListener: () => {},
    removeEventListener: () => {},
  },
  location: { href: 'http://localhost', search: '', pathname: '/' },
  localStorage: globalThis.localStorage,
  navigator: { platform: 'test', hardwareConcurrency: 4 },
}
vi.stubGlobal('window', windowMock)

// ── Suppress expected console noise from StorageEngine fallback + ContextCache ──
const origConsoleWarn = console.warn
console.warn = (...args: unknown[]) => {
  if (
    typeof args[0] === 'string' &&
    (args[0].includes('[MemoryStorage]') || args[0].includes('[ContextCache]'))
  ) return
  origConsoleWarn.call(console, ...args)
}

// ── HTML Canvas / requestAnimationFrame polyfills ──
globalThis.requestAnimationFrame = (cb: FrameRequestCallback) => setTimeout(() => cb(performance.now()), 0) as unknown as number
globalThis.cancelAnimationFrame = (id: number) => clearTimeout(id)
