import { spawn } from 'child_process';
import { promises as fs } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
import log from 'electron-log';
import { execAsync, getEnvWithPath } from './utils/shell-utils';
import { createOutputSender } from './utils/ipc-output-helper';
import { isNewerVersion } from './utils/version-utils';

// Import Docker functionality
import {
  checkDockerStatus as checkDockerStatusImpl,
  removeDockerQuarantine as removeDockerQuarantineImpl,
  type DockerStatus,
  type DockerSettings,
  type InstallResult
} from './services/docker-manager';

// Import Homebrew functionality
import {
  checkHomebrewStatus as checkHomebrewStatusImpl,
  type HomebrewStatus
} from './services/homebrew-manager';

export enum SystemManagerErrorCode {
  NOT_FOUND = 'NOT_FOUND',
  TIMEOUT = 'TIMEOUT',
  PERMISSION_DENIED = 'PERMISSION_DENIED',
  INSTALL_FAILED = 'INSTALL_FAILED'
}

export class SystemManagerError extends Error {
  constructor(
    public code: SystemManagerErrorCode,
    message: string,
    public originalError?: Error
  ) {
    super(message);
    this.name = 'SystemManagerError';
  }
}

// Re-export types from specialized managers for backward compatibility
export type { DockerSettings, DockerStatus, HomebrewStatus, InstallResult };

export interface SystemStatus {
  docker: DockerStatus;
  homebrew: HomebrewStatus;
}

const COMMAND_TIMEOUT = 5000;

// Re-export functions from specialized managers for backward compatibility
export const checkDockerStatus = checkDockerStatusImpl;
export const checkHomebrewStatus = checkHomebrewStatusImpl;
export const removeDockerQuarantine = removeDockerQuarantineImpl;

/**
 * Get system maximum resources
 */
async function getSystemMaxResources(): Promise<{ maxCpus: number; maxMemoryMiB: number; diskSizeMiB: number }> {
  let maxCpus = 10; // default
  let maxMemoryMiB = 30720; // default 30 GB
  let diskSizeMiB = 204800; // default 200 GB

  try {
    // Get number of CPUs
    const cpuResult = await execWithTimeout('sysctl -n hw.ncpu');
    maxCpus = parseInt(cpuResult.stdout.trim(), 10) || 10;
  } catch (error) {
    log.warn('Failed to get CPU count:', error);
  }

  try {
    // Get memory in bytes, convert to MiB
    const memResult = await execWithTimeout('sysctl -n hw.memsize');
    const memBytes = parseInt(memResult.stdout.trim(), 10);
    if (memBytes) {
      maxMemoryMiB = Math.floor(memBytes / (1024 * 1024));
    }
  } catch (error) {
    log.warn('Failed to get memory size:', error);
  }

  try {
    // Get total disk size using df command (returns 512-byte blocks)
    const diskResult = await execWithTimeout('df -k / | tail -1 | awk \'{print $2}\'');
    const diskKb = parseInt(diskResult.stdout.trim(), 10);
    if (diskKb) {
      diskSizeMiB = Math.floor(diskKb / 1024);
    }
  } catch (error) {
    log.warn('Failed to get disk size:', error);
  }

  return { maxCpus, maxMemoryMiB, diskSizeMiB };
}

/**
 * Read Docker Desktop settings from settings-store.json
 */
async function getDockerSettings(): Promise<DockerSettings | null> {
  const settingsPath = join(
    homedir(),
    'Library',
    'Group Containers',
    'group.com.docker',
    'settings-store.json'
  );

  try {
    const fileContent = await fs.readFile(settingsPath, 'utf-8');
    const settings = JSON.parse(fileContent);

    // Log the actual keys and values for debugging
    log.info('Docker settings keys:', Object.keys(settings));
    log.info('Docker settings values:', {
      cpus: settings.cpus,
      Cpus: settings.Cpus,
      memoryMiB: settings.memoryMiB,
      MemoryMiB: settings.MemoryMiB,
      swapMiB: settings.swapMiB,
      SwapMiB: settings.SwapMiB,
      diskSizeMiB: settings.diskSizeMiB,
      DiskSizeMiB: settings.DiskSizeMiB
    });

    // Get system max resources
    const { maxCpus, maxMemoryMiB, diskSizeMiB: systemDiskSizeMiB } = await getSystemMaxResources();

    // Extract settings - try both lowercase and capitalized keys
    const cpus = settings.cpus ?? settings.Cpus ?? maxCpus;
    const memoryMiB = settings.memoryMiB ?? settings.MemoryMiB ?? 8090; // default 7.9 GB if not set
    const swapMiB = settings.swapMiB ?? settings.SwapMiB ?? 1024; // default 1 GB if not set
    const diskSizeMiB = settings.diskSizeMiB ?? settings.DiskSizeMiB ?? systemDiskSizeMiB; // default to system disk size if not set

    log.info('Final Docker settings:', { cpus, memoryMiB, swapMiB, diskSizeMiB });

    return {
      cpus,
      cpusRecommended: 10,
      memoryMiB,
      memoryRecommended: 30720, // 30 GB
      swapMiB,
      swapRecommended: 2560, // 2.5 GB
      diskSizeMiB,
      diskSizeRecommended: 204800 // 200 GB
    };
  } catch (error: any) {
    if (error.code === 'ENOENT') {
      log.info('Docker Desktop settings file not found, using defaults');
    } else {
      log.warn('Failed to read Docker Desktop settings:', error);
    }

    // Return default values when settings file is not available
    const { maxCpus, maxMemoryMiB, diskSizeMiB: systemDiskSizeMiB } = await getSystemMaxResources();
    return {
      cpus: maxCpus,
      cpusRecommended: 10,
      memoryMiB: 8090, // default 7.9 GB
      memoryRecommended: 30720, // 30 GB
      swapMiB: 1024, // default 1 GB
      swapRecommended: 2560, // 2.5 GB
      diskSizeMiB: systemDiskSizeMiB, // default to system disk size
      diskSizeRecommended: 204800 // 200 GB
    };
  }
}

