import { ComConfigType, ComStyleConfigType, SelectedKeysType } from './type';

/**
 * @description 根据公共配置项生成antd Tree树形配置项, 增加key,数据系列的每一列生成的key规则是name-x
 * @param data
 * @param paths
 * @param isArrayType
 * @returns
 */
export const getRenderTreeData = (data: ComStyleConfigType[], paths: string[] = [], isArrayType = false) => {
  return data.map((item) => {
    const { _displayName, _name, _type, _value } = item;
    const title = _displayName || _name;
    const key = isArrayType ? paths.concat('x') : paths.concat(_name);
    // 如果是原子类型则直接返回key和title
    if (!Array.isArray(_value) || (_type && ['range', 'checkbox', 'position', 'select', 'children', 'rangeColor'].includes(_type))) {
      return { key: key.join('-'), title };
    } else if (_type === 'array') {
      // 如果是数据系列、则递归返回树形结构
      return {
        children: getRenderTreeData(_value, key, true),
        key: key.join('-'),
        title
      };
    } else {
      // 如果不是value是数组且不是原子类型，则递归返回树形结构
      return {
        children: getRenderTreeData(_value, key),
        key: key.join('-'),
        title
      };
    }
  });
};
/**
 *
 * @param data
 * @param checkedKeys
 * @returns 根据antd Tree组件配置项树形结构、用户选择的配置项key筛选并转换用户选择的配置项为组件配置项结构
 */
export const getChangedConfigByCheckedKeys = (
  data: ComConfigType['copyedConfig'],
  checkedKeys: string[],
  parentPaths: string[] = [],
  isArrayType = false
) => {
  return data
    .map((cur) => {
      const currentKeys = isArrayType ? parentPaths.concat('x') : parentPaths.concat(cur._name);
      const incluedKey = checkedKeys.includes(currentKeys.join('-'));
      if (incluedKey) {
        if (
          !Array.isArray(cur._value) ||
          (cur._type && ['range', 'checkbox', 'position', 'select', 'children', 'rangeColor'].includes(cur._type))
        ) {
          return cur;
        } else if (cur._type === 'array') {
          return {
            ...cur,
            _value: getChangedConfigByCheckedKeys(cur._value, checkedKeys, currentKeys, true)
          };
        } else {
          return {
            ...cur,
            _value: getChangedConfigByCheckedKeys(cur._value, checkedKeys, currentKeys)
          };
        }
      } else {
        return;
      }
    })
    .filter((d) => d);
};

/**
 * 根据Tree树拿到所有的key
 * @param data
 * @returns
 */
export const getKeysByTreeData = (data) => {
  return data.reduce((all, curr) => {
    if (Array.isArray(curr['children'])) {
      return all.concat([curr.key, ...getKeysByTreeData(curr['children'])]);
    } else {
      return all.concat(curr.key);
    }
  }, []);
};

/**
 * 根据组件配置项获取组件id、组件当前选择的key、以及当前组件配置项Tree的所有节点的key
 * @param data
 * @returns
 */
export const getMultipleSelectedKeys: (data: ComConfigType[]) => SelectedKeysType[] = (data) => {
  return data.reduce((pre, cur) => {
    return [
      ...pre,
      { componentId: cur.componentId, checkedKeys: cur.defaultAllKeys, defaultAllKeys: cur.defaultAllKeys, halfCheckedKeys: [] }
    ];
  }, []);
};

/**
 * 根据源组件样式和目标组件样式以获取两个组件的公共配置项
 * @param targetConfig
 * @param sourceConfig
 * @returns
 */
export function getComponentsComConfigBytargetAndSource(targetConfig, sourceConfig) {
  return targetConfig
    .filter((v) => !(v._name === 'dimension'))
    .map((d) => {
      // 遍历过滤后的配置项与theme取公共配置项,并把公共配置项的值改为theme中的值
      const comConfig = sourceConfig.find((v) => (v._name === d._name || d._type === 'array') && typeof d._value === typeof v._value);
      if (comConfig != null) {
        if (d._type === 'array') {
          if (d._value.length === 0 || comConfig._value.length === 0) {
            return {
              ...d,
              _value: []
            };
          }

          const newValue = [
            {
              ...d._value[0],
              _value: getComponentsComConfigBytargetAndSource(d._value[0]._value, comConfig._value[0]._value)
            }
          ];

          return {
            ...d,
            _value: newValue
          };
        } else if (Array.isArray(d._value) && !['range', 'checkbox', 'position', 'select', 'children', 'rangeColor'].includes(d._type)) {
          return {
            ...d,
            _value: getComponentsComConfigBytargetAndSource(d._value, comConfig._value)
          };
        } else {
          return {
            ...d,
            _value: comConfig._value
          };
        }
      }
      return null;
    })
    .filter(
      (d) =>
        d &&
        (Array.isArray(d._value) && !['range', 'checkbox', 'position', 'select', 'children', 'rangeColor'].includes(d._type)
          ? d._value.length
          : true)
    );
}
