import { ipcMain, BrowserWindow, shell } from 'electron';
import log from 'electron-log';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);
import {
  checkDockerStatus,
  checkHomebrewStatus,
  getSystemStatus,
  installDockerViaHomebrew,
  updateDockerViaHomebrew,
  reinstallDockerViaHomebrew,
  installHomebrew,
  updateHomebrew,
  reinstallHomebrew
} from '../system-manager';
import { getDockerVersions } from '../services/docker-manager';
import {
  checkFrpcStatus,
  installFrpcViaHomebrew,
  updateFrpcViaHomebrew,
  reinstallFrpcViaHomebrew,
  uninstallFrpcViaHomebrew
} from '../services/frpc-manager';
import {
  checkFrpcConfigStatus,
  startFrpcService,
  stopFrpcService
} from '../services/frpc-config-manager';
import { CacheManager, type SetupWizardCacheKey } from '../services/cache-manager';

/**
 * Register system-related IPC handlers (Docker, Homebrew, FRPC)
 */
export function registerSystemHandlers(cache: CacheManager<SetupWizardCacheKey, any>): void {
  // System status
  ipcMain.handle('system:get-status', async () => {
    try {
      return await getSystemStatus();
    } catch (error) {
      log.error('Error getting system status:', error);
      throw error;
    }
  });

  // Docker handlers
  ipcMain.handle('system:check-docker', async (_event, forceRefresh = false) => {
    try {
      // Check cache first (automatically handles TTL)
      if (!forceRefresh) {
        const cached = cache.get('dockerStatus');
        if (cached) {
          log.info('Returning cached Docker status');
          return cached;
        }
      }

      // Fetch fresh data
      const status = await checkDockerStatus();
      cache.set('dockerStatus', status);
      return status;
    } catch (error) {
      log.error('Error checking Docker status:', error);
      throw error;
    }
  });

  ipcMain.handle('system:install-docker', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await installDockerViaHomebrew(window);

      // Invalidate cache after install
      if (result.success) {
        cache.invalidate('dockerStatus');
      }

      return result;
    } catch (error) {
      log.error('Error installing Docker:', error);
      throw error;
    }
  });

  ipcMain.handle('system:update-docker', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await updateDockerViaHomebrew(window);

      // Invalidate cache after update
      if (result.success) {
        cache.invalidate('dockerStatus');
      }

      return result;
    } catch (error) {
      log.error('Error updating Docker:', error);
      throw error;
    }
  });

  ipcMain.handle('system:get-docker-versions', async () => {
    try {
      return await getDockerVersions();
    } catch (error) {
      log.error('Error fetching Docker versions:', error);
      return [];
    }
  });

  ipcMain.handle('system:reinstall-docker', async (event, version?) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await reinstallDockerViaHomebrew(window, version);

      // Invalidate cache after reinstall
      if (result.success) {
        cache.invalidate('dockerStatus');
      }

      return result;
    } catch (error) {
      log.error('Error reinstalling Docker:', error);
      throw error;
    }
  });

  ipcMain.handle('system:open-docker', async () => {
    try {
      log.info('Opening Docker Desktop...');
      // Use open command with full path to Docker Desktop
      await execAsync('open "/Applications/Docker.app/Contents/MacOS/Docker Desktop.app"');
      log.info('Docker Desktop opened successfully');
      return { success: true };
    } catch (error: any) {
      log.error('Error opening Docker Desktop:', error);
      return {
        success: false,
        message: error.message || 'Failed to open Docker Desktop'
      };
    }
  });

  ipcMain.handle('system:open-terminal', async () => {
    try {
      log.info('Opening Terminal...');
      // Use AppleScript to activate Terminal (brings to foreground even if already running)
      await execAsync('osascript -e \'tell application "Terminal" to activate\'');
      log.info('Terminal opened successfully');
      return { success: true };
    } catch (error: any) {
      log.error('Error opening Terminal:', error);
      return {
        success: false,
        message: error.message || 'Failed to open Terminal'
      };
    }
  });

  // Homebrew handlers
  ipcMain.handle('system:check-homebrew', async (_event, forceRefresh = false) => {
    try {
      if (!forceRefresh && cache.get('homebrewStatus')) {
        log.info('Returning cached Homebrew status');
        return cache.get('homebrewStatus');
      }

      const status = await checkHomebrewStatus();
      cache.set('homebrewStatus', status);
      return status;
    } catch (error) {
      log.error('Error checking Homebrew status:', error);
      throw error;
    }
  });

  ipcMain.handle('system:install-homebrew', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await installHomebrew(window);

      // Invalidate cache after install
      if (result.success) {
        cache.invalidate('homebrewStatus');
      }

      return result;
    } catch (error) {
      log.error('Error installing Homebrew:', error);
      throw error;
    }
  });

  ipcMain.handle('system:update-homebrew', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await updateHomebrew(window);

      // Invalidate cache after update
      if (result.success) {
        cache.invalidate('homebrewStatus');
      }

      return result;
    } catch (error) {
      log.error('Error updating Homebrew:', error);
      throw error;
    }
  });

  ipcMain.handle('system:reinstall-homebrew', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await reinstallHomebrew(window);

      // Invalidate cache after reinstall
      if (result.success) {
        cache.invalidate('homebrewStatus');
      }

      return result;
    } catch (error) {
      log.error('Error reinstalling Homebrew:', error);
      throw error;
    }
  });

  // FRPC handlers
  ipcMain.handle('system:check-frpc', async (_event, forceRefresh = false) => {
    try {
      if (!forceRefresh && cache.get('frpcStatus')) {
        log.info('Returning cached FRPC status');
        return cache.get('frpcStatus');
      }

      const status = await checkFrpcStatus();
      cache.set('frpcStatus', status);
      return status;
    } catch (error) {
      log.error('Error checking FRPC status:', error);
      throw error;
    }
  });

  ipcMain.handle('system:install-frpc', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await installFrpcViaHomebrew(window);

      // Invalidate cache after install
      if (result.success) {
        cache.invalidate('frpcStatus');
      }

      return result;
    } catch (error) {
      log.error('Error installing FRPC:', error);
      throw error;
    }
  });

  ipcMain.handle('system:update-frpc', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await updateFrpcViaHomebrew(window);

      // Invalidate cache after update
      if (result.success) {
        cache.invalidate('frpcStatus');
      }

      return result;
    } catch (error) {
      log.error('Error updating FRPC:', error);
      throw error;
    }
  });

  ipcMain.handle('system:reinstall-frpc', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await reinstallFrpcViaHomebrew(window);

      // Invalidate cache after reinstall
      if (result.success) {
        cache.invalidate('frpcStatus');
      }

      return result;
    } catch (error) {
      log.error('Error reinstalling FRPC:', error);
      throw error;
    }
  });

  ipcMain.handle('system:uninstall-frpc', async (event) => {
    try {
      const window = BrowserWindow.fromWebContents(event.sender);
      const result = await uninstallFrpcViaHomebrew(window);

      // Invalidate cache after uninstall
      if (result.success) {
        cache.invalidate('frpcStatus');
      }

      return result;
    } catch (error) {
      log.error('Error uninstalling FRPC:', error);
      throw error;
    }
  });

  // FRPC Config handlers
  ipcMain.handle('system:get-frpc-config-status', async () => {
    try {
      return await checkFrpcConfigStatus();
    } catch (error) {
      log.error('Error getting FRPC config status:', error);
      throw error;
    }
  });

  ipcMain.handle('system:start-frpc-service', async () => {
    try {
      return await startFrpcService();
    } catch (error) {
      log.error('Error starting FRPC service:', error);
      throw error;
    }
  });

  ipcMain.handle('system:stop-frpc-service', async () => {
    try {
      return await stopFrpcService();
    } catch (error) {
      log.error('Error stopping FRPC service:', error);
      throw error;
    }
  });

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