    import * as L from '@mapgis/leaflet'
    import {
      inputCss,
      isNumber,
      SymbolType,
      defined
    } from '@mapgis/webclient-common'
    import LeafletPlugin from '../../util/LeafletPlugin'
    import ConvertSymbolUtil from '../../util/ConvertSymbolUtil'

    function convertClusterSymbol(symbol, textSymbol, text) {
      const dom = document.createElement('div')
      const parentDom = document.createElement('div')
      let bgSize = [10, 10]
      let bgBorderWidth = 0
      let bgColor = 'none'
      // 解析符号为PictureMarker 和 SimpleMarker
      if (SymbolType.pictureMarker === symbol.type) {
        if (defined(symbol.width)) {
          dom.style.width = `${parseFloat(symbol.width)}px`
          bgSize[0] = parseFloat(symbol.width)
        }
        if (defined(symbol.height)) {
          dom.style.height = `${parseFloat(symbol.height)}px`
          bgSize[1] = parseFloat(symbol.height)
        }
        // 图片和几何点中心统一
        if (defined(symbol.xoffset)) {
          dom.style.marginLeft = symbol.xoffset
        }
        if (defined(symbol.yoffset)) {
          dom.style.marginTop = symbol.yoffset
        }
        if (defined(symbol.angle)) {
          dom.style.transform = `rotate(${symbol.angle}deg)`
        }
        if (defined(symbol.url)) {
          dom.style.backgroundImage = `url(${symbol.url})`
          dom.style.backgroundSize = `cover`
        }
      } else {
        const {
          size = 20,
          outline = null,
          style = 'circle',
          path = '',
          angle = 0,
          xoffset = 0,
          yoffset = 0,
          color
        } = symbol

        // 不支持path 和 style
        if (defined(outline)) {
          const { width, color } = outline
          if (style === 'circle') {
            dom.style.borderRadius = `${size}px`
            dom.style.backgroundClip = 'padding-box'
          }
          bgBorderWidth = width
          bgColor = LeafletPlugin.convertColorToRgb(color)
        }

        if (defined(color)) {
          dom.style.backgroundColor = LeafletPlugin.convertColorToRgb(color)
          dom.style.backgroundSize = `cover`
        }
        if (defined(size)) {
          bgSize = [size, size]
          dom.style.width = `${size}px`
          dom.style.height = `${size}px`
        }
        if (defined(xoffset)) {
          dom.style.marginLeft = `${xoffset}px`
        }
        if (defined(yoffset)) {
          dom.style.marginTop = `${yoffset}px`
        }
        if (defined(angle)) {
          dom.style.transform = `rotate(${angle}deg)`
        }
        // 不支持path
      }

      const span = document.createElement('span')
      // 设置文字居中
      dom.style.textAlign = 'center'
      span.style.lineHeight = `${bgSize[1]}px`
      if (textSymbol) {
        const {
          color = '#000000',
          angle = 0,
          backgroundColor,
          borderLineColor,
          borderLineSize,
          font,
          haloColor,
          haloSize,
          xoffset,
          yoffset
        } = textSymbol
        span.style.color = LeafletPlugin.convertColorToRgb(color)
        span.style.transform = `rotate(${angle}deg)`
        if (defined(backgroundColor)) {
          span.style.backgroundColor =
            LeafletPlugin.convertColorToRgb(backgroundColor)
        }
        if (defined(borderLineColor) && defined(borderLineSize)) {
          span.style.border = `${borderLineSize}px solid ${LeafletPlugin.convertColorToRgb(
            borderLineColor
          )}`
        }
        if (defined(font)) {
          const { family = 'Helvetica Neue', size, style, weight } = font
          span.style.fontFamily = family
          span.style.fontSize = `${size}px`
          span.style.fontStyle = style
          span.style.fontWeight = weight
        }
        if (defined(haloColor) && defined(haloSize)) {
          span.style[
            '-webkit-text-stroke'
          ] = `${haloSize}px ${LeafletPlugin.convertColorToRgb(borderLineColor)}`
        }
        // 不支持xoffset yoffset
      }

      const parentDomWidth = bgSize[0] + bgBorderWidth * 2
      const parentDomHeight = bgSize[1] + bgBorderWidth * 2

      parentDom.style = `border:none;background-color:${bgColor};border-radius:${
        symbol.style === 'circle' ? `${parentDomWidth}px` : 'none'
      };padding:${bgBorderWidth}px;`

      span.innerText = text
      dom.appendChild(span)
      parentDom.appendChild(dom)
      // divIcon
      const divIcon = new L.DivIcon({
        html: parentDom,
        iconSize: new L.Point(parentDomWidth, parentDomHeight),
        className: ``
      })
      return divIcon
    }

    // 部分专题图强依赖plugin层，因此需要对这些专题图特殊处理
    class ThemeRenderUtil {
      /**
       * @description: 渲染聚类图
       * @param {*} innerLayer
       * @param {*} layer
       * @param {*} innerView
       * @param {*} features
       * @return {*}
       */
      static renderCluster(innerLayer, layer, innerView, features) {
        // 添加聚类样式
        inputCss(`
        .leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
          -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
          -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
          -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
          transition: transform 0.3s ease-out, opacity 0.3s ease-in;
        }
        .leaflet-cluster-spider-leg {
          /* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */
          -webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in;
          -moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in;
          -o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in;
          transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in;
        }
        `)
        // 初始化配置
        ThemeRenderUtil.updateCluster(innerLayer, layer, innerView)
        features = features || []
        features.forEach((feature) => {
          const marker = L.marker(LeafletPlugin.getAreaCenter(feature.geometry))
          innerLayer.addLayer(marker)
        })
      }

      static updateCluster(innerLayer, layer, innerView) {
        const options = innerLayer.options
        const renderer = layer.renderer

        const {
          defaultSymbol,
          radius,
          clusterBoundSymbol,
          maxScale,
          isExpandOnClick,
          isHoverShowBound
        } = renderer

        let clusterInfos = renderer.clusterInfos || []

        // 设置聚类最大zoom
        let zoom = 20
        if (innerView) {
          const resolution = (maxScale / 96) * 0.0254
          const latlng1 = innerView.unproject(L.point(0, 0), 0)
          const latlng2 = innerView.unproject(L.point(0, 1), 0)
          let dis = innerView.distance(latlng1, latlng2)
          let calcZoom = 0
          while (calcZoom <= 20 && dis > resolution) {
            calcZoom += 1
            dis /= 2
          }
          zoom = Math.max(calcZoom - 1, 0)
        }

        options.disableClusteringAtZoom = zoom
        options.singleMarkerMode = true
        options.maxClusterRadius = radius
        options.polygonOptions =
          ConvertSymbolUtil.convertSymboltoLeafletStyle(clusterBoundSymbol)
        options.zoomToBoundsOnClick = isExpandOnClick
        options.showCoverageOnHover = isHoverShowBound

        // 过滤不合法的聚类
        clusterInfos = clusterInfos.filter(
          (v) =>
            v &&
            isNumber(v.minValue) &&
            isNumber(v.maxValue) &&
            v.maxValue > v.minValue
        )

        options.iconCreateFunction = (cluster) => {
          const childCount = cluster.getChildCount()

          let infoSymbol = defaultSymbol
          let infoTextSymbol
          for (let i = 0; i < clusterInfos.length; i++) {
            const { symbol, labelSymbol, minValue, maxValue } = clusterInfos[i]
            if (childCount >= minValue && childCount < maxValue) {
              infoSymbol = symbol
              infoTextSymbol = labelSymbol
              break
            }
          }
          return convertClusterSymbol(
            infoSymbol,
            infoTextSymbol,
            String(childCount)
          )
        }
      }
    }
    export default ThemeRenderUtil