async function execWithTimeout(
  command: string,
  timeoutMs: number = COMMAND_TIMEOUT
): Promise<{ stdout: string; stderr: string }> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const result = await execAsync(command, { signal: controller.signal });
    clearTimeout(timeout);
    return result;
  } catch (error: any) {
    clearTimeout(timeout);
    if (error.name === 'AbortError') {
      throw new SystemManagerError(
        SystemManagerErrorCode.TIMEOUT,
        `Command timed out after ${timeoutMs}ms: ${command}`,
        error
      );
    }
    throw error;
  }
}

export async function getSystemStatus(): Promise<SystemStatus> {
  const [docker, homebrew] = await Promise.all([
    checkDockerStatus(),
    checkHomebrewStatus()
  ]);

  return { docker, homebrew };
}

/**
 * Remove macOS quarantine attribute from Docker.app
 * This helps avoid "Security policy would not allow process" errors
 */
async function launchDockerDesktop(): Promise<void> {
  try {
    log.info('Launching Docker Desktop...');

    // Strategy 1: Try to remove quarantine attribute first (cleanest solution)
    await removeDockerQuarantine();

    // Strategy 2: Try AppleScript to simulate user action (best for triggering Gatekeeper properly)
    try {
      log.info('Attempting to launch Docker via AppleScript...');
      const appleScript = `
        tell application "Docker Desktop"
          activate
        end tell
      `;
      await execAsync(`osascript -e '${appleScript.replace(/'/g, "'\\''")}'`);
      log.info('Docker Desktop launched successfully via AppleScript');
      return;
    } catch (error: any) {
      log.warn('AppleScript launch failed:', error.message);
    }

    // Strategy 3: Try open command (more user-like than direct execution)
    try {
      log.info('Attempting to launch Docker via open command...');
      await execAsync('open -a /Applications/Docker.app/Contents/MacOS/Docker\\ Desktop.app');
      log.info('Docker Desktop launched successfully via open command');
      return;
    } catch (error: any) {
      log.warn('Open command launch failed:', error.message);
    }

    // Strategy 4: Try direct execution as last resort
    try {
      log.info('Attempting to launch Docker via direct execution...');
      await execAsync('/Applications/Docker.app/Contents/MacOS/Docker');
      log.info('Docker Desktop launched successfully via direct execution');
      return;
    } catch (error: any) {
      log.warn('Direct execution launch failed:', error.message);
    }

    // All strategies failed
    log.error('All Docker launch strategies failed. User may need to open Docker manually.');
    throw new Error(
      'Failed to launch Docker Desktop automatically. Please open Docker.app manually from your Applications folder to complete the setup.'
    );
  } catch (error: any) {
    log.error('Failed to launch Docker Desktop:', error);
    throw error;
  }
}

