const chalk = require('chalk')
const inquirer = require('inquirer')
const { clearConsole } = require('./util/clearConsole')
const shouldBackend = require('./util/shouldBackend')
const loadUserOptions = require('./loadUserOptions')
const { executeCommands } = require('./util/installDeps')
const { error, stopSpinner, log, hasYarn, hasPnpm3OrLater, logWithSpinner, execa } = require('@vue/cli-shared-utils')

async function release (options = {}, context = process.cwd()) {
  const packageManagerChoices = []

  await clearConsole(true)
  packageManagerChoices.push({
    name: 'Use NPM',
    value: 'npm',
    short: 'NPM'
  })

  // ask for packageManager once
  if (hasYarn() || hasPnpm3OrLater()) {
    if (hasYarn()) {
      packageManagerChoices.push({
        name: 'Use Yarn',
        value: 'yarn',
        short: 'Yarn'
      })
    }

    if (hasPnpm3OrLater()) {
      packageManagerChoices.push({
        name: 'Use PNPM',
        value: 'pnpm',
        short: 'PNPM'
      })
    }
  }

  const packageManager = options.packageManager || await inquirer.prompt([
    {
      name: 'packageManager',
      type: 'list',
      message: 'Pick the package manager to use in this project:',
      choices: packageManagerChoices
    }
  ]).then(list => list.packageManager)

  const userOptions = await loadUserOptions(context)

  const isShouldBackend = await shouldBackend(userOptions.type)

  const frontendPath = isShouldBackend ? userOptions.type === 'saas' ? `${context}/central` : `${context}/frontend` : context

  if (!options.force) {
    // run tests
    log()
    logWithSpinner('🚨', 'Running frontend tests...')
    await executeCommands(frontendPath, packageManager, 'test')
    stopSpinner()

    log()
    if (isShouldBackend) {
      logWithSpinner('🚨', 'Running backend tests...')
      await executeCommands(context, 'composer', 'test')
      log()
      stopSpinner()
    }
  }

  log()
  if (isShouldBackend) {
    logWithSpinner('🚨', 'Running lang files...')
    await executeCommands(context, 'composer', 'lang:generate')
    log()
    stopSpinner()
  }

  log()
  logWithSpinner('🔥', `Generating release...`)
  if (userOptions.type === 'landing') {
    await executeCommands(frontendPath, packageManager, 'generate')
  } else {
    await execa(
      'vue-cli-service build --no-clean',
      { cwd: frontendPath, shell: true }
    )
  }

  if (userOptions.type === 'saas') {
    await execa(
      'vue-cli-service build --no-clean',
      { cwd: `${context}/tenant`, shell: true }
    )
  }
  // run vue cli build

  log()
  if (!options.force) {
    logWithSpinner('🚀', 'Update version')
    await executeCommands(frontendPath, packageManager, 'update')
    if (isShouldBackend) {
      await executeCommands(context, packageManager, 'update')
    }
    stopSpinner()
  }

  stopSpinner()
  log()
  log(`🎉  Successfully released project ${chalk.yellow(userOptions.siteName)}.`)
  log()
}

module.exports = (...args) => {
  return release(...args).catch(err => {
    stopSpinner(false) // do not persist
    error(err)
    if (!process.env.CONTROLLA_CLI_TEST) {
      process.exit(1)
    }
  })
}
