import { ref, toRef } from "vue";
import CryptoJS from "crypto-js";

// 构造树型结构数据
export function handleTree(arr: any, id: string) {
  // 数组去重
  arr = arr.filter((item: any, index: number) => {
    if (arr.findIndex((ite: any) => ite[id] === item[id]) === index) {
      return item;
    }
  });

  function turnTree(arr: any, id: string) {
    const tree = ref<any>([]);
    for (let i = 0; i < arr.length; i++) {
      const isFirst = tree.value.findIndex((item: any) => arr[i][id].includes(item[id]));
      if (isFirst !== -1) {
        tree.value[isFirst].children.push(arr[i]);
      } else {
        arr[i].children = [];
        tree.value.push(arr[i]);
      }
    }
    return tree.value;
  }
  return turnTree(arr, id);
}

/**
 * 生成随机len位数字
 */
export const randomLenNum = (len: number, date?: boolean) => {
  let random = "";
  random = Math.ceil(Math.random() * 100000000000000)
    .toString()
    .substr(0, len);
  if (date) random = random + Date.now();
  return random;
};

/**
 *加密处理
 */
export const encryption = (params: any) => {
  let { key } = params;
  const { data, type, param } = params;
  const result = JSON.parse(JSON.stringify(data));
  if (type === "Base64") {
    param.forEach((ele: any) => {
      result[ele] = btoa(result[ele]);
    });
  } else {
    param.forEach((ele: any) => {
      const data = result[ele];
      key = CryptoJS.enc.Latin1.parse(key);
      const iv = key;
      // 加密
      const encrypted = CryptoJS.AES.encrypt(data, key, {
        iv: iv,
        mode: CryptoJS.mode.CFB,
        padding: CryptoJS.pad.NoPadding
      });
      result[ele] = encrypted.toString();
    });
  }
  return result;
};

/**
 * 判断路由是否相等
 */
export const diff = (obj1: any, obj2: any): boolean => {
  delete obj1.close;
  const o1 = obj1 instanceof Object;
  const o2 = obj2 instanceof Object;
  if (!o1 || !o2) {
    /*  判断不是对象  */
    return obj1 === obj2;
  }

  if (Object.keys(obj1).length !== Object.keys(obj2).length) {
    return false;
    // Object.keys() 返回一个由对象的自身可枚举属性(key值)组成的数组,例如：数组返回下表：let arr = ["a", "b", "c"];console.log(Object.keys(arr))->0,1,2;
  }

  for (const attr in obj1) {
    const t1 = obj1[attr] instanceof Object;
    const t2 = obj2[attr] instanceof Object;
    if (t1 && t2) {
      return diff(obj1[attr], obj2[attr]);
    } else if (obj1[attr] !== obj2[attr]) {
      return false;
    }
  }
  return true;
};

/**
 * 对象深拷贝
 */
export const deepClone = (data: any) => {
  const type = getObjType(data);
  let obj: any;
  if (type === "array") {
    obj = [];
  } else if (type === "object") {
    obj = {};
  } else {
    // 不再具有下一层次
    return data;
  }
  if (type === "array") {
    for (let i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === "object") {
    for (const key in data) {
      obj[key] = deepClone(data[key]);
    }
  }
  return obj;
};

export const getObjType = (obj: any) => {
  const toString = Object.prototype.toString;
  const map: any = {
    "[object Boolean]": "boolean",
    "[object Number]": "number",
    "[object String]": "string",
    "[object Function]": "function",
    "[object Array]": "array",
    "[object Date]": "date",
    "[object RegExp]": "regExp",
    "[object Undefined]": "undefined",
    "[object Null]": "null",
    "[object Object]": "object"
  };
  if (obj instanceof Element) {
    return "element";
  }
  return map[toString.call(obj)];
};

// 表单序列化
export const serialize = (data: any) => {
  const list: string[] = [];
  Object.keys(data).forEach((ele) => {
    list.push(`${ele}=${data[ele]}`);
  });
  return list.join("&");
};

/**
 * 日期格式化
 */
export const timestampToTime = (timestamp: number) => {
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, "0");
  const day = date.getDate().toString().padStart(2, "0");
  const hour = date.getHours().toString().padStart(2, "0");
  const minute = date.getMinutes().toString().padStart(2, "0");
  const second = date.getSeconds().toString().padStart(2, "0");
  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
};

// 数组中获取对应value的label
export function getValueLabel(arr: any, value: string, valueName?: string, labelName?: string) {
  const valName = valueName ?? "value";
  const label = labelName ?? "label";
  return arr.find((item: any) => item[valName] === value)[label];
}

// 从字典中获取多选value的label
export function getValueListLabel(arr: any, value: string[], valueName?: string, labelName?: string) {
  const valName = valueName ?? "value";
  const label = labelName ?? "label";
  const showBackList = typeof value === "string" ? JSON.parse(value) : value;
  if (!value || value?.length === 0) return;
  const result: string[] = [];
  showBackList.forEach((item: any) => {
    result.push(arr.find((ite: any) => ite[valName] === item)[label] || "");
  });
  return result.join("、");
}

// 级联字典获取对应value的label
export function getLabelFromMutDict(arr: any, val: string, valueName?: string, labelName?: string): any {
  const value = valueName ?? "value";
  const label = labelName ?? "label";
  for (const item of arr) {
    if (item[value] === val) {
      return item[label];
    } else if (item.children?.length > 0) {
      const result = getLabelFromMutDict(item.children, val, value, label);
      if (result) return result;
    }
  }
}