export async function installDockerViaHomebrew(window?: any): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'docker:install-output');

  try {
    // First check if Homebrew is installed
    const homebrewStatus = await checkHomebrewStatus();
    if (!homebrewStatus.installed) {
      return {
        success: false,
        message: 'Homebrew is not installed. Please install Homebrew first.'
      };
    }

    const brewPath = homebrewStatus.path!;

    return new Promise(async (resolve) => {
      sendOutput('═══════════════════════════════════════════════════');
      sendOutput('Starting Docker Desktop Installation');
      sendOutput('═══════════════════════════════════════════════════\n');

      // Step 1: Clean up files that don't require admin privileges
      sendOutput('Cleaning up leftover files...');
      try {
        await execAsync(
          'rm -f /opt/homebrew/etc/bash_completion.d/docker* /usr/local/etc/bash_completion.d/docker* ' +
          '/opt/homebrew/share/fish/vendor_completions.d/docker* /usr/local/share/fish/vendor_completions.d/docker* ' +
          '/opt/homebrew/share/zsh/site-functions/_docker* /usr/local/share/zsh/site-functions/_docker* ' +
          '/usr/local/bin/docker* /opt/homebrew/bin/docker-compose /usr/local/bin/docker-compose',
          { env: getEnvWithPath() }
        );
      } catch (error) {
        // Continue even if cleanup fails
      }

      // Step 2: Prepare /usr/local directories with proper permissions
      sendOutput('Preparing system directories (you will be prompted to authenticate)...');
      const prepareDirectories = `
set currentUser to do shell script "whoami"
set commands to "rm -rf /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "mkdir -p /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "mkdir -p /usr/local/bin 2>&1 || true; "
set commands to commands & "chown -R " & currentUser & " /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "chown " & currentUser & " /usr/local/bin 2>&1 || true; "
set commands to commands & "chmod 755 /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "chmod 755 /usr/local/bin 2>&1 || true"
do shell script commands with administrator privileges
`;

      try {
        await execAsync(`osascript -e '${prepareDirectories.replace(/'/g, "'\\''")}'`);
        sendOutput('✓ Directories prepared\n');
      } catch (error: any) {
        if (error.message.includes('User canceled')) {
          sendOutput('✗ Authentication cancelled by user\n');
          resolve({
            success: false,
            message: 'Installation cancelled. Authentication was dismissed.'
          });
          return;
        }
        sendOutput('⚠ Directory preparation encountered issues (continuing anyway)\n');
      }

      // Step 3: Install Docker Desktop via Homebrew (as regular user)
      sendOutput(`Running: ${brewPath} install --cask docker-desktop\n`);

      const installProcess = spawn(brewPath, ['install', '--cask', 'docker-desktop'], {
        env: getEnvWithPath()
      });

      let stdout = '';
      let stderr = '';

      installProcess.stdout.on('data', (data) => {
        const output = data.toString();
        stdout += output;
        sendOutput(output);
      });

      installProcess.stderr.on('data', (data) => {
        const output = data.toString();
        stderr += output;
        sendOutput(output);
      });

      installProcess.on('error', (error) => {
        sendOutput(`\nError: ${error.message}`);
        resolve({
          success: false,
          message: `Failed to start installation: ${error.message}`
        });
      });

      installProcess.on('close', async (code) => {
        if (code === 0) {
          // Check if Homebrew said it's already installed
          const alreadyInstalled = stdout.includes('already installed') || stderr.includes('already installed');

          // Verify Docker.app actually exists
          let dockerAppExists = false;
          try {
            await execWithTimeout('test -d /Applications/Docker.app');
            dockerAppExists = true;
          } catch (error) {
            dockerAppExists = false;
          }

          // If Homebrew says it's already installed but Docker.app is missing, automatically reinstall
          if (alreadyInstalled && !dockerAppExists) {
            sendOutput('\n⚠ Detected broken installation (Homebrew metadata exists but Docker.app is missing)');
            sendOutput('Automatically proceeding with complete cleanup and reinstall...\n');

            // Step 1: Complete cleanup with admin privileges (app, launchctl, Homebrew metadata, completions, and binaries)
            // We manually remove Homebrew's caskroom instead of using `brew uninstall` to avoid password prompts
            sendOutput('Step 1/2: Complete cleanup (you will be prompted to authenticate)...');
            const completeCleanupScript = `
set commands to "/Applications/Docker.app/Contents/MacOS/uninstall 2>&1 || true; "
set commands to commands & "rm -rf /Applications/Docker.app 2>&1 || true; "
set commands to commands & "launchctl remove com.docker.helper 2>&1 || true; "
set commands to commands & "rm -rf /opt/homebrew/Caskroom/docker-desktop 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/Caskroom/docker-desktop 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/etc/bash_completion.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/etc/bash_completion.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/share/fish/vendor_completions.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/share/fish/vendor_completions.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/share/zsh/site-functions/_docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/share/zsh/site-functions/_docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/bin/docker* 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "mkdir -p /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/bin/docker-compose 2>&1 || true; "
set commands to commands & "rm -f /usr/local/bin/docker-compose 2>&1 || true"
do shell script commands with administrator privileges
`;

            try {
              const { stdout: cleanupOutput } = await execAsync(`osascript -e '${completeCleanupScript.replace(/'/g, "'\\''")}'`);
              if (cleanupOutput) {
                sendOutput(cleanupOutput);
              }
              sendOutput('✓ Complete cleanup finished\n');
            } catch (error: any) {
              if (error.message.includes('User canceled')) {
                sendOutput('✗ Authentication cancelled by user\n');
                resolve({
                  success: false,
                  message: 'Installation cancelled. Authentication was dismissed.'
                });
                return;
              }
              sendOutput('⚠ Cleanup encountered issues (continuing anyway)\n');
            }

            // Step 2: Fresh install via Homebrew
            sendOutput('Step 2/2: Installing Docker Desktop via Homebrew...');
            sendOutput(`Running: ${brewPath} install --cask docker-desktop\n`);

            const reinstallProcess = spawn(brewPath, ['install', '--cask', 'docker-desktop'], {
              env: getEnvWithPath()
            });

            let reinstallStdout = '';

            reinstallProcess.stdout.on('data', (data) => {
              const output = data.toString();
              reinstallStdout += output;
              sendOutput(output);
            });

            reinstallProcess.stderr.on('data', (data) => {
              const output = data.toString();
              sendOutput(output);
            });

            reinstallProcess.on('close', async (reinstallCode) => {
              if (reinstallCode === 0) {
                // Verify Docker.app exists after reinstall
                try {
                  await execWithTimeout('test -d /Applications/Docker.app');

                  sendOutput('\n✓ Docker Desktop installation completed successfully!');
                  sendOutput('Launching Docker Desktop...');

                  await launchDockerDesktop();

                  sendOutput('✓ Docker Desktop launched');
                  sendOutput('\n═══════════════════════════════════════════════════');
                  sendOutput('Installation Complete');
                  sendOutput('═══════════════════════════════════════════════════');

                  resolve({
                    success: true,
                    message: 'Docker has been installed and launched successfully.'
                  });
                } catch (error) {
                  sendOutput('\n✗ Docker.app still not found after reinstallation');
                  sendOutput('\n═══════════════════════════════════════════════════');
                  resolve({
                    success: false,
                    message: 'Reinstallation completed but Docker.app was not found. Please try installing manually from docker.com.'
                  });
                }
              } else {
                sendOutput(`\n✗ Reinstallation failed with exit code ${reinstallCode}`);
                sendOutput('\n═══════════════════════════════════════════════════');
                resolve({
                  success: false,
                  message: 'Reinstallation failed. Please try installing manually from docker.com.'
                });
              }
            });

            return;
          }

          // Normal installation flow - Docker.app exists
          if (dockerAppExists) {
            sendOutput('\n✓ Docker Desktop installation completed successfully!');
            sendOutput('Launching Docker Desktop...');

            // Automatically launch Docker Desktop
            await launchDockerDesktop();

            sendOutput('✓ Docker Desktop launched');
            sendOutput('\n═══════════════════════════════════════════════════');
            sendOutput('Installation Complete');
            sendOutput('═══════════════════════════════════════════════════');

            resolve({
              success: true,
              message: 'Docker has been installed and launched successfully.'
            });
          } else {
            // Docker.app doesn't exist and wasn't marked as "already installed"
            sendOutput('\n✗ Docker.app not found after installation');
            sendOutput('\n═══════════════════════════════════════════════════');

            resolve({
              success: false,
              message: 'Installation completed but Docker.app was not found. Please try reinstalling or install manually from docker.com.'
            });
          }
        } else {
          sendOutput(`\n✗ Installation failed with exit code ${code}`);
          sendOutput('\n═══════════════════════════════════════════════════');

          let errorMessage = 'Installation failed. ';

          if (stderr.includes('Permission denied') || stderr.includes('EACCES')) {
            errorMessage += 'Permission denied. Please check your system permissions.';
          } else if (stderr.includes('already installed')) {
            errorMessage += 'Docker is already installed.';
          } else {
            errorMessage += 'Please try installing Docker manually from docker.com.';
          }

          resolve({
            success: false,
            message: errorMessage
          });
        }
      });
    });
  } catch (error: any) {
    log.error('Error during Docker installation:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    if (error.code === 'EACCES') {
      throw new SystemManagerError(
        SystemManagerErrorCode.PERMISSION_DENIED,
        'Permission denied while trying to install Docker',
        error
      );
    }

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to install Docker: ${error.message}`,
      error
    );
  }
}

export async function updateDockerViaHomebrew(window?: any): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'docker:update-output');

  try {
    // First check if Homebrew is installed
    const homebrewStatus = await checkHomebrewStatus();
    if (!homebrewStatus.installed) {
      return {
        success: false,
        message: 'Homebrew is not installed. Cannot update Docker Desktop.'
      };
    }

    const brewPath = homebrewStatus.path!;

    sendOutput('═══════════════════════════════════════════════════');
    sendOutput('Starting Docker Desktop Update');
    sendOutput('═══════════════════════════════════════════════════');
    sendOutput('You will be prompted to authenticate when needed...\n');

    // Create a temporary askpass script that shows a GUI password dialog
    // This will be used by sudo when Homebrew needs elevated privileges
    const tmpDir = require('os').tmpdir();
    const askpassScript = `${tmpDir}/askpass-${Date.now()}.sh`;
    const askpassContent = `#!/bin/bash
osascript -e 'display dialog "Docker Desktop update requires administrator privileges:" default answer "" with hidden answer' -e 'text returned of result'
`;

    return new Promise(async (resolve) => {
      // Write the askpass script
      const fs = require('fs').promises;
      try {
        await fs.writeFile(askpassScript, askpassContent, { mode: 0o755 });
      } catch (error: any) {
        sendOutput(`\n✗ Failed to create password prompt: ${error.message}`);
        resolve({
          success: false,
          message: 'Failed to set up authentication prompt.'
        });
        return;
      }

      sendOutput(`Running: ${brewPath} upgrade --cask docker-desktop --greedy\n`);

      // Run brew with SUDO_ASKPASS pointing to our GUI dialog script
      const env = {
        ...getEnvWithPath(),
        SUDO_ASKPASS: askpassScript,
        NONINTERACTIVE: '1' // Tell Homebrew to use non-interactive mode
      };

      const updateProcess = spawn(brewPath, ['upgrade', '--cask', 'docker-desktop', '--greedy'], {
        env
      });

      let stdout = '';
      let stderr = '';

      updateProcess.stdout.on('data', (data) => {
        const output = data.toString();
        stdout += output;
        sendOutput(output);
      });

      updateProcess.stderr.on('data', (data) => {
        const output = data.toString();
        stderr += output;
        sendOutput(output);
      });

      updateProcess.on('error', async (error) => {
        // Clean up the temporary askpass script
        try {
          await fs.unlink(askpassScript);
        } catch (err) {
          // Ignore cleanup errors
        }

        sendOutput(`\nError: ${error.message}`);
        resolve({
          success: false,
          message: `Failed to start update: ${error.message}`
        });
      });

      updateProcess.on('close', async (code) => {
        // Clean up the temporary askpass script
        try {
          await fs.unlink(askpassScript);
        } catch (err) {
          // Ignore cleanup errors
        }

        if (code === 0) {
          // Verify Docker.app actually exists
          try {
            await execWithTimeout('test -d /Applications/Docker.app');

            sendOutput('\n✓ Docker Desktop update completed successfully!');
            sendOutput('Launching Docker Desktop...');

            // Automatically launch Docker Desktop
            await launchDockerDesktop();

            sendOutput('✓ Docker Desktop launched');
            sendOutput('\n═══════════════════════════════════════════════════');
            sendOutput('Update Complete');
            sendOutput('═══════════════════════════════════════════════════');

            resolve({
              success: true,
              message: 'Docker Desktop has been updated and launched successfully.'
            });
          } catch (error) {
            // Docker.app doesn't exist
            sendOutput('\n✗ Docker.app not found after update');
            sendOutput('\n═══════════════════════════════════════════════════');

            resolve({
              success: false,
              message: 'Update completed but Docker.app was not found. Please use the "Reinstall" button to fix this.'
            });
          }
        } else {
          sendOutput(`\n✗ Update failed with exit code ${code}`);
          sendOutput('\n═══════════════════════════════════════════════════');

          let errorMessage = 'Update failed. ';

          if (stderr.includes('Permission denied') || stderr.includes('EACCES')) {
            errorMessage += 'Permission denied. Please check your system permissions.';
          } else if (stderr.includes('already installed') || stderr.includes('latest version')) {
            errorMessage += 'Docker Desktop is already at the latest version.';
          } else if (stderr.includes('not installed')) {
            errorMessage += 'Docker Desktop is not installed via Homebrew.';
          } else {
            errorMessage += 'Please try updating manually from docker.com.';
          }

          resolve({
            success: false,
            message: errorMessage
          });
        }
      });
    });
  } catch (error: any) {
    log.error('Error during Docker Desktop update:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    if (error.code === 'EACCES') {
      throw new SystemManagerError(
        SystemManagerErrorCode.PERMISSION_DENIED,
        'Permission denied while trying to update Docker Desktop',
        error
      );
    }

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to update Docker Desktop: ${error.message}`,
      error
    );
  }
}

