import { promises as fs } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
import log from 'electron-log';
import { BrowserWindow } from 'electron';
import { execAsync } from '../utils/shell-utils';

export interface GitConfigStatus {
  gitInstalled: boolean;
  gitconfigExists: boolean;
  name?: string;
  email?: string;
  version?: string;
  path?: string;
}

export interface GitConfigOptions {
  name: string;
  email: string;
}

/**
 * Check if git command exists and if ~/.gitconfig exists with name/email
 */
export async function checkGitConfigStatus(): Promise<GitConfigStatus> {
  // First, check if git command exists
  let gitInstalled = false;
  let version: string | undefined;
  let path: string | undefined;

  try {
    const { stdout: pathOutput } = await execAsync('which git');
    path = pathOutput.trim();
    gitInstalled = true;

    // Get Git version
    try {
      const { stdout: versionOutput } = await execAsync('git --version');
      // Output format: "git version 2.39.2 (Apple Git-143)"
      const match = versionOutput.match(/git version ([\d.]+)/);
      if (match) {
        version = match[1];
      }
    } catch (error) {
      log.warn('Failed to get git version:', error);
    }
  } catch (error) {
    log.warn('Git command not found');
    return {
      gitInstalled: false,
      gitconfigExists: false
    };
  }

  const gitconfigPath = join(homedir(), '.gitconfig');

  try {
    // Check if file exists
    await fs.access(gitconfigPath);

    // Try to get git user name and email using git commands
    let name: string | undefined;
    let email: string | undefined;

    try {
      const { stdout: nameOutput } = await execAsync('git config --global user.name');
      name = nameOutput.trim();
    } catch (error) {
      log.warn('Failed to get git user.name:', error);
    }

    try {
      const { stdout: emailOutput } = await execAsync('git config --global user.email');
      email = emailOutput.trim();
    } catch (error) {
      log.warn('Failed to get git user.email:', error);
    }

    return {
      gitInstalled: true,
      gitconfigExists: true,
      name,
      email,
      version,
      path
    };
  } catch (error: any) {
    if (error.code === 'ENOENT') {
      return {
        gitInstalled: true,
        gitconfigExists: false,
        version,
        path
      };
    }
    log.error('Failed to check git config status:', error);
    throw error;
  }
}

/**
 * Install Git via Homebrew
 */
export async function installGit(window: BrowserWindow | null): Promise<{ success: boolean; message: string }> {
  const sendOutput = (message: string) => {
    log.info(message);
    if (window?.webContents) {
      window.webContents.send('git:install-output', message + '\n');
    }
  };

  try {
    sendOutput('Installing Git via Homebrew...');
    sendOutput('Running: brew install git');
    sendOutput('');

    const { stdout, stderr } = await execAsync('brew install git');

    if (stdout) {
      sendOutput(stdout);
    }
    if (stderr) {
      sendOutput(stderr);
    }

    sendOutput('');
    sendOutput('Git installed successfully!');

    return {
      success: true,
      message: 'Git installed successfully'
    };
  } catch (error: any) {
    const errorMessage = error.message || 'Failed to install Git';
    sendOutput('');
    sendOutput(`Error: ${errorMessage}`);
    log.error('Failed to install Git:', error);

    return {
      success: false,
      message: errorMessage
    };
  }
}

/**
 * Update git config with name and email
 */
export async function updateGitConfig(options: GitConfigOptions): Promise<{ success: boolean; message: string }> {
  try {
    // Validate inputs
    if (!options.name || !options.name.trim()) {
      return {
        success: false,
        message: 'Name is required'
      };
    }

    if (!options.email || !options.email.trim()) {
      return {
        success: false,
        message: 'Email is required'
      };
    }

    // Basic email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(options.email.trim())) {
      return {
        success: false,
        message: 'Invalid email format'
      };
    }

    // Set git config
    await execAsync(`git config --global user.name "${options.name.trim()}"`);
    await execAsync(`git config --global user.email "${options.email.trim()}"`);

    log.info('Git config updated successfully');

    return {
      success: true,
      message: 'Git configuration saved successfully'
    };
  } catch (error: any) {
    log.error('Failed to update git config:', error);
    return {
      success: false,
      message: error.message || 'Failed to update git configuration'
    };
  }
}
