const fs = require("fs");
const path = require("path");
const util = require("util");
const deleteDir = util.promisify(fs.rmdir);
const makeDir = util.promisify(fs.mkdir);
const sourcePath = "./source"; // 源文件夹路径
const tempPath = "./temp"; // 临时文件夹路径
const basePath = "./base"; // 基础文件夹路径
const map = {
  // 替换规则
  "\\.txt$": "_text",
  "\\.js$": "_js",
};

/**
 * 复制指定文件夹下的所有文件到目标文件夹下
 * @param {string} srcDir - 原文件夹路径
 * @param {string} destDir - 目标文件夹路径
 * @param {Object} options - 可选项，包括以下属性:
 *         - {string} prefix: 重命名前缀。
 *         - {string} suffix: 重命名后缀。
 *         - {string} exclude: 要排除的文件夹名称。
 * @return {Promise}
 */
function copyDir(srcDir, destDir, options = {}) {
  const { prefix = "", suffix = "", exclude = "", include = "" } = options;
  const excludeDirs = exclude ? exclude.split(",") : [];
  return new Promise((resolve, reject) => {
    // 创建目标文件夹
    fs.mkdir(destDir, { recursive: true }, (err) => {
      if (err) {
        reject(err);
      } else {
        // 读取原文件夹下的文件和子文件夹
        fs.readdir(srcDir, { withFileTypes: true }, (err, files) => {
          if (err) {
            reject(err);
          } else {
            // 处理每个文件
            Promise.all(
              files.map((file) => {
                const srcPath = path.join(srcDir, file.name);
                const destPath = path.join(destDir, `${prefix}${file.name}${suffix}`);

                // 排除特定文件夹
                if (excludeDirs.includes(file.name)) {
                  return Promise.resolve();
                }

                return new Promise((resolve, reject) => {
                  // 复制文件或递归复制子文件夹
                  if (file.isFile()) {
                    const readStream = fs.createReadStream(srcPath);
                    readStream.on("error", reject);
                    const writeStream = fs.createWriteStream(destPath);
                    writeStream.on("error", reject);
                    writeStream.on("finish", resolve);
                    readStream.pipe(writeStream);
                  } else {
                    copyDir(srcPath, destPath, options).then(resolve, reject);
                  }
                });
              })
            ).then(resolve, reject);
          }
        });
      }
    });
  });
}

// 替换文件中的文本
const replaceText = async (filePath, map) => {
  let content = await util.promisify(fs.readFile)(filePath, { encoding: "utf8" });
  for (const [regexStr, replacement] of Object.entries(map)) {
    const regex = new RegExp(regexStr, "g");
    content = content.replace(regex, replacement);
  }
  await util.promisify(fs.writeFile)(filePath, content, { encoding: "utf8" });
};

async function replaceFiles(dirPath, map, options) {
  const files = await readDir(dirPath, options);
  for (const file of files) {
    const filePath = path.join(dirPath, file);
    const stats = await stat(filePath);
    if (stats.isDirectory()) {
      await replaceFiles(filePath, map, options);
    } else {
      await replaceFile(filePath, map);
    }
  }
}
async function replaceFile(filePath, map) {
  const content = await readFile(filePath);
  let newContent = content;
  for (const [regex, replacement] of map) {
    newContent = newContent.replace(regex, replacement);
  }
  if (newContent !== content) {
    await writeFile(filePath, newContent);
  }
}
async function readDir(dirPath, options) {
  return new Promise((resolve, reject) => {
    fs.readdir(dirPath, (err, files) => {
      if (err) {
        reject(err);
      } else {
        if (options && options.extensions) {
          files = files.filter((file) => {
            const extension = path.extname(file).toLowerCase();
            return options.extensions.includes(extension);
          });
        }
        if (options && options.exclude) {
          files = files.filter((file) => !options.exclude.test(file));
        }
        resolve(files);
      }
    });
  });
}
async function stat(filePath) {
  return new Promise((resolve, reject) => {
    fs.stat(filePath, (err, stats) => {
      if (err) {
        reject(err);
      } else {
        resolve(stats);
      }
    });
  });
}
async function readFile(filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, "utf8", (err, content) => {
      if (err) {
        reject(err);
      } else {
        resolve(content);
      }
    });
  });
}
async function writeFile(filePath, content) {
  return new Promise((resolve, reject) => {
    fs.writeFile(filePath, content, "utf8", (err) => {
      if (err) {
        reject(err);
      } else {
        resolve();
      }
    });
  });
}