export async function reinstallDockerViaHomebrew(window?: any, version?: { version: string; buildNumber: string; downloadUrl: string; isLatest: boolean }): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'docker:reinstall-output');

  try {
    const useSpecificVersion = version && !version.isLatest;

    // For Homebrew path we still need it for the latest install case
    const homebrewStatus = await checkHomebrewStatus();
    if (!homebrewStatus.installed && !useSpecificVersion) {
      return {
        success: false,
        message: 'Homebrew is not installed. Cannot reinstall Docker Desktop.'
      };
    }

    const brewPath = homebrewStatus.path;

    return new Promise(async (resolve) => {
      sendOutput('═══════════════════════════════════════════════════');
      sendOutput(`Starting Docker Desktop Reinstallation${useSpecificVersion ? ` (v${version!.version})` : ' (Latest)'}`);
      sendOutput('═══════════════════════════════════════════════════');
      sendOutput('You will be prompted to authenticate for privileged operations.\n');

      // Step 1: Remove system-level files and prepare directories with admin privileges
      sendOutput('Step 1/4: Removing system files and preparing directories (authentication required)...');

      const systemCleanupScript = `
set currentUser to do shell script "whoami"
set commands to "/Applications/Docker.app/Contents/MacOS/uninstall 2>&1 || true; "
set commands to commands & "rm -rf /Applications/Docker.app 2>&1 || true; "
set commands to commands & "launchctl remove com.docker.helper 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "mkdir -p /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "mkdir -p /usr/local/bin 2>&1 || true; "
set commands to commands & "chown -R " & currentUser & " /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "chown " & currentUser & " /usr/local/bin 2>&1 || true; "
set commands to commands & "chmod 755 /usr/local/cli-plugins 2>&1 || true; "
set commands to commands & "chmod 755 /usr/local/bin 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/etc/bash_completion.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/etc/bash_completion.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/share/fish/vendor_completions.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/share/fish/vendor_completions.d/docker* 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/share/zsh/site-functions/_docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/share/zsh/site-functions/_docker* 2>&1 || true; "
set commands to commands & "rm -f /usr/local/bin/docker* 2>&1 || true; "
set commands to commands & "rm -f /opt/homebrew/bin/docker-compose 2>&1 || true; "
set commands to commands & "rm -f /usr/local/bin/docker-compose 2>&1 || true; "
set commands to commands & "rm -f /usr/local/bin/hub-tool 2>&1 || true"
do shell script commands with administrator privileges
`;

      try {
        const { stdout: cleanupOutput } = await execAsync(`osascript -e '${systemCleanupScript.replace(/'/g, "'\\''")}'`);
        if (cleanupOutput) {
          sendOutput(cleanupOutput);
        }
        sendOutput('✓ System cleanup completed\n');
      } catch (error: any) {
        if (error.message.includes('User canceled')) {
          sendOutput('✗ Authentication cancelled by user\n');
          resolve({
            success: false,
            message: 'Reinstallation cancelled. Authentication was dismissed.'
          });
          return;
        }
        sendOutput('⚠ System cleanup encountered issues (continuing anyway)\n');
        if (error.stdout) sendOutput(error.stdout);
        if (error.stderr) sendOutput(error.stderr);
      }

      if (useSpecificVersion) {
        // ── Specific version path: download DMG → install via AppleScript ──

        // Step 2/3: Download the DMG
        const tmpDmg = `/tmp/Docker-${version!.version}.dmg`;
        sendOutput(`Step 2/3: Downloading Docker Desktop ${version!.version}...`);
        sendOutput(`Source: ${version!.downloadUrl}\n`);

        const downloadResult = await new Promise<boolean>((res) => {
          const dl = spawn('curl', ['-L', '-o', tmpDmg, '--progress-bar', version!.downloadUrl], {
            env: getEnvWithPath()
          });
          dl.stderr.on('data', (d) => sendOutput(d.toString()));
          dl.on('error', (e) => { sendOutput(`✗ Download error: ${e.message}\n`); res(false); });
          dl.on('close', (code) => res(code === 0));
        });

        if (!downloadResult) {
          resolve({ success: false, message: 'Failed to download Docker Desktop DMG.' });
          return;
        }
        sendOutput('✓ Download complete\n');

        // Step 3/3: Mount DMG, copy to /Applications (admin), unmount, cleanup
        sendOutput(`Step 3/3: Installing Docker Desktop ${version!.version} (authentication required)...`);

        try {
          // Mount (no admin needed)
          const { stdout: attachOut } = await execAsync(
            `hdiutil attach "${tmpDmg}" -nobrowse -quiet`,
            { env: getEnvWithPath() }
          );
          const mountMatch = attachOut.match(/\/Volumes\/[^\n]+/);
          const mountPoint = mountMatch ? mountMatch[0].trim() : '/Volumes/Docker';

          // Copy to /Applications and remove quarantine (admin needed)
          const installScript = `
set commands to "ditto '${mountPoint}/Docker.app' '/Applications/Docker.app' 2>&1; "
set commands to commands & "xattr -dr com.apple.quarantine /Applications/Docker.app 2>&1 || true"
do shell script commands with administrator privileges
`;
          try {
            await execAsync(`osascript -e '${installScript.replace(/'/g, "'\\''")}'`);
          } catch (err: any) {
            if (err.message?.includes('User canceled')) {
              sendOutput('✗ Authentication cancelled by user\n');
              await execAsync(`hdiutil detach "${mountPoint}" -force`, { env: getEnvWithPath() }).catch(() => {});
              await execAsync(`rm -f "${tmpDmg}"`, { env: getEnvWithPath() }).catch(() => {});
              resolve({ success: false, message: 'Reinstallation cancelled. Authentication was dismissed.' });
              return;
            }
            throw err;
          }

          // Unmount and cleanup
          await execAsync(`hdiutil detach "${mountPoint}" -force`, { env: getEnvWithPath() }).catch(() => {});
          await execAsync(`rm -f "${tmpDmg}"`, { env: getEnvWithPath() }).catch(() => {});

          sendOutput('✓ Installation complete\n');
        } catch (err: any) {
          await execAsync(`rm -f "${tmpDmg}"`, { env: getEnvWithPath() }).catch(() => {});
          sendOutput(`✗ Installation error: ${err.message}\n`);
          resolve({ success: false, message: `Failed to install Docker Desktop: ${err.message}` });
          return;
        }

        // Verify and launch
        try {
          await execWithTimeout('test -d /Applications/Docker.app');
          sendOutput('Launching Docker Desktop...');
          await launchDockerDesktop();
          sendOutput('✓ Docker Desktop launched');
          sendOutput('\n═══════════════════════════════════════════════════');
          sendOutput('Reinstallation Complete');
          sendOutput('═══════════════════════════════════════════════════');
          resolve({ success: true, message: `Docker Desktop ${version!.version} has been installed and launched successfully.` });
        } catch {
          sendOutput('\n✗ Docker.app not found after installation');
          sendOutput('\n═══════════════════════════════════════════════════');
          resolve({ success: false, message: 'Installation completed but Docker.app was not found. Please try installing manually from docker.com.' });
        }

      } else {
        // ── Latest version path: Homebrew cask ──

        // Step 2/3: Remove Homebrew caskroom
        sendOutput('Step 2/3: Cleaning up Homebrew metadata...');
        try {
          await execAsync(`rm -rf /opt/homebrew/Caskroom/docker-desktop /usr/local/Caskroom/docker-desktop`, {
            env: getEnvWithPath()
          });
          sendOutput('✓ Homebrew metadata cleaned\n');
        } catch {
          sendOutput('✓ Homebrew metadata cleaned\n');
        }

        // Step 3/3: Install via Homebrew
        sendOutput('Step 3/3: Installing Docker Desktop via Homebrew...');
        sendOutput(`Running: ${brewPath} install --cask docker-desktop\n`);

        const installProcess = spawn(brewPath!, ['install', '--cask', 'docker-desktop'], {
          env: getEnvWithPath()
        });

        installProcess.stdout.on('data', (data) => sendOutput(data.toString()));
        installProcess.stderr.on('data', (data) => sendOutput(data.toString()));

        installProcess.on('error', (error) => {
          sendOutput(`\nError: ${error.message}`);
          resolve({ success: false, message: `Failed to start reinstallation: ${error.message}` });
        });

        installProcess.on('close', async (code) => {
          if (code === 0) {
            try {
              await execWithTimeout('test -d /Applications/Docker.app');
              sendOutput('\n✓ Docker Desktop installation completed successfully!');
              sendOutput('Launching Docker Desktop...');
              await launchDockerDesktop();
              sendOutput('✓ Docker Desktop launched');
              sendOutput('\n═══════════════════════════════════════════════════');
              sendOutput('Reinstallation Complete');
              sendOutput('═══════════════════════════════════════════════════');
              resolve({ success: true, message: 'Docker Desktop has been reinstalled and launched successfully.' });
            } catch {
              sendOutput('\n✗ Docker.app not found after reinstallation');
              sendOutput('\n═══════════════════════════════════════════════════');
              resolve({ success: false, message: 'Reinstallation completed but Docker.app was not found. Please try installing manually from docker.com.' });
            }
          } else {
            sendOutput(`\n✗ Reinstallation failed with exit code ${code}`);
            sendOutput('\n═══════════════════════════════════════════════════');
            resolve({ success: false, message: 'Installation failed. Please check the output above for details, or try reinstalling Docker manually from docker.com.' });
          }
        });
      }
    });
  } catch (error: any) {
    log.error('Error during Docker Desktop reinstall:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    if (error.code === 'EACCES') {
      throw new SystemManagerError(
        SystemManagerErrorCode.PERMISSION_DENIED,
        'Permission denied while trying to reinstall Docker Desktop',
        error
      );
    }

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to reinstall Docker Desktop: ${error.message}`,
      error
    );
  }
}

// Homebrew Management Functions

export async function installHomebrew(window?: any): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'homebrew:install-output');

  try {
    sendOutput('═══════════════════════════════════════════════════');
    sendOutput('Starting Homebrew Installation');
    sendOutput('═══════════════════════════════════════════════════\n');

    sendOutput('Downloading and running Homebrew install script...');
    sendOutput('You will be prompted to authenticate.\n');

    // Use the official Homebrew install script
    const installScript = '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"';

    return new Promise((resolve) => {
      const installProcess = spawn('/bin/bash', ['-c', installScript], {
        env: getEnvWithPath()
      });

      let output = '';

      installProcess.stdout.on('data', (data) => {
        const text = data.toString();
        output += text;
        sendOutput(text);
      });

      installProcess.stderr.on('data', (data) => {
        const text = data.toString();
        output += text;
        sendOutput(text);
      });

      installProcess.on('error', (error) => {
        sendOutput(`\nError: ${error.message}`);
        resolve({
          success: false,
          message: `Failed to start installation: ${error.message}`
        });
      });

      installProcess.on('close', async (code) => {
        if (code === 0) {
          sendOutput('\n✓ Homebrew installation completed successfully!');
          sendOutput('\n═══════════════════════════════════════════════════');
          sendOutput('Installation Complete');
          sendOutput('═══════════════════════════════════════════════════');

          resolve({
            success: true,
            message: 'Homebrew has been installed successfully.'
          });
        } else {
          sendOutput(`\n✗ Installation failed with exit code ${code}`);
          sendOutput('\n═══════════════════════════════════════════════════');

          resolve({
            success: false,
            message: 'Installation failed. Please check the output for details.'
          });
        }
      });
    });
  } catch (error: any) {
    log.error('Error during Homebrew installation:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to install Homebrew: ${error.message}`,
      error
    );
  }
}

