#!/usr/bin/env node
const { program } = require("commander");
const fs = require("fs");
const path = require("path");
const clc = require("cli-color");
const { promisify } = require("util");
const cliProgress = require("cli-progress");
const ncp = promisify(require("ncp").ncp);
const { exec, execSync } = require("child_process");
const pkg = require("./package.json");

process.stdout.setEncoding("utf8");

program
  .version(pkg.version)
  .arguments("<projectName>")
  .action(async (projectName) => {
    const projectDir = path.join(process.cwd(), projectName);

    if (fs.existsSync(projectDir)) {
      console.log(clc.red("当前目录下已存在" + projectName));
      return;
    }

    fs.mkdirSync(projectDir);

    const templateDir = path.join(__dirname, "template");
    const exclusions = ["node_modules", "pnpm-lock.yaml"];

    const files = await promisify(fs.readdir)(templateDir);
    const progressBar = new cliProgress.SingleBar({
      format: "Progress [{bar}] {percentage}% | {value}/{total}",
      barCompleteChar: "\u001b[42m \u001b[0m",
      barIncompleteChar: "\u001b[40m \u001b[0m",
      hideCursor: true,
    });
    progressBar.start(files.length, 0);

    for (const file of files) {
      if (!exclusions.includes(file)) {
        const srcPath = path.join(templateDir, file);
        const destPath = path.join(projectDir, file);
        await ncp(srcPath, destPath);

        if (file === "package.json") {
          const packageJsonPath = path.join(destPath);
          const packageJson = JSON.parse(
            fs.readFileSync(packageJsonPath, "utf8")
          );

          packageJson.name = projectName;
          packageJson.version = pkg.version;

          Object.keys(packageJson.dependencies).forEach((key) => {
            if (key.startsWith("@dage")) {
              packageJson.dependencies[key] = "^" + getPackageVersion(key);
            }
          });

          fs.writeFileSync(
            packageJsonPath,
            JSON.stringify(packageJson, null, 2)
          );
        }
      }

      progressBar.increment();
    }

    progressBar.stop();
    console.log(clc.blue("=====执行初始化====="));

    const installCommand =
      "pnpm i --registry http://192.168.20.245:4873/ || yarn --registry http://192.168.20.245:4873/ || npm i --registry http://192.168.20.245:4873/";

    try {
      await new Promise((resolve, reject) => {
        const childProcess = exec(
          installCommand,
          { cwd: projectDir },
          (error) => {
            if (error) {
              reject(error);
            } else {
              resolve();
            }
          }
        );

        childProcess.stdout.on("data", (data) => {
          console.log(data.trim());
        });
      });

      console.log(clc.green("=====初始化完成====="));
    } catch (error) {
      console.log(
        clc.red(`Error executing installation command: ${error.message}`)
      );
    }
  });

program.parse(process.argv);

function getPackageVersion(pkgName) {
  let version = "1.0.0";
  try {
    const componentsVersion = execSync(
      "npm info " + pkgName + " version --registry http://192.168.20.245:4873"
    );
    version = componentsVersion.toString().trim();
  } catch (err) {
    console.log(clc.red("获取 " + pkgName + " 版本号失败"));
  }
  return version;
}
