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();
                }
                if (excludeDirs?.length > 0) {
                  const filters = excludeDirs.filter(dir => {
                    return new RegExp(dir, "g").test(srcPath);
                  });

                  if (filters.length > 0) {
                    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}`, `${tempPath}`);

  // 首页 S
  // await copyDir(`${sourcePath}/views/home/`, `${tempPath}/pages/home`);
  // await copyDir(`${sourcePath}/views/orders/`, `${tempPath}/pages/orders`);
  // await copyDir(`${sourcePath}/views/product/`, `${tempPath}/pages/product`);
  // await copyDir(`${sourcePath}/components/`, `${tempPath}/components`);
  // await copyDir(`${sourcePath}/style/`, `${tempPath}/style`);
  // await copyDir(`${sourcePath}/assets/`, `${tempPath}/static`);
  // await copyDir(`${sourcePath}/filters/`, `${tempPath}/filters`);
  // await copyDir(`${sourcePath}/mixins/`, `${tempPath}/mixins`);
  // await copyDir(`${sourcePath}/service/`, `${tempPath}/service`);
  // await copyDir(`${sourcePath}/constants/`, `${tempPath}/constants`);
  // await copyDir(`${sourcePath}/store/`, `${tempPath}/store`);
  // await copyDir(`${sourcePath}/api/`, `${tempPath}/api`);
  // await copyDir(`${sourcePath}/customize/`, `${tempPath}/customize`);
  // 首页 E

  await copyDir(`${sourcePath}/views/address/`, `${tempPath}/pages/address`);
  await copyDir(`${sourcePath}/api/`, `${tempPath}/api`);
  await copyDir(`${sourcePath}/service/`, `${tempPath}/service`);

  // 标签操作

  const mapping = {
    "<div": "<view",
    "</div": "</view",
    "<ul": "<view",
    "</ul": "</view",
    "<li": "<view",
    "</li>": "</view>",
    "@/assets/": "@/static/",
    "@/views/": "@/pages/",
    "<img": "<image"
  };
  const options = {
    extensions: [".vue", ".js"]
  };

  await traverseDirectory(tempPath, mapping, options);

  await copyDir(tempPath, "./src");
  await copyDir(basePath, "./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");
})();
