import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import fs__default from 'fs';
import path__default from 'path';
import { randomString } from '../string/random.mjs';
import { pascalCase } from '../string/string.mjs';
import { getGlob } from '../third-party/glob.mjs';

function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
/**
 * 生成 PascalCase 匹配正则（前后必须是非单词字符）
 * @param {string} value - kebab-case 名称
 * @returns {RegExp}
 * @example
 * ```ts
 * const reg = getComponentPascalReg('press-icon');
 * 'use <PressIcon/>'.match(reg); // ['PressIcon']
 * ```
 */
function getComponentPascalReg(value) {
  return new RegExp("(?<=\\W)(".concat(pascalCase(value), ")(?=\\W)"), 'g');
}
/**
 * 生成三阶段重命名配置（plus -> temp, key -> plus, temp -> key）
 * @param {string[]} rawList - 组件名列表，如 ['dialog', 'icon']
 * @param {string[]} [extraList=[]] - 额外需要重命名的组件名列表
 * @returns {{ renameConfig: Object, renameConfig2: Object, renameConfig3: Object }}
 * @example
 * ```ts
 * const { renameConfig, renameConfig2, renameConfig3 } = getThreeStageRenameConfig(['dialog', 'icon']);
 * // renameConfig:  { 'press-dialog-plus': '<random>', 'press-icon-plus': '<random>' }
 * // renameConfig2: { 'press-dialog': 'press-dialog-plus', 'press-icon': 'press-icon-plus' }
 * // renameConfig3: { '<random>': 'press-dialog', '<random>': 'press-icon' }
 * ```
 */
function getThreeStageRenameConfig(rawList) {
  var extraList = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var renameConfig = {};
  var renameConfig2 = {};
  var renameConfig3 = {};
  var iRawList = [].concat(_toConsumableArray(rawList), _toConsumableArray(extraList));
  var _iterator = _createForOfIteratorHelper(iRawList),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var item = _step.value;
      var plusKey = "press-".concat(item, "-plus");
      var key = "press-".concat(item);
      var tempKey = randomString(6);
      renameConfig[plusKey] = tempKey;
      renameConfig2[key] = plusKey;
      renameConfig3[tempKey] = key;
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return {
    renameConfig: renameConfig,
    renameConfig2: renameConfig2,
    renameConfig3: renameConfig3
  };
}
/**
 * 生成 meta config（如 component-config.json）的 PascalCase 替换规则
 * @param {string[]} rawList - 组件名列表
 * @param {string[]} dirList - 目标文件 glob 列表
 * @returns {Array<{ list: Array, dirList: string[] }>}
 * @example
 * ```ts
 * const rules = getMetaConfigPascalReplaceRules(
 *   ['dialog', 'icon'],
 *   ['src/component-config.json'],
 * );
 * // rules 为三阶段替换规则数组，供 batchReplaceFileContent 使用
 * ```
 */
