    import { Log, RendererType } from '../../index'
    import { defined } from '../../util'

    /**
     * @description: 更新要素的符号信息
     * @param {*} feature
     * @param {*} rendererSymbol
     * @param {Boolean} visible
     * @return {*}
     */
    function updateFeatureSymbol(feature, rendererSymbol, visible) {
      if (!feature || !feature.symbol || !rendererSymbol) return
      const oldJSON = feature.symbol.toJSON()
      const newJSON = rendererSymbol.toJSON()
      if (oldJSON !== newJSON) {
        feature.symbol = newJSON
      }
      feature.visible = defined(visible) ? visible : true
    }

    /**
     * @description: 简单解析数值表达式
     * @param {*} feature
     * @param {String} expression
     * @return {*}
     */
    function parseExpression(feature, expression) {
      if (!expression) return ''
      const excuteStr = expression.replace('$feature', `feature.attributes`)
      try {
        // eslint-disable-next-line no-eval
        const v = eval(excuteStr)
        return v
      } catch (err) {
        Log.info('字段表达式输入值非法')
      }
      return ''
    }

    /**
     * @description 渲染要素集
     * @public
     * @param {FeatureSet|Array<Feature>} featureSet
     * @param {*} renderer
     * @return {*}
     */
    function applyRenderer(features, renderer) {
      renderer = renderer || {}
      switch (renderer.type) {
        case RendererType.simple: {
          const rendererSymbol = renderer.symbol
          features.forEach((feature) => {
            updateFeatureSymbol(feature, rendererSymbol)
          })
          break
        }
        case RendererType.uniqueValue: {
          const defaultSymbol = renderer.defaultSymbol || {}
          const defaultVisible = renderer.defaultVisible
          const uniqueValueInfos = renderer.uniqueValueInfos || []
          const valueExpression = renderer.valueExpression || ''
          for (let i = 0; i < features.length; i++) {
            const feature = features[i]
            const field = renderer.field || ''
            const attributes = feature.attributes || {}
            let value = attributes[field]
            value = defined(value)
              ? value
              : parseExpression(feature, valueExpression)
            if (defined(value)) {
              let uniqueSymbol = null
              let _uniqueValueInfo = null
              for (let j = 0; j < uniqueValueInfos.length; j++) {
                const uniqueValueInfo = uniqueValueInfos[j]
                if (uniqueValueInfo.value === value) {
                  uniqueSymbol = uniqueValueInfo.symbol
                  _uniqueValueInfo = uniqueValueInfo
                  break
                }
              }
              if (uniqueSymbol) {
                updateFeatureSymbol(feature, uniqueSymbol, _uniqueValueInfo.visible)
                // eslint-disable-next-line no-continue
                continue
              }
            }
            // 采用默认的样式
            updateFeatureSymbol(feature, defaultSymbol, defaultVisible)
          }
          break
        }
        case RendererType.classBreak: {
          const defaultSymbol = renderer.defaultSymbol || {}
          const classBreakInfos = renderer.classBreakInfos || []
          const valueExpression = renderer.valueExpression || ''
          const defaultVisible = renderer.defaultVisible
          for (let i = 0; i < features.length; i++) {
            const feature = features[i]
            const field = renderer.field || ''
            const attributes = feature.attributes || {}
            let value = attributes[field]
            value = defined(value)
              ? value
              : parseExpression(feature, valueExpression)

            if (defined(value)) {
              let classBreakSymbol = null
              let _classBreakInfo = null
              for (let j = 0; j < classBreakInfos.length; j++) {
                const classBreakInfo = classBreakInfos[j]
                const maxValue = classBreakInfo.maxValue
                const minValue = classBreakInfo.minValue
                if (value >= minValue && value < maxValue) {
                  classBreakSymbol = classBreakInfo.symbol
                  _classBreakInfo = classBreakInfo
                  break
                }
              }
              if (classBreakSymbol) {
                updateFeatureSymbol(
                  feature,
                  classBreakSymbol,
                  _classBreakInfo.visible
                )
                // eslint-disable-next-line no-continue
                continue
              }
            }
            // 采用默认的样式
            updateFeatureSymbol(feature, defaultSymbol, defaultVisible)
          }

          break
        }
        default: {
          const rendererSymbol = renderer.symbol
          features.forEach((feature) => {
            updateFeatureSymbol(feature, rendererSymbol)
          })
          break
        }
      }
    }

    export { applyRenderer }