    import * as L from '@mapgis/leaflet'
    import MapCoordSys from './MapCoordSys'
    import { getMapRotateBounds } from '../support/utils'

    const echarts = window.echarts

    const EchartsLayerConstuct = L.Layer.extend({
      map: null, // 传入的leaflet地图
      chart: null,
      options: null,
      echartsInitOpts: null,
      canvas: null,

      initialize(map, options) {
        this.map = map
        this.options = options
        this.echartsInitOpts = options.echartsInitOpts
        this.layerId = options.layerId || 'echartlayerdefaultid'
        this.layerClass = options.classId || 'echartlayerdefaultclass'

        this.visible = true
        this.initDevicePixelRatio()
        this.initOptions(this.options)
        this.initEcharts()

        this._resizeCanvas()
      },

      initDevicePixelRatio() {
        this.devicePixelRatio = window.devicePixelRatio || 1
      },

      initOptions(options) {
        if (options) {
          if (options.leaflet) {
            return
          }
          this.options.leaflet = {
            roam: true
          }
        }
      },

      initEcharts() {
        echarts.registerCoordinateSystem('leaflet', MapCoordSys)

        echarts.extendComponentModel({
          type: 'leaflet',
          getBMap() {
            return this.__leaflet
          },
          defaultOption: {
            roam: false
          }
        })

        echarts.registerAction(
          {
            type: 'LeafletRoma',
            event: 'LeafletRoma',
            update: 'updateLayout'
          },
          function () {}
        )
      },

      _visible() {
        this.visible = true
        this.canvas.style.visibility = 'visible'
      },

      _unvisible() {
        this.visible = false
        this.canvas.style.visibility = 'hidden'
      },

      onAdd(map) {
        const vm = this
        this.map = map
        this.canvas = this._createCanvas()

        this.map.getPanes().overlayPane.appendChild(this.canvas)

        this.chart = echarts.init(this.canvas, null, this.echartsInitOpts)

        echarts.leafletMap = map

        const self = this
        map.on('resize', function (e) {
          self.resize()
        })
        map.on('zoomstart', function () {
          self._unvisible()
        })
        map.on('rotate', () => {
          self.resize()
        })

        echarts.extendComponentView({
          type: 'leaflet',

          render(mapModel, ecModel, api) {
            let rendering = true
            if (!self._echartRenderApi) {
              self._echartRenderApi = api
            }

            if (!self._mapModel) {
              self._mapModel = mapModel
            }

            const leafletMap = echarts.leafletMap

            const viewportRoot = api.getZr().painter.getViewportRoot()
            const coordSys = mapModel.coordinateSystem

            const moveHandler = function () {
              if (rendering || !vm.visible) {
                return
              }
              const topleft = leafletMap.getBounds().getNorthWest()
              const offset = leafletMap.latLngToLayerPoint(topleft)
              const mapOffset = [
                parseInt(offset.x, 10) || 0,
                parseInt(offset.y, 10) || 0
              ]
              viewportRoot.style.left = `${mapOffset[0]}px`
              viewportRoot.style.top = `${mapOffset[1]}px`
              coordSys.setMapOffset(mapOffset)
              mapModel.__mapOffset = mapOffset

              api.dispatchAction({
                type: 'LeafletRoma'
              })
            }

            const zoomEndHandler = function () {
              self._visible()
              if (rendering || !vm.visible) {
                return
              }

              api.dispatchAction({
                type: 'LeafletRoma'
              })
            }

            if (this._oldMoveHandler) {
              leafletMap.off('move', this._oldMoveHandler)
            }
            if (this._oldZoomEndHandler) {
              leafletMap.off('zoomend', this._oldZoomEndHandler)
            }

            leafletMap.on('move', moveHandler)
            leafletMap.on('zoomend', zoomEndHandler)
            this._oldMoveHandler = moveHandler
            this._oldZoomEndHandler = zoomEndHandler

            rendering = false
          }
        })
        this.chart.setOption(this.options)
      },

      onRemove() {
        this.chart.dispose()
      },

      _createCanvas() {
        const canvas = document.createElement('div')
        canvas.id = this.layerId
        canvas.style.top = '0px'
        canvas.style.left = '0px'
        canvas.height = `${this.map.getSize().y}px`
        canvas.width = `${this.map.getSize().x}px`
        canvas.style.height = `${this.map.getSize().y}px`
        canvas.style.width = `${this.map.getSize().x}px`
        canvas.style.zIndex = 1000

        canvas.setAttribute('id', this.layerId)
        canvas.setAttribute('class', this.layerClass)

        this.canvas = canvas

        return canvas
      },

      _resizeCanvas() {
        window.onresize = this.resize.bind(this)
      },

      _calcRotateBounds() {
        return getMapRotateBounds(this._map)
      },

      /**
       * 显示图层
       * @function L.zondy.EchartsLayer.prototype.show
       */
      show() {
        this._visible()
      },

      /**
       * 隐藏图层
       * @function L.zondy.EchartsLayer.prototype.hide
       */
      hide() {
        this._unvisible()
      },

      /**
       * 重置图层大小
       * @function L.zondy.EchartsLayer.prototype.resize
       */
      resize() {
        const self = this
        const size = self._calcRotateBounds().getSize()
        self.canvas.style.width = `${size.x}px`
        self.canvas.style.height = `${size.y}px`
        self.canvas.width = size.x
        self.canvas.height = size.y
        self.chart.resize()
        // 缓存echart api
        if (self._echartRenderApi && self._mapModel && self._map._rotate) {
          // 以下渲染逻辑和moveHandler一致
          const api = self._echartRenderApi
          const mapModel = self._mapModel
          const viewportRoot = api.getZr().painter.getViewportRoot()
          const coordSys = mapModel.coordinateSystem
          const topleft = this.map.getBounds().getNorthWest()
          const offset = this.map.latLngToLayerPoint(topleft)
          const mapOffset = [
            parseInt(offset.x, 10) || 0,
            parseInt(offset.y, 10) || 0
          ]
          viewportRoot.style.left = `${mapOffset[0]}px`
          viewportRoot.style.top = `${mapOffset[1]}px`
          coordSys.setMapOffset(mapOffset)
          mapModel.__mapOffset = mapOffset
          // 触发echarts图层更新
          api.dispatchAction({
            type: 'LeafletRoma'
          })
        }
      },

      /**
       * @function L.zondy.EchartsLayer.prototype.update
       * @param {*} option echarts.option
       * @see https://www.echartsjs.com/zh/tutorial.html#异步数据加载和更新
       * @description ECharts 由数据驱动，数据的改变驱动图表展现的改变，因此动态数据的实现也变得异常简单。所有数据的更新都通过 setOption实现，你只需要定时获取数据，setOption 填入数据，而不用考虑数据到底产生了那些变化，ECharts 会找到两组数据之间的差异然后通过合适的动画去表现数据的变化。
       */
      update(option) {
        this.chart.setOption(option)
      },

      /**
       * 删除图层
       * @function module:客户端可视化.EchartsLayer.prototype.remove
       */
      remove() {
        this.chart.clear()

        if (this.canvas.parentElement) {
          this.canvas.parentElement.removeChild(this.canvas)
        }
        this.map = undefined

        return this
      },
      setOpacity(opacity) {
        this.canvas.style.opacity = opacity
      }
    })

    const echartsLayer = function (echartsParams, options) {
      return new EchartsLayerConstuct(echartsParams, options)
    }

    export default echartsLayer