export async function updateHomebrew(window?: any): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'homebrew:update-output');

  try {
    const homebrewStatus = await checkHomebrewStatus();
    if (!homebrewStatus.installed || !homebrewStatus.path) {
      return {
        success: false,
        message: 'Homebrew is not installed. Cannot update.'
      };
    }

    const brewPath = homebrewStatus.path;

    return new Promise((resolve) => {
      sendOutput('═══════════════════════════════════════════════════');
      sendOutput('Starting Homebrew Update');
      sendOutput('═══════════════════════════════════════════════════');
      sendOutput(`Running: ${brewPath} update\n`);

      const updateProcess = spawn(brewPath, ['update'], {
        env: getEnvWithPath()
      });

      let output = '';

      updateProcess.stdout.on('data', (data) => {
        const text = data.toString();
        output += text;
        sendOutput(text);
      });

      updateProcess.stderr.on('data', (data) => {
        const text = data.toString();
        output += text;
        sendOutput(text);
      });

      updateProcess.on('error', (error) => {
        sendOutput(`\nError: ${error.message}`);
        resolve({
          success: false,
          message: `Failed to start update: ${error.message}`
        });
      });

      updateProcess.on('close', async (code) => {
        if (code === 0) {
          sendOutput('\n✓ Homebrew update completed successfully!');
          sendOutput('\n═══════════════════════════════════════════════════');
          sendOutput('Update Complete');
          sendOutput('═══════════════════════════════════════════════════');

          resolve({
            success: true,
            message: 'Homebrew has been updated successfully.'
          });
        } else {
          sendOutput(`\n✗ Update failed with exit code ${code}`);
          sendOutput('\n═══════════════════════════════════════════════════');

          resolve({
            success: false,
            message: 'Update failed. Please check the output for details.'
          });
        }
      });
    });
  } catch (error: any) {
    log.error('Error during Homebrew update:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to update Homebrew: ${error.message}`,
      error
    );
  }
}

