var filterField = ''
function createFilter(filter, type) {
  if (type === 'geojson') filterField = 'properties'
  return item => eval(parseFilter(filter))
}

function parseFilter(filter) {
  if (!Array.isArray(filter) || filter.length === 0) {
    return false
  }
  switch (filter[0]) {
    case '>':
    case '>=':
    case '<':
    case '<=':
    case '==':
    case '!=': {
      let v = isExpression(filter[2]) ? parseExpression(filter[2]) : filter[2]
      v = typeof v === 'string' ? '"' + v + '"' : v
      return `(item.${filterField && `${filterField}.`}${filter[1]} ${
        filter[0]
      } ${v})`
    }
    case 'all':
    case 'any':
    case 'none': {
      let c = ''
      let op = filter[0] === 'any' ? '||' : '&&'
      for (let i = 1; i < filter.length; i++) {
        let prefix = filter[0] === 'none' ? '!' : ''
        let subfix = i === filter.length - 1 ? '' : op
        c += prefix + parseFilter(filter[i]) + subfix
      }
      if (filter.length >= 2) {
        return '(' + c + ')'
      }
      return c
    }
    case 'has':
      return `(item.${filterField && `${filterField}.`}${
        filter[1]
      } !== undefined)`
    case '!has':
      return `(item.${filterField && `${filterField}.`}${
        filter[1]
      } === undefined)`
    case 'in':
    case '!in': {
      let values = []
      for (let i = 2; i < filter.length; i++) {
        let v = isExpression(filter[i]) ? parseExpression(filter[i]) : filter[i]
        v = typeof v === 'string' ? '"' + v + '"' : v
        values.push(v)
      }
      let opr = filter[0] === 'in' ? '!==' : '==='
      return `([${values}].indexOf(item.${filterField && `${filterField}.`}${
        filter[1]
      }) ${opr} -1)`
    }
  }
}

function isExpression(ex) {
  if (Array.isArray(ex) && ex.length > 0) {
    return true
  }
  return false
}

function parseExpression(ex) {
  switch (ex[0]) {
    case 'get':
      return `item.${filterField && `${filterField}.`}${ex[1]}`
    case '+':
    case '-':
    case '*':
    case '/':
    case '%': {
      let v1 = isExpression(ex[1]) ? parseExpression(ex[1]) : ex[1]
      let v2 = isExpression(ex[2]) ? parseExpression(ex[2]) : ex[2]
      v1 = typeof v1 === 'string' ? '"' + v1 + '"' : v1
      v2 = typeof v2 === 'string' ? '"' + v2 + '"' : v2
      return '(' + v1 + ex[0] + v2 + ')'
    }
    default:
      return ''
  }
}

export default createFilter
