    import { GeometryType, Log, RendererType, SymbolType } from '../../index'
    import { defined, isNumber } from '../../util'
    import {
      SimpleFillSymbol,
      SimpleMarkerSymbol,
      SimpleLineSymbol
    } from '../../base/symbol'

    /**
     * @description: 随机颜色
     * @return {*}
     */
    function randomColor() {
      return `rgba(${Math.round(Math.random() * 255)},${Math.round(
        Math.random() * 255
      )},${Math.round(Math.random() * 255)},1)`
    }

    /**
     * @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
     * @return {*}
     */
    function updateRandomFeatureSymbol(feature) {
      if (!feature || !feature.geometry) return
      const geometry = feature.geometry
      switch (geometry.type) {
        case GeometryType.multiPoint:
        case GeometryType.point: {
          feature.symbol = new SimpleMarkerSymbol({
            color: randomColor(),
            outline: new SimpleLineSymbol({
              color: randomColor()
            })
          })
          break
        }
        case GeometryType.multiLineString:
        case GeometryType.lineString: {
          feature.symbol = new SimpleLineSymbol({
            color: randomColor()
          })
          break
        }
        case GeometryType.polygon:
        case GeometryType.extent:
        case GeometryType.circle:
        case GeometryType.multiPolygon: {
          feature.symbol = new SimpleFillSymbol({
            color: randomColor(),
            outline: new SimpleLineSymbol({
              color: randomColor()
            })
          })
          break
        }
        default: {
          break
        }
      }
    }

    /**
     * @description: 简单解析数值表达式
     * @param {*} feature
     * @param {String} expression
     * @return {*}
     */
    function parseExpression(feature, expression) {
      if (!expression) return ''
      const excuteStr = expression.replace(/\$feature/g, `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 updateRenderer(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
        }
        case RendererType.random: {
          features.forEach((feature) => {
            updateRandomFeatureSymbol(feature)
          })
          break
        }
        case RendererType.rank: {
          const symbol = renderer.symbol
          const {
            minSize,
            maxSize,
            maxDataValue,
            minDataValue,
            field,
            valueExpression
          } = renderer
          if (!symbol || minSize > maxSize || (!field && !valueExpression)) {
            Log.error('等级符号专题图参数异常！')
          }
          // 计算最大数值
          let max
          let min

          features.forEach((feature) => {
            const attributes = feature.attributes || {}
            let value = attributes[field]
            value = defined(value)
              ? value
              : parseExpression(feature, valueExpression)
            value = parseFloat(value)
            if (!defined(max)) {
              max = value
            }
            if (!defined(min)) {
              min = value
            }
            max = Math.max(max, value)
            min = Math.min(min, value)
          })
          // 如果设置有数据最大范围，则用数据最大范围
          if (
            defined(minDataValue) &&
            defined(maxDataValue) &&
            maxDataValue > minDataValue
          ) {
            max = maxDataValue

            min = minDataValue
          }
          // 处理最大最小值相同的情况
          if (max - min === 0) {
            max += 0.0001
          }
          // 设置样式
          features.forEach((feature) => {
            const featureSymbol = symbol.clone()
            const attributes = feature.attributes || {}
            let value = attributes[field]
            value = defined(value)
              ? value
              : parseExpression(feature, valueExpression)
            value = parseFloat(value)

            // 计算比率
            let clampRate
            if (value < min) {
              clampRate = 0
            } else if (value > max) {
              clampRate = 1
            } else {
              clampRate = (value - min) / (max - min)
            }
            const clampSize = parseInt(clampRate * (maxSize - minSize) + minSize)
            // 判断是否有计算值
            if (isNumber(clampSize)) {
              switch (featureSymbol.type) {
                case SymbolType.simpleMarker: {
                  featureSymbol.size = clampSize
                  break
                }
                case SymbolType.pictureMarker: {
                  featureSymbol.width = clampSize
                  featureSymbol.height = clampSize
                  break
                }
                case SymbolType.text: {
                  const font = featureSymbol.font || {}
                  font.size = clampSize
                  featureSymbol.font = font
                  break
                }
                default: {
                  break
                }
              }
            }
            // 更新符号
            updateFeatureSymbol(feature, featureSymbol)
          })
          break
        }
        default: {
          const rendererSymbol = renderer.symbol
          features.forEach((feature) => {
            updateFeatureSymbol(feature, rendererSymbol)
          })
          break
        }
      }
    }

    export { updateRenderer }