import { contextBridge, ipcRenderer } from 'electron';

console.log('[Setup Wizard Preload] Electron modules imported');

// Inline the createOutputListener to avoid module resolution issues in preload context
function createOutputListener(channel: string) {
  return (callback: (output: string) => void): (() => void) => {
    const listener = (_event: any, output: string) => callback(output);
    ipcRenderer.on(channel, listener);
    return () => {
      ipcRenderer.removeListener(channel, listener);
    };
  };
}

console.log('[Setup Wizard Preload] Listener helpers defined');

import type {
  SetupWizardState,
  SetupWizardStepConfig,
  StepValidationResult,
  ArtifactoryStatus,
  ArtifactorySetupOptions,
  DockerStatus,
  DockerVersion,
  InstallResult,
  InstCliStatus,
  GitConfigStatus,
  GitConfigOptions,
  SshKeyStatus,
  SshKeyGenerateOptions,
  FrpcStatus,
  FrpcConfigStatus,
  GitCloneStatus,
  BuildRunStatus
} from '../renderer/types';

console.log('[Setup Wizard Preload] Starting to load preload script...');

// CRITICAL: Expose API BEFORE any imports or complex logic
try {
  console.log('[Setup Wizard Preload] About to expose API...');

  // Add a marker to verify preload loaded
  contextBridge.exposeInMainWorld('__PRELOAD_LOADED__', true);
  console.log('[Setup Wizard Preload] Marker exposed');

  // Expose protected methods that allow the renderer process to use
  // ipcRenderer without exposing the entire object
  contextBridge.exposeInMainWorld('setupWizardAPI', {
  // State management
  getState: async (): Promise<SetupWizardState> => {
    return ipcRenderer.invoke('onboarding:get-state');
  },

  setState: async (state: SetupWizardState): Promise<void> => {
    return ipcRenderer.invoke('onboarding:set-state', state);
  },

  // Step management
  getSteps: async (): Promise<SetupWizardStepConfig[]> => {
    return ipcRenderer.invoke('onboarding:get-steps');
  },

  validateStep: async (stepId: string): Promise<StepValidationResult> => {
    return ipcRenderer.invoke('onboarding:validate-step', stepId);
  },

  // Artifactory operations
  getArtifactoryStatus: async (forceRefresh = false): Promise<ArtifactoryStatus> => {
    return ipcRenderer.invoke('artifactory:get-status', forceRefresh);
  },

  setupArtifactory: async (options: ArtifactorySetupOptions): Promise<InstallResult> => {
    return ipcRenderer.invoke('artifactory:setup', options);
  },

  // Homebrew operations
  getHomebrewStatus: async (forceRefresh = false) => {
    return ipcRenderer.invoke('system:check-homebrew', forceRefresh);
  },

  installHomebrew: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:install-homebrew');
  },

  updateHomebrew: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:update-homebrew');
  },

  reinstallHomebrew: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:reinstall-homebrew');
  },

  onInstallHomebrewOutput: createOutputListener('homebrew:install-output'),

  onUpdateHomebrewOutput: createOutputListener('homebrew:update-output'),

  onReinstallHomebrewOutput: createOutputListener('homebrew:reinstall-output'),

  // Docker operations (reuse from settings)
  getDockerStatus: async (forceRefresh = false): Promise<DockerStatus> => {
    return ipcRenderer.invoke('system:check-docker', forceRefresh);
  },

  installDocker: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:install-docker');
  },

  updateDocker: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:update-docker');
  },

  getDockerVersions: async (): Promise<DockerVersion[]> => {
    return ipcRenderer.invoke('system:get-docker-versions');
  },

  reinstallDocker: async (version?: DockerVersion): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:reinstall-docker', version);
  },

  openDocker: async (): Promise<{ success: boolean; message?: string }> => {
    return ipcRenderer.invoke('system:open-docker');
  },

  openTerminal: async (): Promise<{ success: boolean; message?: string }> => {
    return ipcRenderer.invoke('system:open-terminal');
  },

  onInstallOutput: createOutputListener('docker:install-output'),

  onUpdateOutput: createOutputListener('docker:update-output'),

  onReinstallOutput: createOutputListener('docker:reinstall-output'),

  // inst-cli operations
  getInstCliStatus: async (forceRefresh = false): Promise<InstCliStatus> => {
    return ipcRenderer.invoke('inst-cli:get-status', forceRefresh);
  },

  buildInstCli: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('inst-cli:build');
  },

  onBuildOutput: createOutputListener('inst-cli:build-output'),

  // Git operations
  getGitConfigStatus: async (forceRefresh = false): Promise<GitConfigStatus> => {
    return ipcRenderer.invoke('git:get-status', forceRefresh);
  },

  updateGitConfig: async (options: GitConfigOptions): Promise<InstallResult> => {
    return ipcRenderer.invoke('git:update-config', options);
  },

  installGit: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('git:install');
  },

  onInstallGitOutput: createOutputListener('git:install-output'),

  // SSH key operations
  getSshKeyStatus: async (publicKeyPath?: string, forceRefresh = false): Promise<SshKeyStatus> => {
    return ipcRenderer.invoke('ssh:get-status', publicKeyPath, forceRefresh);
  },

  generateSshKeys: async (options: SshKeyGenerateOptions): Promise<InstallResult> => {
    return ipcRenderer.invoke('ssh:generate-keys', options);
  },

  selectPublicKeyFile: async (): Promise<{ filePath: string } | null> => {
    return ipcRenderer.invoke('ssh:select-public-key');
  },

  readPublicKey: async (publicKeyPath: string): Promise<{ success: boolean; content?: string; message?: string }> => {
    return ipcRenderer.invoke('ssh:read-public-key', publicKeyPath);
  },

  updateSshConfig: async (privateKeyPath: string): Promise<{ success: boolean; message: string }> => {
    return ipcRenderer.invoke('ssh:update-config', privateKeyPath);
  },

  getGerritUsername: async (): Promise<string | null> => {
    return ipcRenderer.invoke('ssh:get-gerrit-username');
  },

  updateGerritSshConfig: async (privateKeyPath: string, username: string): Promise<{ success: boolean; message: string }> => {
    return ipcRenderer.invoke('ssh:update-gerrit-config', privateKeyPath, username);
  },

  testGerritConnection: async (privateKeyPath: string): Promise<{ success: boolean; message: string }> => {
    return ipcRenderer.invoke('ssh:test-gerrit', privateKeyPath);
  },

  // FRPC operations
  getFrpcStatus: async (forceRefresh = false): Promise<FrpcStatus> => {
    return ipcRenderer.invoke('system:check-frpc', forceRefresh);
  },

  installFrpc: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:install-frpc');
  },

  updateFrpc: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:update-frpc');
  },

  reinstallFrpc: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:reinstall-frpc');
  },

  onInstallFrpcOutput: createOutputListener('frpc:install-output'),

  onUpdateFrpcOutput: createOutputListener('frpc:update-output'),

  onReinstallFrpcOutput: createOutputListener('frpc:reinstall-output'),

  uninstallFrpc: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:uninstall-frpc');
  },

  onUninstallFrpcOutput: createOutputListener('frpc:uninstall-output'),

  // FRPC Config operations
  getFrpcConfigStatus: async () => {
    return ipcRenderer.invoke('system:get-frpc-config-status');
  },

  startFrpcService: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:start-frpc-service');
  },

  stopFrpcService: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('system:stop-frpc-service');
  },

  // Git Clone operations
  getGitCloneStatus: async (forceRefresh = false): Promise<GitCloneStatus> => {
    return ipcRenderer.invoke('git-clone:get-status', forceRefresh);
  },

  selectCloneFolder: async (): Promise<string | null> => {
    return ipcRenderer.invoke('git-clone:select-folder');
  },

  saveCloneFolder: async (folder: string, folderName?: string): Promise<void> => {
    return ipcRenderer.invoke('git-clone:save-folder', folder, folderName);
  },

  saveFolderName: async (folderName: string): Promise<void> => {
    return ipcRenderer.invoke('git-clone:save-folder-name', folderName);
  },

  cloneCanvasLms: async (targetFolder: string, folderName = 'dev'): Promise<InstallResult> => {
    return ipcRenderer.invoke('git-clone:clone', targetFolder, folderName);
  },

  resetRepository: async (repositoryPath: string): Promise<InstallResult> => {
    return ipcRenderer.invoke('git-clone:reset', repositoryPath);
  },

  onCloneOutput: createOutputListener('git-clone:clone-output'),

  onResetOutput: createOutputListener('git-clone:reset-output'),

  markGitCloneConfigured: async (): Promise<void> => {
    return ipcRenderer.invoke('git-clone:mark-configured');
  },

  // Inst Config operations
  getInstConfigStatus: async (): Promise<any> => {
    return ipcRenderer.invoke('inst-config:get-status');
  },

  saveInstConfig: async (content: string): Promise<InstallResult> => {
    return ipcRenderer.invoke('inst-config:save', content);
  },

  // Inst CLI Proxy operations
  getInstCliProxyStatus: async (): Promise<any> => {
    return ipcRenderer.invoke('inst-cli-proxy:get-status');
  },

  createDockerComposeOverride: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('inst-cli-proxy:create-docker-compose');
  },

  startProxy: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('inst-cli-proxy:start');
  },

  stopProxy: async (): Promise<InstallResult> => {
    return ipcRenderer.invoke('inst-cli-proxy:stop');
  },

  onStartProxyOutput: createOutputListener('inst-cli-proxy:start-output'),

  onStopProxyOutput: createOutputListener('inst-cli-proxy:stop-output'),

  // Multi-deploy preference
  getMultiDeploy: async (): Promise<boolean> => {
    return ipcRenderer.invoke('settings:get-multi-deploy');
  },

  setMultiDeploy: async (value: boolean): Promise<void> => {
    return ipcRenderer.invoke('settings:set', 'multiDeploy', value);
  },

  // Build and Run operations
  getBuildRunStatus: async (multiDeploy = true): Promise<BuildRunStatus> => {
    return ipcRenderer.invoke('build-run:get-status', multiDeploy);
  },

  buildAndRun: async (multiDeploy = true): Promise<InstallResult> => {
    return ipcRenderer.invoke('build-run:build', multiDeploy);
  },

  cleanBuildAndRun: async (multiDeploy = true): Promise<InstallResult> => {
    return ipcRenderer.invoke('build-run:clean-build', multiDeploy);
  },

  onBuildRunOutput: createOutputListener('build-run:output'),

  // Tray icon update
  updateTrayIcon: async (): Promise<void> => {
    return ipcRenderer.invoke('onboarding:update-tray-icon');
  },

  // File system operations
  showInFinder: async (path: string): Promise<boolean> => {
    return ipcRenderer.invoke('file-system:show-in-finder', path);
  },

  // Theme operations
  getTheme: async (): Promise<string> => {
    return ipcRenderer.invoke('settings:get-theme');
  },

  // Theme change listener
  onThemeChange: createOutputListener('theme-changed')
});

  console.log('[Setup Wizard Preload] setupWizardAPI exposed successfully!');
} catch (error) {
  console.error('[Setup Wizard Preload] FATAL ERROR:', error);
  throw error;
}
