import { execAsync, getEnvWithPath } from '../utils/shell-utils';
import log from 'electron-log';
import { BrowserWindow } from 'electron';
import { spawn } from 'child_process';
import { createOutputSender } from '../utils/ipc-output-helper';

export interface FrpcStatus {
  installed: boolean;
  version: string | null;
  path: string | null;
  updateAvailable: boolean;
  latestVersion: string | null;
}

/**
 * Check if frpc is installed and get its version
 */
export async function checkFrpcStatus(): Promise<FrpcStatus> {
  try {
    // Check if frpc is installed
    const whichResult = await execAsync('which frpc').catch(() => ({ stdout: '', stderr: '' }));
    const frpcPath = whichResult.stdout.trim();

    if (!frpcPath) {
      return {
        installed: false,
        version: null,
        path: null,
        updateAvailable: false,
        latestVersion: null
      };
    }

    // Get current version
    const versionResult = await execAsync('frpc --version').catch(() => ({ stdout: '', stderr: '' }));
    const versionMatch = versionResult.stdout.match(/(\d+\.\d+\.\d+)/);
    const currentVersion = versionMatch ? versionMatch[1] : null;

    // Check for updates using brew
    let updateAvailable = false;
    let latestVersion = null;

    try {
      const infoResult = await execAsync('brew info frpc --json=v2');
      const info = JSON.parse(infoResult.stdout);

      if (info.formulae && info.formulae.length > 0) {
        const formula = info.formulae[0];
        latestVersion = formula.versions?.stable || null;

        if (currentVersion && latestVersion) {
          updateAvailable = currentVersion !== latestVersion;
        }
      }
    } catch (error) {
      log.warn('Failed to check for frpc updates:', error);
    }

    return {
      installed: true,
      version: currentVersion,
      path: frpcPath,
      updateAvailable,
      latestVersion
    };
  } catch (error) {
    log.error('Error checking frpc status:', error);
    throw error;
  }
}

/**
 * Install frpc via Homebrew
 */
export async function installFrpcViaHomebrew(window: BrowserWindow | null): Promise<{ success: boolean; message: string }> {
  const sendOutput = createOutputSender(window, 'frpc:install-output');

  try {
    sendOutput('Installing FRPC via Homebrew...');

    return new Promise((resolve) => {
      const installProcess = spawn('brew', ['install', 'frpc'], {
        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('close', (code) => {
        if (code === 0) {
          sendOutput('\n✓ FRPC installed successfully');
          resolve({
            success: true,
            message: 'FRPC installed successfully'
          });
        } else {
          sendOutput(`\n✗ Installation failed with code ${code}`);
          resolve({
            success: false,
            message: `Failed to install FRPC (exit code: ${code})`
          });
        }
      });

      installProcess.on('error', (error) => {
        sendOutput(`\n✗ Error: ${error.message}`);
        resolve({
          success: false,
          message: error.message
        });
      });
    });
  } catch (error: any) {
    log.error('Error installing frpc:', error);
    return {
      success: false,
      message: error.message || 'Failed to install frpc'
    };
  }
}

/**
 * Update frpc via Homebrew
 */
export async function updateFrpcViaHomebrew(window: BrowserWindow | null): Promise<{ success: boolean; message: string }> {
  const sendOutput = createOutputSender(window, 'frpc:update-output');

  try {
    sendOutput('Updating FRPC via Homebrew...');

    return new Promise((resolve) => {
      const updateProcess = spawn('brew', ['upgrade', 'frpc'], {
        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('close', (code) => {
        if (code === 0) {
          sendOutput('\n✓ FRPC updated successfully');
          resolve({
            success: true,
            message: 'FRPC updated successfully'
          });
        } else {
          sendOutput(`\n✗ Update failed with code ${code}`);
          resolve({
            success: false,
            message: `Failed to update FRPC (exit code: ${code})`
          });
        }
      });

      updateProcess.on('error', (error) => {
        sendOutput(`\n✗ Error: ${error.message}`);
        resolve({
          success: false,
          message: error.message
        });
      });
    });
  } catch (error: any) {
    log.error('Error updating frpc:', error);
    return {
      success: false,
      message: error.message || 'Failed to update frpc'
    };
  }
}

/**
 * Uninstall frpc via Homebrew
 */
export async function uninstallFrpcViaHomebrew(window: BrowserWindow | null): Promise<{ success: boolean; message: string }> {
  const sendOutput = createOutputSender(window, 'frpc:uninstall-output');

  try {
    sendOutput('Uninstalling FRPC via Homebrew...');

    return new Promise((resolve) => {
      const uninstallProcess = spawn('brew', ['uninstall', 'frpc'], {
        env: getEnvWithPath()
      });

      let output = '';

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

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

      uninstallProcess.on('close', (code) => {
        if (code === 0) {
          sendOutput('\n✓ FRPC uninstalled successfully');
          resolve({
            success: true,
            message: 'FRPC uninstalled successfully'
          });
        } else {
          sendOutput(`\n✗ Uninstall failed with code ${code}`);
          resolve({
            success: false,
            message: `Failed to uninstall FRPC (exit code: ${code})`
          });
        }
      });

      uninstallProcess.on('error', (error) => {
        sendOutput(`\n✗ Error: ${error.message}`);
        resolve({
          success: false,
          message: error.message
        });
      });
    });
  } catch (error: any) {
    log.error('Error uninstalling frpc:', error);
    return {
      success: false,
      message: error.message || 'Failed to uninstall frpc'
    };
  }
}

/**
 * Reinstall frpc via Homebrew
 */
export async function reinstallFrpcViaHomebrew(window: BrowserWindow | null): Promise<{ success: boolean; message: string }> {
  const sendOutput = createOutputSender(window, 'frpc:reinstall-output');

  try {
    sendOutput('Reinstalling FRPC via Homebrew...');
    sendOutput('Step 1: Uninstalling FRPC...');

    // Uninstall first
    const uninstallSuccess = await new Promise<boolean>((resolve) => {
      const uninstallProcess = spawn('brew', ['uninstall', 'frpc', '--force'], {
        env: getEnvWithPath()
      });

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

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

      uninstallProcess.on('close', (code) => {
        if (code === 0) {
          sendOutput('✓ Uninstall complete\n');
          resolve(true);
        } else {
          sendOutput(`✗ Uninstall failed with code ${code}\n`);
          resolve(false);
        }
      });

      uninstallProcess.on('error', () => {
        resolve(false);
      });
    });

    if (!uninstallSuccess) {
      return {
        success: false,
        message: 'Failed to uninstall FRPC'
      };
    }

    sendOutput('Step 2: Installing FRPC...');

    // Then install
    return new Promise((resolve) => {
      const installProcess = spawn('brew', ['install', 'frpc'], {
        env: getEnvWithPath()
      });

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

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

      installProcess.on('close', (code) => {
        if (code === 0) {
          sendOutput('\n✓ FRPC reinstalled successfully');
          resolve({
            success: true,
            message: 'FRPC reinstalled successfully'
          });
        } else {
          sendOutput(`\n✗ Reinstall failed with code ${code}`);
          resolve({
            success: false,
            message: `Failed to reinstall FRPC (exit code: ${code})`
          });
        }
      });

      installProcess.on('error', (error) => {
        sendOutput(`\n✗ Error: ${error.message}`);
        resolve({
          success: false,
          message: error.message
        });
      });
    });
  } catch (error: any) {
    log.error('Error reinstalling frpc:', error);
    return {
      success: false,
      message: error.message || 'Failed to reinstall frpc'
    };
  }
}
