import cookie from 'vue-cookies'; // 用于管理浏览器中的cookie
import router from '@/router'; // 引入Vue Router实例

/**
 * 获取UUID（通用唯一识别码）
 * @returns {string} - 返回一个随机生成的UUID字符串
 */
export function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    // 使用位运算生成随机数，并根据'x'或'y'的不同生成不同的值
    return (c === 'x' ? (Math.random() * 16) | 0 : ('r&0x3' | '0x8')).toString(16);
  });
}

/**
 * 检查用户是否有特定权限
 * @param {string} key - 权限标识符
 * @returns {boolean} - 如果用户有此权限则返回true，否则返回false
 */
export function isAuth(key) {
  const authorities = JSON.parse(sessionStorage.getItem('Authorities') || '[]'); // 尝试从sessionStorage中获取用户权限列表
  if (authorities.length) {
    for (const i in authorities) {
      const element = authorities[i];
      if (element === key) {
        return true; // 如果找到匹配的权限，则返回true
      }
    }
  }
  return false; // 如果没有找到匹配的权限，则返回false
}

/**
 * 清除登录信息
 */
export function clearLoginInfo() {
  cookie.remove('Authorization'); // 移除存储在cookie中的授权token
  router.options.isAddDynamicMenuRoutes = false; // 禁用动态路由添加功能
}

/**
 * 树形数据转换
 * 将扁平的数据结构转换为树形结构
 * @param {Array} data - 扁平化的数据数组
 * @param {string} [id='id'] - 数据项ID字段名，默认为'id'
 * @param {string} [pid='parentId'] - 数据项父级ID字段名，默认为'parentId'
 * @returns {Array} - 转换后的树形数据结构
 */
export function treeDataTranslate(data, id = 'id', pid = 'parentId') {
  const res = []; // 存储根节点
  const temp = {}; // 临时对象，用于快速查找子节点

  // 首先将所有元素存入temp对象中，以它们的ID作为键
  for (let i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i];
  }

  // 再次遍历data数组，构建树结构
  for (let k = 0; k < data.length; k++) {
    // 如果当前元素有父级元素且不是自身，则将其作为子元素加入到父元素下
    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
      if (!temp[data[k][pid]].children) {
        temp[data[k][pid]].children = [];
      }
      if (!temp[data[k][pid]]._level) {
        temp[data[k][pid]]._level = 1;
      }
      data[k]._level = temp[data[k][pid]]._level + 1;
      temp[data[k][pid]].children.push(data[k]);
    } else {
      // 如果没有父级元素，则认为是根节点，直接加入到结果数组中
      res.push(data[k]);
    }
  }

  return res;
}

/**
 * 递归函数：从树结构中提取指定ID路径
 * @param {Array} data - 树形数据结构
 * @param {any} val - 查找的目标ID
 * @param {Array} [res=[]] - 存储找到的ID路径
 * @param {string} [id='id'] - 数据项ID字段名，默认为'id'
 * @param {string} [children='children'] - 数据项子元素字段名，默认为'children'
 * @returns {boolean} - 是否找到了目标ID
 */
function idListFromTree(data, val, res = [], id = 'id', children = 'children') {
  for (let i = 0; i < data.length; i++) {
    const element = data[i];

    // 递归处理子元素
    if (element[children] && idListFromTree(element[children], val, res, id, children)) {
      res.push(element[id]); // 当找到目标时，将当前节点ID加入路径
      return true;
    }

    // 如果当前节点就是目标节点，直接加入路径并返回
    if (element[id] === val) {
      res.push(element[id]);
      return true;
    }
  }
  return false;
}

/**
 * 将数组中的parentId列表取出，倒序排列
 * @param {Array} data - 树形数据结构
 * @param {any} val - 查找的目标ID
 * @param {string} [id='id'] - 数据项ID字段名，默认为'id'
 * @param {string} [children='children'] - 数据项子元素字段名，默认为'children'
 * @returns {Array} - 倒序排列的ID路径
 */
export function idList(data, val, id = 'id', children = 'children') {
  const res = [];
  idListFromTree(data, val, res, id, children); // 调用递归函数查找ID路径
  return res.reverse(); // 返回倒序排列的结果
}

/**
 * 文件地址校验与处理
 * @param {string|Array} fileUrl - 获取到的文件路径或文件路径数组
 * @returns {string|Array} - 处理后的文件路径或路径数组
 */
export function checkFileUrl(fileUrl) {
  if (fileUrl === '') return ''; // 如果输入为空字符串，直接返回空字符串

  const baseUrl = import.meta.env.VITE_APP_RESOURCES_URL; // 获取资源基础URL

  // 如果fileUrl是一个对象（如el-image组件传递的对象），则递归处理每个元素
  if (fileUrl && typeof fileUrl === 'object' && !Array.isArray(fileUrl)) {
    return Object.keys(fileUrl).reduce((acc, key) => {
      acc[key] = checkFileUrl(fileUrl[key]);
      return acc;
    }, {});
  }

  // 如果fileUrl是数组，则映射处理每个元素
  if (Array.isArray(fileUrl)) {
    return fileUrl.map(el => checkFileUrl(el));
  }

  // 对于单个文件路径，如果它不是绝对路径，则拼接基础URL
  if (fileUrl && typeof fileUrl === 'string' && fileUrl.indexOf('http') === -1) {
    return baseUrl + fileUrl;
  }

  return fileUrl; // 如果已经是绝对路径或无效路径，则直接返回原值
}
