import { fileURLToPath } from 'node:url';
import inquirer from 'inquirer';
import fs from 'fs-extra';
import path from 'path';
import chalk from 'chalk';
import ora from 'ora';
import shell from 'shelljs';
import crossSpawn from 'cross-spawn';

const setName = [
  {
    name: "setName",
    type: "input",
    message: "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0\uFF1A"
  }
];
const pickProjectQues = [
  {
    name: "TempType",
    type: "list",
    message: "\u8BF7\u9009\u62E9\u4E00\u4E2A\u9879\u76EE\u6A21\u677F:",
    choices: [
      new inquirer.Separator("-----\u9879\u76EE------"),
      {
        name: "Simple",
        value: "simple"
      },
      {
        name: "Vue",
        value: "vue"
      },
      {
        name: "React",
        value: "react"
      },
      new inquirer.Separator("-----\u8D44\u6E90------"),
      {
        name: "Prefab",
        value: "prefab"
      },
      {
        name: "Plugin",
        value: "plugin"
      }
    ]
  }
];
const tempAction = (projUrl) => {
  return [
    {
      name: "action",
      type: "list",
      message: `
\u6587\u4EF6\uFF1A ${projUrl} \u5DF2\u5B58\u5728, \u8BF7\u9009\u62E9:`,
      choices: [
        {
          name: "\u8986\u76D6",
          value: "overwrite"
        },
        {
          name: "\u53D6\u6D88",
          value: " cancel"
        }
      ]
    }
  ];
};

async function copyDir(projectUrl, templeteUrl) {
  await fs.copy(templeteUrl, projectUrl, {
    filter: (src) => {
      return !["node_modules", "dist", ".vscode", "package-lock.json"].some(
        (dirName) => src.includes(dirName)
      );
    }
  });
  console.info(`\u2728 \u9879\u76EE\u521B\u5EFA\u5728 ${chalk.yellow(projectUrl)}
`);
}
async function shellCommand(name, tplname) {
  if (["simple"].includes(tplname)) {
    return console.info(chalk.green("\u{1F389} \u521B\u5EFA\u6210\u529F!\n"));
  }
  const cwd = process.cwd();
  const projUrl = path.join(cwd, name);
  await execCommand("npm", projUrl);
  console.info(chalk.green(`
\u{1F389} \u6210\u529F\u521B\u5EFA\u9879\u76EE: ${name}!!`));
  console.info(chalk.green("\u{1F449} \u63D0\u793A:\n"));
  console.info(chalk.cyan(`cd ${name}`));
  console.info(chalk.cyan(`npm run dev`));
}
async function execCommand(command, cwd) {
  shell.cd(cwd);
  const spinner = ora(
    "\u6B63\u5728\u52A0\u8F7D\u4F9D\u8D56\uFF0C\u8BF7\u7A0D\u5019...\n\n"
  ).start();
  const proc = crossSpawn.sync(command, ["install"], { stdio: "inherit" });
  if (proc.status !== 0) {
    console.error("npm install failed");
    spinner.fail();
    return;
  }
  spinner.succeed("\u4F9D\u8D56\u5DF2\u6210\u529F\u52A0\u8F7D!");
}
async function create(param) {
  const {
    command: { args }
  } = param;
  let name = args[0];
  if (!name) {
    const res = await inquirer.prompt(setName);
    name = res.setName;
    if (!name) {
      console.info(chalk.yellow(`\u540D\u5B57\u4E3A\u7A7A\uFF0C\u9000\u51FA\u521B\u5EFA\u6D41\u7A0B!
`));
      process.exit(1);
    }
  }
  const cwd = process.cwd();
  const projUrl = path.join(cwd, name);
  if (fs.existsSync(projUrl)) {
    const { answer } = await inquirer.prompt(tempAction(projUrl));
    if (answer === "cancel") {
      process.exit(1);
    }
    console.info(`
\u6B63\u5728\u79FB\u9664 ${chalk.blue(projUrl)}...
`);
    fs.removeSync(projUrl);
  }
  const { TempType } = await inquirer.prompt(pickProjectQues);
  await execCopyFIle(projUrl, name, TempType);
}
async function execCopyFIle(projUrl, name, tplname) {
  const dirPath = path.dirname(fileURLToPath(import.meta.url));
  const templeteUrl = path.join(dirPath, "../", "templates/", tplname);
  await copyDir(projUrl, templeteUrl);
  shellCommand(name, tplname);
}

export { create as default };
