import { ipcMain, BrowserWindow } from 'electron';
import log from 'electron-log';
import {
  checkGitCloneStatus,
  selectCloneFolder,
  cloneCanvasLms,
  resetRepository
} from '../services/git-clone-manager';
import {
  checkInstConfigStatus,
  saveInstConfig
} from '../services/inst-config-manager';
import {
  checkInstCliProxyStatus,
  createDockerComposeOverride,
  startProxy,
  stopProxy
} from '../services/inst-cli-proxy-manager';
import {
  checkBuildRunStatus,
  buildAndRun,
  cleanBuildAndRun
} from '../services/build-run-manager';
import { showInFinder } from '../services/file-system-utils';
import { settingsStore } from '../store';

/**
 * Register tool-related IPC handlers (git-clone, inst-config, inst-cli-proxy, build-run)
 */
export function registerToolHandlers(): void {
  // Git Clone handlers
  ipcMain.handle('git-clone:get-status', async (_event, forceRefresh = false) => {
    try {
      const onboardingState = settingsStore.get('onboarding');
      const stepData = onboardingState.stepStatus['git-clone'];
      const cloneFolder = stepData?.data?.cloneFolder;
      const folderName = stepData?.data?.folderName || 'dev';
      const status = await checkGitCloneStatus(cloneFolder, folderName);
      return {
        ...status,
        cloneFolder,
        folderName
      };
    } catch (error) {
      log.error('Error getting git clone status:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:select-folder', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      return await selectCloneFolder(window);
    } catch (error) {
      log.error('Error selecting repository folder:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:save-folder', async (_event, folder: string, folderName?: string) => {
    try {
      log.info('Saving clone folder:', folder, 'folderName:', folderName);
      const onboardingState = settingsStore.get('onboarding');

      // Preserve existing data if it exists
      const existingStepData = onboardingState.stepStatus['git-clone'] || {};
      const existingData = existingStepData.data || {};

      onboardingState.stepStatus['git-clone'] = {
        ...existingStepData,
        completed: false,
        lastChecked: Date.now(),
        data: {
          ...existingData,
          cloneFolder: folder,
          ...(folderName !== undefined ? { folderName } : {})
        }
      };

      settingsStore.set('onboarding', onboardingState);
      log.info('Clone folder saved successfully');
    } catch (error) {
      log.error('Error saving clone folder:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:save-folder-name', async (_event, folderName: string) => {
    try {
      log.info('Saving clone folder name:', folderName);
      const onboardingState = settingsStore.get('onboarding');
      const existingStepData = onboardingState.stepStatus['git-clone'] || {};
      const existingData = existingStepData.data || {};

      onboardingState.stepStatus['git-clone'] = {
        ...existingStepData,
        completed: false,
        lastChecked: Date.now(),
        data: {
          ...existingData,
          folderName
        }
      };

      settingsStore.set('onboarding', onboardingState);
      log.info('Clone folder name saved successfully');
    } catch (error) {
      log.error('Error saving clone folder name:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:clone', async (event, targetFolder: string, folderName = 'dev') => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      return await cloneCanvasLms(targetFolder, window, folderName);
    } catch (error) {
      log.error('Error cloning repository:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:reset', async (event, repositoryPath: string) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      return await resetRepository(repositoryPath, window);
    } catch (error) {
      log.error('Error resetting repository:', error);
      throw error;
    }
  });

  ipcMain.handle('git-clone:mark-configured', async () => {
    try {
      const onboardingState = settingsStore.get('onboarding');
      const stepData = onboardingState.stepStatus['git-clone'];
      if (stepData) {
        stepData.completed = true;
        stepData.lastChecked = Date.now();
        settingsStore.set('onboarding', onboardingState);
      }
    } catch (error) {
      log.error('Error marking git clone as configured:', error);
      throw error;
    }
  });

  // Inst Config handlers
  ipcMain.handle('inst-config:get-status', async () => {
    try {
      // Get clone folder from git-clone step data
      const onboardingState = settingsStore.get('onboarding');
      const gitCloneStepData = onboardingState.stepStatus['git-clone'];
      const cloneFolder = gitCloneStepData?.data?.cloneFolder;
      const folderName = gitCloneStepData?.data?.folderName || 'dev';

      return await checkInstConfigStatus(cloneFolder, folderName);
    } catch (error) {
      log.error('Error getting inst config status:', error);
      throw error;
    }
  });

  ipcMain.handle('inst-config:save', async (_event, content: string) => {
    try {
      return await saveInstConfig(content);
    } catch (error) {
      log.error('Error saving inst config:', error);
      throw error;
    }
  });

  // Inst CLI Proxy handlers
  ipcMain.handle('inst-cli-proxy:get-status', async () => {
    try {
      return await checkInstCliProxyStatus();
    } catch (error) {
      log.error('Error getting inst-cli proxy status:', error);
      throw error;
    }
  });

  ipcMain.handle('inst-cli-proxy:create-docker-compose', async () => {
    try {
      return await createDockerComposeOverride();
    } catch (error) {
      log.error('Error creating docker-compose override:', error);
      throw error;
    }
  });

  ipcMain.handle('inst-cli-proxy:start', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender) || undefined;
      return await startProxy(window);
    } catch (error) {
      log.error('Error starting proxy:', error);
      throw error;
    }
  });

  ipcMain.handle('inst-cli-proxy:stop', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender) || undefined;
      return await stopProxy(window);
    } catch (error) {
      log.error('Error stopping proxy:', error);
      throw error;
    }
  });

  // Build and Run handlers
  ipcMain.handle('build-run:get-status', async (_event, multiDeploy = true) => {
    try {
      return await checkBuildRunStatus(multiDeploy);
    } catch (error) {
      log.error('Error getting build-run status:', error);
      throw error;
    }
  });

  ipcMain.handle('build-run:build', async (event, multiDeploy = true) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender) || undefined;
      return await buildAndRun(window, multiDeploy);
    } catch (error) {
      log.error('Error building and running:', error);
      throw error;
    }
  });

  ipcMain.handle('build-run:clean-build', async (event, multiDeploy = true) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender) || undefined;
      return await cleanBuildAndRun(window, multiDeploy);
    } catch (error) {
      log.error('Error running clean build and run:', error);
      throw error;
    }
  });

  // File system handlers
  ipcMain.handle('file-system:show-in-finder', async (_event, path: string) => {
    try {
      return await showInFinder(path);
    } catch (error) {
      log.error('Error showing in Finder:', error);
      throw error;
    }
  });

  log.info('Tool handlers registered');
}
