import arg from "arg"
import fs from "fs"
import inquirer from "inquirer"
import path from "path"

import { createProject } from "./main"

const isVersioned = ["angular", "react", "eleventy", "eleventy-ssr", "html"]
const versionObject = isVersioned.reduce((a, v) => ({ ...a, [v]: v }), {})
// load directory names of /templates/
const templateDir = path.resolve(__dirname, "..", "templates")
for (const [key, value] of Object.entries(versionObject)) {
  const versions = fs.readdirSync(`${templateDir}/${key}`).filter(f => !f.startsWith("."))
  versionObject[key] = versions
}

function parseArgumentsIntoOptions(rawArgs) {
  const args = arg(
    {
      "--git": Boolean,
      "--install": Boolean,
      "--title": String,
      "--template": String,
      "--version": String,
      "-g": "--git",
      "-i": "--install",
      "-t": "--title",
      "-v": "--version",
    },
    {
      argv: rawArgs.slice(2),
    }
  )
  return {
    git: args["--git"] || false,
    title: args._[0],
    template: args["--template"],
    runInstall: args["--install"] || true,
    version: args["--version"] || false,
  }
}

async function promptForMissingOptions(options) {
  const defaultTemplate = "Eleventy"
  const defaultTitle = "duet-prototype"

  if (options.skipPrompts) {
    return {
      ...options,
      template: options.template || defaultTemplate,
      title: options.title || defaultTitle,
    }
  }

  const questions = []
  if (!options.template) {
    questions.push({
      type: "list",
      name: "template",
      message: "Please choose which Duet template to use",
      choices: ["Eleventy", "Eleventy-SSR", "HTML", "Angular", "React"],
      default: defaultTemplate,
    })
  }

  if (!options.version) {
    questions.push({
      type: "list",
      name: "version",
      message: "Which version would you like to use?",
      choices: answers => versionObject[options.template ? options.template : answers.template.toLowerCase()],
    })
  }

  if (!options.title) {
    questions.push({
      type: "input",
      name: "title",
      message: "Enter a name for this project",
      default: defaultTitle,
    })
  }

  if (!options.git) {
    questions.push({
      type: "confirm",
      name: "git",
      message: "Initialize a git repository?",
      default: false,
    })
  }

  const answers = await inquirer.prompt(questions)
  return {
    ...options,
    template: options.template || answers.template,
    targetDirectory: options.title || answers.title,
    version: options.version || answers.version,
    git: options.git || answers.git,
  }
}

export async function cli(args) {
  let options = parseArgumentsIntoOptions(args)
  options = await promptForMissingOptions(options)
  await createProject(options)
}
