/*
 * ✨ 字典工具类函数 ✨
 * */

import utils from '@/utils.js';

/**
 * 通过字典编码获取字典
 * @param {String} code 字典编码
 * @return {Array} 字典
 * @example
 * getDictionaryByCode('xxx') // 获取'xxx'字典编码对应的字典数组
 * */
export function getDictionaryByCode(code = '') {
  if (!(typeof code === 'string' && code)) return [];
  return utils.getDictItemsFromCache(code) || [];
}

/**
 * 通过字典编码及其关联的value或name值获取级联字典
 * @param {String} code 字典编码
 * @param {String | Number} event 关联的value或name值
 * @param {'value' | 'name'} [eventType = 'value'] 通过名称还是值获取级联字典
 * @return {Array} 级联字典
 * @example
 * getCascadeDictByCodeEvent(code,event)
 * */
export function getCascadeDictByCodeEvent(code, event, eventType = 'value') {
  const eventTypeArr = ['value', 'name']; // 限制eventType参数值
  if (!eventTypeArr.includes(eventType)) return [];
  // 匹配级联字典对象
  const cascadeDictObj = getDictionaryByCode(code).find(item => item[eventType] === event)?.lowerDic || {};
  // 将级联字典对象转为二维数组后，合并所有字典
  return Object.entries(cascadeDictObj).reduce((concatDictArr, [_, dictArr = []]) => {
    if (!(Array.isArray(dictArr) && dictArr.length)) return concatDictArr;
    return concatDictArr.concat(dictArr);
  }, []);
}

/**
 * 配置对象
 * @typedef {Object} EscapeConfig
 * @property {String} [valueKey = 'value'] 需转义字段键名
 * @property {String} [labelKey = 'name'] 对应字段键名
 * @property {Boolean} [dictionaryType = true] true 为转义 false 为翻译
 * @property {Boolean} [congruent = true] 匹配为全等于还是等于
 * */

/**
 * 转义、翻译函数
 * @param {Array | string} data 配置数组或字典编码
 * @param {String} val 需转义内容
 * @param {EscapeConfig} [escapeConfig] 配置对象
 * @returns {String} 转义后的内容
 * */
export function dictionaryEscape(data, val = '', escapeConfig = {}) {
  // 参数归一化
  if (typeof data === 'string') data = getDictionaryByCode(data);
  if (!(Array.isArray(data) && data.length)) return '';

  escapeConfig = {
    valueKey: 'value',
    labelKey: 'name',
    dictionaryType: true,
    congruent: true,
    ...escapeConfig,
  };
  const { valueKey, labelKey, dictionaryType, congruent } = escapeConfig;
  const item =
    data.find(i => {
      const dictionaryValue = i[dictionaryType ? valueKey : labelKey]; // 字典值
      let condition = dictionaryValue === val; // 返回条件
      if (!congruent) condition = dictionaryValue == val;
      return condition;
    }) || {};
  return item[dictionaryType ? labelKey : valueKey] || '';
}
