/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import type { CommandModule } from 'yargs';
import { debugLogger, getErrorMessage } from '@google/gemini-cli-core';
import { requestConsentNonInteractive } from '../../config/extensions/consent.js';
import { ExtensionManager } from '../../config/extension-manager.js';
import { loadSettings } from '../../config/settings.js';
import { promptForSetting } from '../../config/extensions/extensionSettings.js';
import { exitCli } from '../utils.js';

interface UninstallArgs {
  names?: string[]; // can be extension names or source URLs.
  all?: boolean;
}

export async function handleUninstall(args: UninstallArgs) {
  try {
    const workspaceDir = process.cwd();
    const extensionManager = new ExtensionManager({
      workspaceDir,
      requestConsent: requestConsentNonInteractive,
      requestSetting: promptForSetting,
      settings: loadSettings(workspaceDir).merged,
    });
    await extensionManager.loadExtensions();

    let namesToUninstall: string[] = [];
    if (args.all) {
      namesToUninstall = extensionManager
        .getExtensions()
        .map((ext) => ext.name);
    } else if (args.names) {
      namesToUninstall = [...new Set(args.names)];
    }

    if (namesToUninstall.length === 0) {
      if (args.all) {
        debugLogger.log('No extensions currently installed.');
      }
      return;
    }

    const errors: Array<{ name: string; error: string }> = [];
    for (const name of namesToUninstall) {
      try {
        await extensionManager.uninstallExtension(name, false);
        debugLogger.log(`Extension "${name}" successfully uninstalled.`);
      } catch (error) {
        errors.push({ name, error: getErrorMessage(error) });
      }
    }

    if (errors.length > 0) {
      for (const { name, error } of errors) {
        debugLogger.error(`Failed to uninstall "${name}": ${error}`);
      }
      process.exit(1);
    }
  } catch (error) {
    debugLogger.error(getErrorMessage(error));
    process.exit(1);
  }
}

export const uninstallCommand: CommandModule = {
  command: 'uninstall [names..]',
  describe: 'Uninstalls one or more extensions.',
  builder: (yargs) =>
    yargs
      .positional('names', {
        describe:
          'The name(s) or source path(s) of the extension(s) to uninstall.',
        type: 'string',
        array: true,
      })
      .option('all', {
        type: 'boolean',
        describe: 'Uninstall all installed extensions.',
        default: false,
      })
      .check((argv) => {
        if (!argv.all && (!argv.names || argv.names.length === 0)) {
          throw new Error(
            'Please include at least one extension name to uninstall as a positional argument, or use the --all flag.',
          );
        }
        return true;
      }),
  handler: async (argv) => {
    await handleUninstall({
      // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
      names: argv['names'] as string[] | undefined,
      // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
      all: argv['all'] as boolean,
    });
    await exitCli();
  },
};
