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

async function start (options = {}, context = process.cwd()) {
  const isTestOrDebug = process.env.CONTROLLA_CLI_TEST || process.env.CONTROLLA_CLI_DEBUG
  const packageManagerChoices = []

  await clearConsole(true)

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

    if (hasYarn()) {
      packageManagerChoices.push({
        name: 'Use Yarn',
        value: 'yarn',
        short: 'Yarn'
      })
    }

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

  const { packageManager } = await inquirer.prompt([
    {
      name: 'packageManager',
      type: 'list',
      message: 'Pick the package manager to use when installing dependencies:',
      choices: packageManagerChoices
    }
  ])

  const userOptions = await loadUserOptions(context)

  const isShouldBackend = await shouldBackend(userOptions.type)

  const frontendPath = isShouldBackend ? `${context}/frontend` : context
  // install plugins
  stopSpinner()
  log(`🚀  Installing CLI plugins. This might take a while...`)
  log()
  if (isTestOrDebug) {
    // in development, avoid installation process
    await require('./util/setupDevProject')(context)
  } else {
    await installDeps(frontendPath, packageManager, options.registry)
  }

  // install composer
  if (isShouldBackend) {
    log()
    log(`🚀  Installing additional dependencies...`)
    log()
    await installDeps(context, packageManager, options.registry)
  }

  // install composer
  if (isShouldBackend) {
    log()
    log(`🚀  Installing Composer dependencies...`)
    log()
    await installComposerDeps(context, 'composer')
  }

  // Injected additional scripts
  if (isShouldBackend) {
    log()
    log(`📦  Injected additional scripts...`)
    log()
    await injectedScripts(context, 'composer')
  }

  // run complete cbs if any (injected by generators)
  log()
  logWithSpinner('⚓', `Running completion hooks...`)
  await execa.shell('find . -type f -name ".controllaignore" -execdir mv {} .gitignore ";"', { cwd: this.context }).then(result => {
    stopSpinner()
  })

  stopSpinner()
  log()
  log(`🎉  Successfully started project ${chalk.yellow(userOptions.siteName)}.`)
  log(
    `👉  Get started with the following commands:\n\n` +
    chalk.cyan(` ${chalk.gray('$')} ${packageManager === 'yarn' ? 'yarn serve' : packageManager === 'pnpm' ? 'pnpm run serve' : 'npm run serve'}`)
  )
  log()
}

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