const ObjFilters = {
  /**
   * 字符串类型筛选
   * @param {array<Obj>} objArr
   * @param {array<{type: String, val: String}>} strs
   */
  strsFilter(objArr, strs) {
    if (strs.length === 0) {
      return objArr
    } else {
      for (const str of strs) {
        objArr = objArr.filter(item => {
          if (item[str.type]) {
            return item[str.type].match(str.val) !== null
          } else {
            return item
          }
        })
      }
    }
    return objArr
  },
  /**
   * 区间类型筛选
   * @param {array<Obj>} objArr
   * @param {array<{type: String, min: String, max: String}>} ranges
   */
  rangesFilter(objArr, ranges) {
    if (ranges.length === 0) {
      return objArr
    } else {
      /**
       * 循环多个区间条件，
       * 每种区间类型应该只有一个，
       * 比如价格区间不会有1000-2000和4000-6000同时需要的情况
       */
      for (const range of ranges) {
        // 多个不同类型区间是与逻辑，可以直接赋值给自身
        objArr = objArr.filter(item => {
          if (item[range.type]) {
            const r = new Date(item[range.type]).getTime()
            if (range.min && range.max) {
              return r >= range.min && r <= range.max
            }
          } else {
            return item
          }
        })
      }
      return objArr
    }
  },

  /**
   * 选择类型筛选
   * @param {array<Obj>} objArr
   * @param {array<{type: String, val: String}>} chooses
   */
  choosesFilter(objArr, chooses) {
    let tmpObj = []
    if (chooses.length === 0) {
      tmpObj = objArr
    } else {
      /**
       * 选择类型条件是或逻辑，使用数组连接concat
       */
      for (const choice of chooses) {
        tmpObj = tmpObj.concat(objArr.filter(item => {
          if (item[choice.type]) {
            return item[choice.type].match(choice.val) !== null
          }
        }))
      }
    }
    return tmpObj
  }
}

export function doneFilter(obj, conditions) {
  // 根据条件循环调用筛选器里的方法
  for (const key in conditions) {
    // 判断是否有需要的过滤方法
    if (ObjFilters.hasOwnProperty(key + 'Filter') && typeof ObjFilters[key + 'Filter'] === 'function') {
      obj = ObjFilters[key + 'Filter'](obj, conditions[key])
    }
  }
  return obj
}

