import clear from 'clear';

// Import helpers
import showChooser from '../helpers/showChooser';
import getDeploymentConfig from '../operations/getDeploymentConfig';
import print from '../helpers/print';
import prompt from '../helpers/prompt';
import exec from '../helpers/exec';

// Import shared types
import Deployment from '../types/Deployment';
import ChooserOption from '../types/ChooserOption';

/**
 * Show and/or modify environment variables
 * @author Gabe Abrams
 * @param deployment the currently selected deployment
 */
const showModifyEnvVars = async (deployment: Deployment) => {
  while (true) {
    // Show loading indicator
    clear();
    console.log('Loading environment variables...\n');

    // Get environment variables
    const deployConfig = getDeploymentConfig(deployment);

    // Create options
    const envVarNames = Object.keys(deployConfig.appEnvironment ?? {});
    // Sort env var names alphabetically (a-z)
    envVarNames.sort((a, b) => {
      return a.localeCompare(b);
    });
    const options: ChooserOption[] = envVarNames.map((name) => {
      return {
        description: `${name}=${deployConfig.appEnvironment[name]}`,
      };
    });

    // Add "create new" option
    options.push({
      description: '[New Environment Var]',
      tag: 'N',
    });

    // Add "back to main menu" option
    options.push({
      description: '[Back to Main Menu]',
      tag: 'B',
    });

    // Show chooser
    const option = showChooser({
      question: 'Choose environment variable to modify:',
      options,
    });

    // Handle "back"
    if (option.tag === 'B') {
      return;
    }

    // Get variable name
    let varName: string;
    if (option.tag === 'N') {
      // Handle "create new" option
      clear();
      print.subtitle('Create new environment variable:');
      varName = prompt('Name: ');
      clear();
    } else {
      // Edit existing variable
      clear();
      varName = envVarNames[option.index];
    }

    // Add variable name prefix
    const fullVarName = `appEnvironment/${varName}`;

    // Ask for a new value
    if (option.tag === 'N') {
      print.subtitle('Enter a value or leave empty to cancel:');
    } else {
      print.subtitle('Enter a new value or leave empty to delete:');
    }
    const newValue = prompt(`${varName}=`, true);

    // Delete
    if (newValue.length === 0) {
      if (option.tag === 'N') {
        clear();
        print.title('Invalid Value');
        console.log('');
        print.enterToContinue();
        continue;
      }

      // Not new. Confirm delete
      clear();
      const { tag } = showChooser({
        question: `Are you sure you want to delete "${varName}"?`,
        options: [
          {
            description: 'Yes',
            tag: 'Y',
          },
          {
            description: 'No',
            tag: 'N',
          },
        ],
      });
      if (tag === 'N') {
        // Cancel
        clear();
        print.title('Cancelled!');
        console.log('');
        print.enterToContinue();
        continue;
      }
      
      // Delete
      clear();
      console.log('Deleting...\n');
      exec(
        `./node_modules/.bin/caccl-deploy update --profile ${deployment.profile} --app ${deployment.app} -D ${fullVarName}`,
        true,
      );

      // Wait extra for caccl deploy
      await new Promise((resolve) => {
        setTimeout(resolve, 2000);
      });
      
      // Confirmation
      clear();
      print.title(`${varName} Deleted Successfully`);
      console.log('');
      print.enterToContinue();
      continue;
    }

    // Update value/create variable
    clear();
    console.log('Working...\n');
    exec(
      `./node_modules/.bin/caccl-deploy update --profile ${deployment.profile} --app ${deployment.app} ${fullVarName} "${newValue}"`,
      true,
    );

    // Wait extra for caccl deploy
    await new Promise((resolve) => {
      setTimeout(resolve, 2000);
    });

    // Confirmation
    clear();
    print.title(`${varName} ${option.tag === 'N' ? 'Created' : 'Updated'} Successfully`);
    console.log('');
    print.enterToContinue();
    continue;
  }
};

export default showModifyEnvVars;