function getMetaConfigPascalReplaceRules(rawList, dirList) {
  var list = [];
  var list2 = [];
  var list3 = [];
  var _iterator2 = _createForOfIteratorHelper(rawList),
    _step2;
  try {
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      var item = _step2.value;
      var plusKey = "".concat(item, "-plus");
      var key = "".concat(item);
      var tempKey = randomString(6);
      var preAndPostfixList = [['"', '"'], [' ', ' ']];
      for (var _i = 0, _preAndPostfixList = preAndPostfixList; _i < _preAndPostfixList.length; _i++) {
        var prefix = _preAndPostfixList[_i];
        list.push(["".concat(prefix[0]).concat(pascalCase(plusKey)).concat(prefix[1]), "".concat(prefix[0]).concat(tempKey).concat(prefix[1])]);
        list2.push(["".concat(prefix[0]).concat(pascalCase(key)).concat(prefix[1]), "".concat(prefix[0]).concat(pascalCase(plusKey)).concat(prefix[1])]);
        list3.push(["".concat(prefix[0]).concat(tempKey).concat(prefix[1]), "".concat(prefix[0]).concat(pascalCase(key)).concat(prefix[1])]);
      }
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  return [{
    list: list,
    dirList: dirList
  }, {
    list: list2,
    dirList: dirList
  }, {
    list: list3,
    dirList: dirList
  }];
}
/**
 * 生成文件内容的三阶段替换规则（kebab-case + PascalCase + 类名）
 * @param {string[]} rawList - 组件名列表
 * @param {string[]} dirList - 目标文件 glob 列表
 * @param {Object} [options={}] - 可选配置
 * @param {string[]} [options.needClassReplaceList=[]] - 需要额外替换类名的组件列表
 * @returns {Array<{ list: Array, dirList: string[] }>}
 * @example
 * ```ts
 * const rules = getComponentContentReplaceRules(
 *   ['dialog', 'icon'],
 *   ['src/**\/*.{ts,vue,less}'],
 *   { needClassReplaceList: ['icon'] },
 * );
 * batchReplaceFileContent(rules);
 * ```
 */
function getComponentContentReplaceRules(rawList, dirList) {
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var _options$needClassRep = options.needClassReplaceList,
    needClassReplaceList = _options$needClassRep === void 0 ? [] : _options$needClassRep;
  var list = [];
  var list2 = [];
  var list3 = [];
  // kebab-case 前后缀匹配规则
  var preAndPostfixList = [['/', '/'], ['/', '\''], ['/', '"'], ['/', '.vue'], ['<', ''], ['</', '>']];
  var _iterator3 = _createForOfIteratorHelper(rawList),
    _step3;
  try {
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      var item = _step3.value;
      var plusKey = "press-".concat(item, "-plus");
      var key = "press-".concat(item);
      var tempKey = randomString(6);
      var tempKey2 = randomString(6);
      // kebab-case 替换
      var _iterator5 = _createForOfIteratorHelper(preAndPostfixList),
        _step5;
      try {
        for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
          var prefix = _step5.value;
          list.push(["".concat(prefix[0]).concat(plusKey).concat(prefix[1]), "".concat(prefix[0]).concat(tempKey).concat(prefix[1])]);
          list2.push(["".concat(prefix[0]).concat(key).concat(prefix[1]), "".concat(prefix[0]).concat(plusKey).concat(prefix[1])]);
          list3.push(["".concat(prefix[0]).concat(tempKey).concat(prefix[1]), "".concat(prefix[0]).concat(key).concat(prefix[1])]);
        }
        // PascalCase 替换（使用正则）
      } catch (err) {
        _iterator5.e(err);
      } finally {
        _iterator5.f();
      }
      list.push([getComponentPascalReg(plusKey), pascalCase(tempKey2)]);
      list.push([getComponentPascalReg(key), pascalCase(plusKey)]);
      list.push([getComponentPascalReg(tempKey2), pascalCase(key)]);
    }
    // CSS 类名替换规则
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
  var classPrefixList = [['.', ' '], ['.', ','], ['.', '-'], ['', ';'], ['', '__'], ['', '--'], ['\'', '\''] // press-icon-plus (iconPrefix)
  ];
  var _iterator4 = _createForOfIteratorHelper(needClassReplaceList),
    _step4;
  try {
    for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
      var _item = _step4.value;
      var _plusKey = "press-".concat(_item, "-plus");
      var _key = "press-".concat(_item);
      var _tempKey = randomString(6);
      var _iterator6 = _createForOfIteratorHelper(classPrefixList),
        _step6;
      try {
        for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
          var _prefix = _step6.value;
          list.push(["".concat(_prefix[0]).concat(_plusKey).concat(_prefix[1]), "".concat(_prefix[0]).concat(_tempKey).concat(_prefix[1])]);
          list2.push(["".concat(_prefix[0]).concat(_key).concat(_prefix[1]), "".concat(_prefix[0]).concat(_plusKey).concat(_prefix[1])]);
          list3.push(["".concat(_prefix[0]).concat(_tempKey).concat(_prefix[1]), "".concat(_prefix[0]).concat(_key).concat(_prefix[1])]);
        }
      } catch (err) {
        _iterator6.e(err);
      } finally {
        _iterator6.f();
      }
    }
  } catch (err) {
    _iterator4.e(err);
  } finally {
    _iterator4.f();
  }
  return [{
    list: list,
    dirList: dirList
  }, {
    list: list2,
    dirList: dirList
  }, {
    list: list3,
    dirList: dirList
  }];
}
/**
 * 批量替换文件内容（性能优化版）
 * 将同 dirList 的规则合并，每个文件只读写一次
 * @param {Array<{ list: Array, dirList: string|string[] }>} replaceList - 替换规则列表
 * @example
 * ```ts
 * batchReplaceFileContent([
 *   {
 *     list: [
 *       ['<PressIconPlus', '<PressIcon'],
 *       [/press-icon-plus/g, 'press-icon'],
 *     ],
 *     dirList: ['src/**\/*.vue'],
 *   },
 * ]);
 * // 同 dirList 的规则会被合并，避免重复读写
 * ```
 */
