import {
  Feature,
  Projection,
  SpatialReference,
  BaseGraphicsLayerView
} from '@mapgis/webclient-common'
import { CesiumInnerGraphicsLayer } from './support/graphic'

class GraphicsLayerView extends BaseGraphicsLayerView {
  /**
   * 添加图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onAdd(event) {
    const layer = this.layer
    const innerView = this.innerView
    const features = layer.graphics || []
    // cesium graphicsLayer图层
    this.innerLayer = new CesiumInnerGraphicsLayer({
      id: layer.id,
      viewer: innerView,
      opacity: this.layer.opacity
    })
    // 坐标投影转换
    const _features = this._projectFeatures(features)
    this.render.drawFeature(this.innerLayer, _features)
    return Promise.resolve(this)
  }

  /**
   * 移除图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onRemove(event) {
    this.innerLayer.destroy()
    this.innerLayer = null
    return Promise.resolve(this)
  }

  /**
   * 更新图层视图
   * @param {LayerViewUpdateEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onUpdate(event) {
    const innerLayer = this.innerLayer
    if (event.updateContent && innerLayer) {
      event.updateContent.forEach((layerUpdateCotent) => {
        if (
          layerUpdateCotent &&
          layerUpdateCotent.operationType === 'property'
        ) {
          switch (layerUpdateCotent.name) {
            case 'opacity': {
              const params = layerUpdateCotent.params
              innerLayer.setOpacity(params[0])
              break
            }
            case 'visible': {
              const params = layerUpdateCotent.params
              innerLayer.setVisible(params[0])
              break
            }
            default: {
              break
            }
          }
        }
        if (layerUpdateCotent && layerUpdateCotent.operationType === 'method') {
          switch (layerUpdateCotent.name) {
            case 'add': {
              const params = layerUpdateCotent.params
              // 坐标投影转换
              const _features = this._projectFeatures([params[0]])
              this.render.drawFeature(innerLayer, _features)
              break
            }
            case 'remove': {
              const params = layerUpdateCotent.params
              innerLayer.remove(params[0])
              break
            }
            case 'addMany': {
              const params = layerUpdateCotent.params
              // 坐标投影转换
              const _features = this._projectFeatures(params[0])
              this.render.drawFeature(innerLayer, _features)
              break
            }
            case 'removeMany': {
              const params = layerUpdateCotent.params
              const features = params[0]
              features.forEach((feature) => {
                innerLayer.remove(feature)
              })
              break
            }
            case 'removeAll': {
              innerLayer.removeAll()
              break
            }
            default: {
              break
            }
          }
        }
      })
    }
    return Promise.resolve(this)
  }

  /**
   * 要素数组坐标投影转换
   * @private
   * @param {Array<Feature>} features 要素数组
   * @return {Array<Feature>} 坐标投影转换后的要素数组
   */
  _projectFeatures(features) {
    const _features = []
    // 坐标投影转换
    features.forEach((feature) => {
      const _feature = Feature.fromJSON(feature)
      if (!_feature.geometry.spatialReference.isWGS84) {
        _feature.geometry = Projection.project(
          _feature.geometry,
          new SpatialReference({
            wkid: 4326
          })
        )
      }
      _features.push(_feature)
    })
    return _features
  }
}
export default GraphicsLayerView
