import { isEmpty } from './isEmpty';

type IndexKey = string | number | symbol;
interface AnyObject {
  [propName: IndexKey]: any;
}

/**
 * @description 判断两个对象是否相等
 * @param {AnyObject} obj1
 * @param {AnyObject} obj2
 * @param {boolean} omitEmpty 默认为false，当为true时，为空的值判断为相等
 * @return {boolean}
 */
export const isObjectEqual = function (
  obj1: AnyObject,
  obj2: AnyObject,
  omitEmpty = false
) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length === keys2.length) {
    const sortKeys1 = keys1.sort();
    const sortKeys2 = keys2.sort();

    const sortStr1 = JSON.stringify(sortKeys1);
    const sortStr2 = JSON.stringify(sortKeys2);

    // 对象的key值都相等
    if (sortStr1 === sortStr2) {
      let flag = true;
      for (const key1 in obj1) {
        const value1 = obj1[key1];
        const value2 = obj2[key1];
        const typeofs = Object.prototype.toString.call(value1);
        const typeofs2 = Object.prototype.toString.call(value2);

        // 如果两个都为空，判断为相等
        if (omitEmpty && isEmpty(value1) && isEmpty(value2)) {
          // flag = true;
        } else {
          if (typeofs === '[object Object]' && typeofs2 === '[object Object]') {
            const _flag = isObjectEqual(value1, value2, omitEmpty);
            if (!_flag) {
              flag = false;
              break;
            }
          } else if (
            typeofs === '[object Array]' &&
            typeofs2 === '[object Array]'
          ) {
            const _flag = isArrayEqual(value1, value2, omitEmpty);
            if (!_flag) {
              flag = false;
              break;
            }
          } else if (typeofs === typeofs2) {
            // string number boolean null undefined
            if (value1 !== value2) {
              flag = false;
              break;
            }
          } else {
            // 类型不同，不相等
            flag = false;
            break;
          }
        }
      }
      return flag;
    } else {
      return false;
    }
  } else {
    return false;
  }
};

/**
 * @description 判断两个数组是否相等
 * @param {any[]} arr1
 * @param {any[]} arr2
 * @param {boolean} omitEmpty 默认为false，当为true时，为空的值判断为相等
 * @return {boolean}
 */
export const isArrayEqual = function (
  arr1: any[],
  arr2: any[],
  omitEmpty = false
) {
  if (arr1.length === arr2.length) {
    let flag = true;
    let i = 0;
    for (const item of arr1) {
      const value1 = item;
      const value2 = arr2[i];
      const typeofs = Object.prototype.toString.call(value1);
      const typeofs2 = Object.prototype.toString.call(value2);

      // 如果两个都为空，判断为相等
      if (omitEmpty && isEmpty(value1) && isEmpty(value2)) {
        // flag = true;
      } else {
        if (typeofs === '[object Object]' && typeofs2 === '[object Object]') {
          const _flag = isObjectEqual(value1, value2, omitEmpty);
          if (!_flag) {
            flag = false;
            break;
          }
        } else if (
          typeofs === '[object Array]' &&
          typeofs2 === '[object Array]'
        ) {
          const _flag = isArrayEqual(value1, value2, omitEmpty);
          if (!_flag) {
            flag = false;
            break;
          }
        } else if (typeofs === typeofs2) {
          // string number boolean null undefined
          if (value1 !== value2) {
            flag = false;
            break;
          }
        } else {
          // 类型不同，不相等
          flag = false;
          break;
        }
      }

      i++;
    }
    return flag;
  } else {
    return false;
  }
};

/**
 * @description 判断两个数据是否相等
 * @param {any} data1
 * @param {any} data2
 * @param {boolean} omitEmpty 默认为false，当为true时，为空的值判断为相等
 * @return {boolean}
 */
export const isEqual = function (data1: any, data2: any, omitEmpty = false) {
  let flag = true;
  // 如果两个都为空，判断为相等
  if (omitEmpty && isEmpty(data1) && isEmpty(data2)) {
    // flag = true;
  } else {
    const typeofs = Object.prototype.toString.call(data1);
    const typeofs2 = Object.prototype.toString.call(data2);

    if (typeofs === '[object Object]' && typeofs2 === '[object Object]') {
      const _flag = isObjectEqual(data1, data2, omitEmpty);
      if (!_flag) {
        flag = false;
      }
    } else if (typeofs === '[object Array]' && typeofs2 === '[object Array]') {
      const _flag = isArrayEqual(data1, data2, omitEmpty);
      if (!_flag) {
        flag = false;
      }
    } else if (typeofs === typeofs2) {
      // string number boolean null undefined
      if (data1 !== data2) {
        flag = false;
      }
    } else {
      // 类型不同，不相等
      flag = false;
    }
  }

  return flag;
};