function batchReplaceFileContent(replaceList) {
  // 按 dirList 分组，将相同 dirList 的规则合并
  var groupMap = new Map();
  var _iterator7 = _createForOfIteratorHelper(replaceList),
    _step7;
  try {
    for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
      var _groupMap$get$rules;
      var item = _step7.value;
      var dirList = item.dirList,
        list = item.list;
      if (!(list === null || list === void 0 ? void 0 : list.length)) continue;
      var newDir = Array.isArray(dirList) ? dirList : [dirList];
      var dirKey = JSON.stringify(newDir.sort());
      if (!groupMap.has(dirKey)) {
        groupMap.set(dirKey, {
          dirList: newDir,
          rules: []
        });
      }
      (_groupMap$get$rules = groupMap.get(dirKey).rules).push.apply(_groupMap$get$rules, _toConsumableArray(list));
    }
  } catch (err) {
    _iterator7.e(err);
  } finally {
    _iterator7.f();
  }
  var glob = getGlob();
  var _iterator8 = _createForOfIteratorHelper(groupMap),
    _step8;
  try {
    for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
      var _step8$value = _slicedToArray(_step8.value, 2),
        _step8$value$ = _step8$value[1],
        _dirList = _step8$value$.dirList,
        rules = _step8$value$.rules;
      var files = _toConsumableArray(new Set(_dirList.flatMap(function (pattern) {
        return glob.sync(pattern);
      })));
      var _iterator9 = _createForOfIteratorHelper(files),
        _step9;
      try {
        for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
          var file = _step9.value;
          if (fs__default.statSync(file).isDirectory()) continue;
          var content = fs__default.readFileSync(file, 'utf-8');
          var changed = false;
          var _iterator0 = _createForOfIteratorHelper(rules),
            _step0;
          try {
            for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
              var _step0$value = _slicedToArray(_step0.value, 2),
                from = _step0$value[0],
                to = _step0$value[1];
              var newContent = typeof from === 'string' ? content.replaceAll(from, to) : content.replace(from, to);
              if (newContent !== content) {
                content = newContent;
                changed = true;
              }
            }
          } catch (err) {
            _iterator0.e(err);
          } finally {
            _iterator0.f();
          }
          if (changed) {
            fs__default.writeFileSync(file, content);
            console.log("[batchReplaceFileContent]: \u6587\u4EF6: ".concat(file));
          }
        }
      } catch (err) {
        _iterator9.e(err);
      } finally {
        _iterator9.f();
      }
    }
  } catch (err) {
    _iterator8.e(err);
  } finally {
    _iterator8.f();
  }
}
/**
 * 批量重命名文件和文件夹（同步版本）
 * @param {string} dirPath - 要处理的目录路径
 * @param {Object} renameConfig - 重命名配置对象 { 旧名称: 新名称 }
 * @param {boolean} [recursive=true] - 是否递归处理子目录
 * @example
 * ```ts
 * batchRenameDirEntries('src/components', {
 *   'press-icon-plus': 'press-icon',
 *   'press-dialog-plus': 'press-dialog',
 * });
 * // 递归将 src/components 下名为 press-icon-plus、press-dialog-plus 的文件/文件夹重命名
 *
 * // 只重命名当前层、不递归
 * batchRenameDirEntries('src/components', { 'a': 'b' }, false);
 * ```
 */
function batchRenameDirEntries(dirPath, renameConfig) {
  var recursive = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  try {
    var items = fs__default.readdirSync(dirPath, {
      withFileTypes: true
    });
    var _iterator1 = _createForOfIteratorHelper(items),
      _step1;
    try {
      for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
        var item = _step1.value;
        var oldPath = path__default.join(dirPath, item.name);
        var newName = item.name;
        var _loop = function _loop() {
            var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
              oldName = _Object$entries$_i[0],
              newNamePart = _Object$entries$_i[1];
            var oldNameReg = new RegExp("^".concat(oldName, "(\\.\\w+)$"));
            if (item.name === oldName) {
              newName = newNamePart;
              return 0; // break
            } else if (oldNameReg.test(item.name)) {
              newName = item.name.replace(oldNameReg, function (_, postfix) {
                return newNamePart + postfix;
              });
              return 0; // break
            }
          },
          _ret;
        for (var _i2 = 0, _Object$entries = Object.entries(renameConfig); _i2 < _Object$entries.length; _i2++) {
          _ret = _loop();
          if (_ret === 0) break;
        }
        if (newName !== item.name) {
          var newPath = path__default.join(dirPath, newName);
          console.log("[batchRenameDirEntries]: ".concat(oldPath, " -> ").concat(newPath));
          fs__default.renameSync(oldPath, newPath);
        }
        if (recursive && item.isDirectory()) {
          var currentPath = newName !== item.name ? path__default.join(dirPath, newName) : oldPath;
          batchRenameDirEntries(currentPath, renameConfig, recursive);
        }
      }
    } catch (err) {
      _iterator1.e(err);
    } finally {
      _iterator1.f();
    }
  } catch (error) {
    console.error("[batchRenameDirEntries] Error processing directory ".concat(dirPath, ":"), error);
  }
}

export { batchRenameDirEntries, batchReplaceFileContent, getComponentContentReplaceRules, getComponentPascalReg, getMetaConfigPascalReplaceRules, getThreeStageRenameConfig };
