#!/usr/bin/env node
import { Command } from 'commander';
import prompts from 'prompts';
import { cyan, green, red } from 'picocolors'; 
import { readJson, writeJson, existsSync } from 'fs-extra';
import { resolve } from 'path';
import { logError, logWarn, logSuccess } from './utils';
import { loadJson, writePublicationJson, PublicationData } from './readWritePublications';
import { PromptConfig, createPrompts } from './prompts';
import { updateFiles } from './fileUpdates';
import { checkArn, checkNotEmpty, stripSpace, checkName, checkDomain } from './checkers';
const program = new Command();

const handleSigTerm = () => process.exit(0)

process.on('SIGINT', handleSigTerm);
process.on('SIGTERM', handleSigTerm);

(async ()=> {
    const packageObj = await loadJson(resolve('./package.json'), {
      error: 'Error loading package.json',
      success: null
    });
    
    program
      .version(
        packageObj.version,
        '-v, --version',
        'Output the current version of create new publication.'
      )
      .helpOption('-h, --help', 'Display this help message.')
      .option('--db, --debug', 'output extra debugging')
      .option('-p, --platform <type>', 'platform')
      .option('-t, --title <type>', 'publication title')
      .option('-c, --cue-name <type>', 'name in cue')
      .option('--vr', '--vr-steps <type>', 'number of vr steps')
      .option('-f, --func-steps <type>', 'number of functional steps')
      .option('-d, --domain <type>', 'domain of site')
      .allowUnknownOption();
    program.parse(process.argv);
  
})();

const opts = program.opts()

const platforms: prompts.Choice[] = [
  {
    title: 'nationals',
    value: 'nationals'
  }, 
  { 
    title: 'ronionals', 
    value: 'ronionals',
  },
  {
    title: 'regionals',
    value: 'regionals',
  }, 
  {
    title: "visionals",
    value: "visionals",
  }
];

async function run () {
  const currentDir = process.cwd();
  const webRepoPath = currentDir.includes('web') ? currentDir : null;

  if (!webRepoPath) {
    throw new Error('This script must be run inside the web repository.');
  }

  const publicationJson = resolve(webRepoPath, 'drone', 'publication.json');

  if (!existsSync(publicationJson)) {
    throw new Error(`Required file not found: ${publicationJson}`);
  }

  const publicationList = await loadJson(publicationJson, {
    error: 'Error loading publication list',
    success: 'Publication list loaded successfully'
  });

  const platformObj =  platforms.find(({title})=> title === opts.platform);

  let config: PublicationData  = {
    domain: opts.domain,
    platform: (platformObj) ? platformObj.value : null,
    title: opts.title,
    stackAlias: opts.cueName,
    vr: opts.vrSteps,
    func: opts.funcSteps,
    arn: {
      dev: '',
      qa: '',
      preprod: '',
      prod: '',
    },
    autoScaling: {
      min: 5,
      max: 20,
    }
  };

  config = await createPrompts(config, 'platform', {
    type: 'select',
    name: 'platform',
    message: 'What Platform is it on?',
    choices: platforms,
    errorMsg: 'Platform is required'
  });
  console.log(config, publicationList, publicationList[config.platform])
  config = await createPrompts(config, 'title', {
    type: 'text',
    name: 'title',
    errorMsg: 'Publication Name is required',
    message: 'What is the Name of the publication?',
    validate: checkName(publicationList[config.platform]) as  PromptConfig['validate']
  });


  config = await createPrompts(config, 'cueName', [
    {
        type: 'confirm',
        name: 'hasCue',
        message: 'Is the publication name different in cue?',
        initial: false
      },
      {
        type: prev => prev ? 'text' : null,
        name: 'stackAlias',
        message: 'What is the publication\'s name in cue?',
        validate: checkNotEmpty as  PromptConfig['validate']
      }
  ]);



  if(!config.domain) {
    const { domain } = await prompts({
      type: 'text',
      name: 'domain',
      message: 'What is the publication\'s domain?',
      validate: checkDomain
    });

    config.domain = domain;
  }

  if(!config.vr) {
    const { vr } = await prompts({
      type: 'number',
      name: 'vr',
      message: 'How many vr steps for this publication?',
      initial: 5
    });

    config.vr = vr;
  }

  if(!config.func) {
    const { func } = await prompts({
    type: 'number',
    name: 'func',
    message: 'How many Functional steps for this publication?',
    initial: 14
  },);

    config.func = func;
  }



  const awsResponses = await prompts([
    {
      type: 'confirm',
      name: 'arnTrue',
      message: 'Do you know the certificateArn for each environment?',
      initial: true
    },
    {
      type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null,
      name: 'devCertificateArn',
      message: 'What is certificateArn for dev environment?',
      validate: checkArn
    },
    {
      type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null,
      name: 'qaCertificateArn',
      message: 'What is certificateArn for QA environment?',
      validate: checkArn
    },
    {
      type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null,
      name: 'preprodCertificateArn',
      message: 'What is certificateArn for PreProd environment?',
      validate: checkArn
    },
    {
      type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null,
      name: 'prodCertificateArn',
      message: 'What is certificateArn for Prod environment?',
      validate: checkArn
    },
    {
      type: 'number',
      name: 'autoScalingMin',
      message: 'AWS autoscaling, what is the minimum capacity?',
      initial: 5,
    },
    {
      type: 'number',
      name: 'autoScalingMax',
      message: 'AWS autoscaling, what is the maximum capacity?',
      initial: 20,
    },
  ]);

  config.arn = {
    dev: awsResponses.devCertificateArn,
    qa: awsResponses.qaCertificateArn,
    preprod: awsResponses.preprodCertificateArn,
    prod: awsResponses.prodCertificateArn,
  };

  config.autoScaling = {
    min: awsResponses.autoScalingMin,
    max: awsResponses.autoScalingMax,
  };
  
  await updateFiles(config);
};

async function exit(reason: any) {
  console.log()
  console.log('Aborting installation.')
  if (reason.command) {
    console.log(`  ${cyan(reason.command)} has failed.`)
  } else {
    console.log(
      red('Unexpected error. Please report it as a bug:') + '\n',
      reason
    )
  }
  process.exit(1)
}

run().catch(exit);

