    import { FetchServer } from '@mapgis/webclient-common'
    import {
      getFonts,
      getLayers,
      getSpritePng,
      getVectorTileSource
    } from './MapgisVectorTileLayer'
    import VectorTileStyle from './MapgisVectorTileStyle'
    import VectorTileProvider from './VectorTileProvider'

    class VectorTileLayer {
      constructor(viewer, options) {
        this.viewer = viewer
        this.scene = this.viewer.scene

        this.url = options.styleUrl
        if (!this.url && options.ip) {
          this.url = `http://${options.ip}:${options.port}/igs/rest/mrcs/vtiles/0/${options.layerName}`
        }

        this.options = options
        this.callback = options.callback
        this.token = options.token || ''
        this.opacity = options.opacity || 1
        this.vectortilejson = options.vectortilejson
        this.threadId = options.threadId || Math.random() * 10000
        this.show = options.show || true
        this.style = options.style
        this.tilingScheme = options.tilingScheme
        this.provider = null
        this.maximumLevel = options.maximumLevel || 20
        this.minimumLevel = options.minimumLevel || 0
        this.labelsRenderMode = options.labelsRenderMode || 'off-screen'
        this._dynamicEntityVisualizer =
          this.labelsRenderMode === 'on-screen'
            ? new Cesium.DynamicEntityVisualizer(viewer.scene, {})
            : null
        this.initDevicePixelRatio()
        this._fetchService = new FetchServer('', {})
        this._addCallback = options.addCallback || undefined
        this._wgs84Extent = options.wgs84Extent
        this._labelsNoteStyle = options.labelsNoteStyle

        if (this.style) {
          if (typeof this.style === 'string') {
            this.url = this.style
            this.requestVectortileJson()
          } else {
            this.vectortilejson = this.style
            this.requestStyleData(this.vectortilejson)
          }
        }
      }

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

      bindEvent() {
        // 下面几个是cesium专属事件,clickEvent和mousemoveEvent是mapv内部自带的方法不放出来
        this.innerMoveStart = this.moveStartEvent.bind(this)
        this.innerMoveEnd = this.moveEndEvent.bind(this)

        this.innnerZoomStart = this.zoomStartEvent.bind(this)
        this.innnerZoomEnd = this.zoomEndEvent.bind(this)
      }

      /**
       * 通过url获取矢量瓦片json对象
       */
      requestVectortileJson() {
        if (!this.vectortilejson) {
          // 发起请求
          const that = this
          this._fetchService.request({
            url: this.url,
            method: 'GET',
            success(result) {
              that.vectortilejson = result
              that.requestStyleData(that.vectortilejson)
            }
          })
        }
      }

      /**
       * 通过矢量瓦片json对象，获取样式参数
       * @function module:客户端渲染.VectorTileLayer.prototype.requestStyleData
       * @param {Object} vectortilejson 矢量瓦片对象 Mapbox-Style-Spec样式对象
       * @see https://docs.mapbox.com/mapbox-gl-js/style-spec/
       */
      requestStyleData(vectortilejson) {
        this.vectortilejson = vectortilejson
        const layers = getLayers(vectortilejson)
        const sources = getVectorTileSource(vectortilejson)
        const spritepng = getSpritePng(vectortilejson)
        // 发起请求
        const that = this
        this._fetchService.request({
          url: `${vectortilejson.sprite}.json`,
          method: 'GET',
          success(result) {
            that.styleData = {
              vectortilejson,
              layers,
              spritedata: result,
              spritepng,
              fonts: getFonts,
              sources
            }
            that.addLayer(that.styleData)
            if (that._addCallback && that._addCallback instanceof Function) {
              that._addCallback()
            }
          }
        })
      }

      getLayer() {
        return self.provider ? self.provider : undefined
      }

      /**
       * 首先构造矢量瓦片样式，再添加图层
       * @function module:客户端渲染.VectorTileLayer.prototype.addLayer
       * @param {Object} styleData 矢量瓦片样式参数 Mapbox-Style-Spec样式对象
       * @see https://docs.mapbox.com/mapbox-gl-js/style-spec/
       */
      addLayer(styleData) {
        const vectortileStyle = VectorTileStyle(
          styleData.vectortilejson,
          Object.keys(styleData.vectortilejson.sources),
          null,
          styleData.spritedata,
          styleData.spritepng,
          styleData.fonts
        )

        if (styleData.sources.length > 0) {
          const source = styleData.sources[0]
          const vectortile = VectorTileProvider(Cesium, {
            key: this.token,
            url: source.tiles[0],
            style: vectortileStyle,
            opacity: this.opacity,
            threadId: this.threadId,
            show: this.show,
            tilingScheme: this.tilingScheme,
            maximumLevel: this.maximumLevel,
            minimumLevel: this.minimumLevel,
            scene:this.scene,
            dynamicEntityVisualizer: this._dynamicEntityVisualizer,
            labelsRenderMode: this.labelsRenderMode,
            wgs84Extent: this._wgs84Extent,
            labelsNoteStyle: this._labelsNoteStyle
          })
          this.provider = this.viewer.imageryLayers.addImageryProvider(vectortile)
          this.provider.show = this.show

          if (this.callback) {
            this.callback({ imageryLayer: this.provider })
          }
        }
      }

      /**
       * @description 设置布局属性
       * @function module:客户端渲染.VectorTileLayer.prototype.updateStyle
       * @param {Object} mvtStyle
       */
      updateStyle(mvtStyle) {
        if (!this.styleData) return
        this.styleData.vectortilejson = mvtStyle
        this.remove()
        this.addLayer(this.styleData)
      }

      /**
       * @description 设置布局属性
       * @function module:客户端渲染.VectorTileLayer.prototype.setLayoutProperty
       * @param {String} layer
       * @param {String} key
       * @param {Object} value
       */
      setLayoutProperty(layerId, key, value) {
        if (!this.vectortilejson || !this.vectortilejson.layers) return
        const { layers } = this.vectortilejson
        const finds = layers.filter((l) => {
          return l.id === layerId
        })
        const layer = finds && finds.length > 0 ? finds[0] : undefined
        if (!layer) return
        layer.layout = layer.layout || {}
        layer.layout[key] = value
        this.styleData.vectortilejson = this.vectortilejson
        this.remove()
        this.addLayer(this.styleData)
      }

      /**
       * @description 设置画笔属性
       * @function module:客户端渲染.VectorTileLayer.prototype.setPaintProperty
       * @param {String} layerId
       * @param {String} key
       * @param {Object} value
       */
      setPaintProperty(layerId, key, value) {
        if (!this.vectortilejson || !this.vectortilejson.layers) return
        const { layers } = this.vectortilejson
        const finds = layers.filter((l) => {
          return l.id === layerId
        })
        const layer = finds && finds.length > 0 ? finds[0] : undefined
        if (!layer) return
        layer.paint = layer.paint || {}
        layer.paint[key] = value
        this.remove()
        this.addLayer(this.styleData)
      }

      /**
       * @description 设置过滤属性
       * @function module:客户端渲染.VectorTileLayer.prototype.setFilter
       * @param {String} layerId
       * @param {Array} rule
       */
      setFilter(layerId, rule) {
        if (!this.vectortilejson || !this.vectortilejson.layers) return
        const { layers } = this.vectortilejson
        const finds = layers.filter((l) => {
          return l.id === layerId
        })
        const layer = finds && finds.length > 0 ? finds[0] : undefined
        if (!layer) return
        layer.filter = layer.filter || {}
        layer.filter = rule
        this.remove()
        this.addLayer(this.styleData)
      }

      unbindEvent() {}

      moveStartEvent() {}

      moveEndEvent() {}

      zoomStartEvent() {}

      zoomEndEvent() {}

      /**
       * 销毁图层-实际调用remove，为了接口保持一致
       * @function module:客户端渲染.VectorTileLayer.prototype.destroy
       */
      destroy() {
        this.remove()
      }

      /**
       * 设置图层的可见性
       * @param visible
       */
      setVisible(visible) {
        if (this.provider) {
          this.provider.show = visible
        }
      }

      /**
       * 移除图层
       * @function module:客户端渲染.VectorTileLayer.prototype.remove
       */
      remove() {
        const self = this
        if (self.provider) {
          self.viewer.imageryLayers.remove(self.provider, true)
          self.provider.show = false
        }
        /* let self = this;
            window.setTimeout(() => {
                if (self.provider) {
                    self.viewer.imageryLayers.remove(self.provider, true);
                    self.provider.show = false;
                }
            }, 1000); */
      }
    }

    export default VectorTileLayer