export async function reinstallHomebrew(window?: any): Promise<InstallResult> {
  const sendOutput = createOutputSender(window ?? null, 'homebrew:reinstall-output');

  try {
    sendOutput('═══════════════════════════════════════════════════');
    sendOutput('Starting Homebrew Reinstallation');
    sendOutput('═══════════════════════════════════════════════════\n');

    // Step 1: Manual cleanup of Homebrew directories with admin privileges
    sendOutput('Step 1/3: Cleaning up Homebrew directories (you will be prompted to authenticate)...');

    const cleanupScript = `
set commands to "rm -rf /opt/homebrew 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/Homebrew 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/Caskroom 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/Cellar 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/bin/brew 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/var/homebrew 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/etc/bash_completion.d 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/share/zsh/site-functions 2>&1 || true; "
set commands to commands & "rm -rf /usr/local/share/fish/vendor_completions.d 2>&1 || true; "
set commands to commands & "rm -rf ~/Library/Caches/Homebrew 2>&1 || true; "
set commands to commands & "rm -rf ~/Library/Logs/Homebrew 2>&1 || true"
do shell script commands with administrator privileges
`;

    try {
      const { stdout: cleanupOutput } = await execAsync(`osascript -e '${cleanupScript.replace(/'/g, "'\\''")}'`);
      if (cleanupOutput) {
        sendOutput(cleanupOutput);
      }
      sendOutput('✓ Cleanup completed\n');
    } catch (error: any) {
      if (error.message.includes('User canceled')) {
        sendOutput('✗ Authentication cancelled by user\n');
        return {
          success: false,
          message: 'Reinstallation cancelled. Authentication was dismissed.'
        };
      }
      sendOutput('⚠ Cleanup encountered some issues (continuing anyway)\n');
    }

    // Step 2: Download and run uninstall script with admin privileges
    sendOutput('Step 2/3: Running Homebrew uninstall script...');

    const uninstallWithSudo = `
set uninstallScript to do shell script "curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh"
do shell script "/bin/bash -c " & quoted form of uninstallScript with administrator privileges
`;

    try {
      const uninstallProcess = spawn('osascript', ['-e', uninstallWithSudo], {
        env: getEnvWithPath()
      });

      let uninstallOutput = '';

      uninstallProcess.stdout.on('data', (data) => {
        const text = data.toString();
        uninstallOutput += text;
        sendOutput(text);
      });

      uninstallProcess.stderr.on('data', (data) => {
        const text = data.toString();
        uninstallOutput += text;
        sendOutput(text);
      });

      await new Promise<void>((resolve, reject) => {
        uninstallProcess.on('error', (error) => {
          reject(error);
        });

        uninstallProcess.on('close', (code) => {
          if (code === 0 || uninstallOutput.includes('Homebrew is not installed')) {
            resolve();
          } else {
            reject(new Error(`Uninstall failed with exit code ${code}`));
          }
        });
      });

      sendOutput('✓ Uninstall completed\n');
    } catch (error: any) {
      if (error.message.includes('User canceled')) {
        sendOutput('✗ Authentication cancelled by user\n');
        return {
          success: false,
          message: 'Reinstallation cancelled. Authentication was dismissed.'
        };
      }
      sendOutput('⚠ Uninstall script encountered issues (continuing with installation)\n');
    }

    // Step 3: Install Homebrew
    sendOutput('Step 3/3: Installing Homebrew...\n');

    const installScript = 'NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"';

    return new Promise((resolve) => {
      const installProcess = spawn('/bin/bash', ['-c', installScript], {
        env: { ...getEnvWithPath(), NONINTERACTIVE: '1' }
      });

      let installOutput = '';

      installProcess.stdout.on('data', (data) => {
        const text = data.toString();
        installOutput += text;
        sendOutput(text);
      });

      installProcess.stderr.on('data', (data) => {
        const text = data.toString();
        installOutput += text;
        sendOutput(text);
      });

      installProcess.on('error', (error) => {
        sendOutput(`\nError: ${error.message}`);
        resolve({
          success: false,
          message: `Failed to install: ${error.message}`
        });
      });

      installProcess.on('close', async (installCode) => {
        if (installCode === 0) {
          sendOutput('\n✓ Homebrew reinstallation completed successfully!');
          sendOutput('\n═══════════════════════════════════════════════════');
          sendOutput('Reinstallation Complete');
          sendOutput('═══════════════════════════════════════════════════');

          resolve({
            success: true,
            message: 'Homebrew has been reinstalled successfully.'
          });
        } else {
          sendOutput(`\n✗ Installation failed with exit code ${installCode}`);
          sendOutput('\n═══════════════════════════════════════════════════');

          resolve({
            success: false,
            message: 'Reinstallation failed. Please check the output for details.'
          });
        }
      });
    });
  } catch (error: any) {
    log.error('Error during Homebrew reinstall:', error);
    sendOutput(`\n✗ Unexpected error: ${error.message}`);

    throw new SystemManagerError(
      SystemManagerErrorCode.INSTALL_FAILED,
      `Failed to reinstall Homebrew: ${error.message}`,
      error
    );
  }
}