// 复制 temp 文件到 src
const copyTempToSrc = async (tempPath, srcPath) => {
  await copyFolder(tempPath, srcPath);
};

// 删除目录
const deleteFolder = async (folderPath) => {
  const files = await util.promisify(fs.readdir)(folderPath);
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    const filePath = path.join(folderPath, file);
    const stat = await util.promisify(fs.stat)(filePath);
    if (stat.isDirectory()) {
      await deleteFolder(filePath);
    } else {
      await util.promisify(fs.unlink)(filePath);
    }
  }
  await util.promisify(fs.rmdir)(folderPath);
};

async function renameFolder(oldName, newName) {
  try {
    await fs.promises.rename(oldName, newName);
  } catch (error) {
    console.error("Error:", error);
  }
}
const replaceInFile = async (file, mapping, options) => {
  try {
    let content = await fs.promises.readFile(file, "utf8");
    Object.entries(mapping).forEach(([pattern, replacement]) => {
      content = content.replace(new RegExp(pattern, "g"), replacement);
    });
    await fs.promises.writeFile(file, content, "utf8");
  } catch (err) {
    console.error(`Error replacing in file ${file}: ${err.message}`);
  }
};
const traverseDirectory = async (dir, mapping, options) => {
  try {
    const files = await fs.promises.readdir(dir);
    for (const file of files) {
      const filePath = path.join(dir, file);
      const stats = await fs.promises.lstat(filePath);
      if (stats.isDirectory()) {
        if (options && options.excludeDirs && options.excludeDirs.includes(file)) {
          continue;
        }
        await traverseDirectory(filePath, mapping, options);
      } else if (stats.isFile()) {
        const ext = path.extname(file);
        if (options && options.excludeFiles && options.excludeFiles.includes(file)) {
          continue;
        }
        if (options && options.extensions && !options.extensions.includes(ext)) {
          continue;
        }
        await replaceInFile(filePath, mapping, options);
      }
    }
  } catch (err) {
    console.error(`Error traversing directory ${dir}: ${err.message}`);
  }
};

// 执行操作
(async () => {
  await deleteFolder(tempPath).finally(() => {
    return makeDir(tempPath);
  });
  // home 页面调整
  // 复制 source 下所有文件到 temp
  await copyDir(`${sourcePath}/views/home/`, `${tempPath}/pages/home`);
  await copyDir(`${sourcePath}/views/test/`, `${tempPath}/pages/test`);
  // 标签操作

  const mapping = {
    "<div": "<view",
    "</div": "</view",
  };
  const options = {
    extensions: [".vue"],
  };

  await traverseDirectory(tempPath, mapping, options);

  await copyDir(tempPath, "./src");

  // 删除并重新创建 temp 目录
  // await deleteFolder(tempPath).finally(() => {
  //   return makeDir(tempPath);
  // });
  // // 复制 source 下所有文件到 temp
  // await copyDir(sourcePath, tempPath, { exclude: "App.vue,main.js" });
  // // 调整pages 目录
  // await renameFolder(tempPath + "/views", tempPath + "/pages");
  // // copy temp 文件到 src
  // await copyDir(tempPath, "./src");
  // // 删除 temp 目录
  // await deleteFolder(tempPath);
  //
  // // 复制base 到src
  // await copyDir(basePath, "./src");
})();
