    import { Feature, ViewEventType } from '../../base'
    import { Point, Extent } from '../../base/geometry'
    import { defaultValue } from '../../util'
    import SketchStage from './SketchStage'
    import SketchBaseDrawTool from './SketchBaseDrawTool'
    import SketchPointDrawTool from './SketchPointDrawTool'
    import SketchPolygonDrawTool from './SketchPolygonDrawTool'
    import SketchStyle from './SketchStyle'
    /**
     * 面绘图工具类
     * @class SketchExtentDrawTool
     * @moduleEX SketchEditorModule
     * @extends SketchBaseDrawTool
     * @param {Object} options 构造参数
     * @param {MapView}  [options.mapView]  地图视图对象
     * @param {GraphicsLayer}  [options.layer]  草图图层管对象
     * @param {SketchStyle}  [options.sketchStyle]  草图符号
     */
    class SketchExtentDrawTool extends SketchBaseDrawTool {
      constructor(options) {
        super(options)
        /**
         * 地图视图
         * @member {MapView|SecenView} SketchEditor.prototype._mapView
         */
        this._mapView = options.mapView
        /**
         * 草图图层
         * @member {GraphicsLayer} SketchEditor.prototype._layer
         */
        this._layer = defaultValue(options.layer, undefined)
        /**
         * 草图绘图形集合
         * @member {SketchStage} SketchEditor.prototype._sketchStage
         */
        this._sketchStage = new SketchStage()
        /**
         * 草图符号
         * @member {SketchStyle} SketchEditor.prototype._sketchStyle
         */
        this._sketchStyle = defaultValue(options.sketchStyle, new SketchStyle())
        // this._mouseEventHandlers = null
        this._currentVertexIndexOnMultiPoint = null
        /**
         * 草图编辑状态
         * 0:没有画图或编辑状态
         * 1:图形编辑
         * 2:节点编辑
         * 3:画图中
         * @member {MapView|SecenView} SketchEditor.prototype._editMode
         */
        this._editMode = 0
        /**
         * 草图捕获配置项
         * @member {Object} SketchEditor.prototype.snappingOption
         * @param {Object} [snappingOption.showSelectBox = {}] 捕捉时是否展示选中编辑框
         * @param {Object} [snappingOption.showSelectVertex = {}] 捕捉时是否展示顶点可编辑图形
         * @param {Object} [snappingOption._hitTestMode = {}] 捕捉拾取方式，0：click鼠标拾取。1：pointerDown鼠标按下拾取
         */
        const snappingOption = {
          showSelectBox: true,
          showSelectVertex: false,
          canEditFeature: false,
          canEditVertex: false,
          _hitTestMode: 0
        }
        this.snappingOption = defaultValue(options.snappingOption, snappingOption)
        /**
         * 所属父级绘图工具
         * @member {GraphicsLayer} SketchEditor.prototype._layer
         */
        this._parent = defaultValue(options._parent, undefined)
        // 所属sketchEditor对象
        this._sketchEditor = defaultValue(options._sketchEditor, undefined)
        // this.sketchSnappingTool = new SketchSnappingTool(this.snappingOption)
        // 初始化事件
        this._initEvent()
        this.undoRedoManager = defaultValue(options.undoRedoManager, undefined)
        this._drawTools = [this]
        this._otherDrawTools = []
      }

      /**
       * @description 初始化事件
       * @private
       */
      _initEvent() {
        this._processEvent = this._processEvent.bind(this)
        this.on('pan', this._processEvent)
        this.on('vertexScale', this._processEvent)
        this.on('midVertexScale', this._processEvent)
        this.on('vertexMove', this._processEvent)
        this.on('midVertexAdd', this._processEvent)
      }

      /**
       * @description 鼠标绘制图形：鼠标单击绘制区的一个顶点；鼠标移动，区图形随鼠标位置变动；鼠标双击，完成区图形绘制。
       */
      drawFeature() {
        // 屏蔽地图默认拖拽事件
        this._mapView._mapActionControl('drag-pan', false)
        // 控制鼠标移动事件频率
        const timer = null

        /// /////////////////////////
        // 当前正在绘制的图形对象
        let feature = null
        let originCoord = null

        // 处理鼠标点击事件。点击后渲染端点图形，渲染区图形
        const handlerDrag = (options) => {
          clearTimeout(timer)
          if (options.button === 0) {
            if (options.action === 'start') {
              originCoord = originCoord || this._mapView.toMap(options.origin)
            } else if (options.action === 'update') {
              const curCoord = this._mapView.toMap({ x: options.x, y: options.y })
              const xmin = Math.min(
                originCoord.coordinates[0],
                curCoord.coordinates[0]
              )
              const ymin = Math.min(
                originCoord.coordinates[1],
                curCoord.coordinates[1]
              )
              const xmax = Math.max(
                originCoord.coordinates[0],
                curCoord.coordinates[0]
              )
              const ymax = Math.max(
                originCoord.coordinates[1],
                curCoord.coordinates[1]
              )
              if (!feature) {
                feature = this._getFeature(xmin, ymin, xmax, ymax)
                this._addFeaturesToMap(feature)
                this._sketchStage.entityGraphic = feature
              } else {
                feature.geometry.xmin = xmin
                feature.geometry.ymin = ymin
                feature.geometry.xmax = xmax
                feature.geometry.ymax = ymax
              }
            } else if (options.action === 'end') {
              // 停止绘制
              this.stop()
              // 清除捕获效果
              if (this._sketchStage.snapGraphics.length > 0) {
                this._sketchStage.snapGraphics.forEach((feature) => {
                  this._removeFeatureFromMap(feature)
                })
                this._sketchStage.snapGraphics = []
              }
              this._editMode = 0
              // 发送绘制完成事件
              this.fire('drawn', { geometry: feature.geometry }, self)
              // 恢复地图默认拖拽事件
              this._mapView._mapActionControl('drag-pan', true)
            }
          }
        }

        this._mouseEventHandlers = this._mouseEventHandlers
          ? this._mouseEventHandlers
          : []
        // 移除绘制事件
        this._mouseEventHandlers.push(handlerDrag)
        this._mapView.on(ViewEventType.drag, handlerDrag)
      }

      /**
       * @description 添加图形
       * @param {Array} points 生成面的点地理坐标集
       * @param {SketchStyle} sketchStyle 面的符号样式
       */
      addFeature(points, sketchStyle, attributes) {
        let lineStyle = null
        if (!sketchStyle || !sketchStyle.lineStyle) {
          lineStyle = this._sketchStyle.lineStyle
        } else {
          lineStyle = sketchStyle.lineStyle
        }

        const feature = this._getFeature(points, lineStyle)
        if (attributes) {
          feature.attributes = attributes
        }
        this._sketchStage.entityGraphic = feature
        // 更新图层图形
        this._addFeaturesToMap(feature)
      }

      addFeatureByGeometry(geometry, sketchStyle, attributes) {
        let symbol = null
        if (!sketchStyle || !sketchStyle.lineStyle) {
          symbol = this._sketchStyle.lineStyle
        } else {
          symbol = sketchStyle.lineStyle
        }

        const feature = new Feature({
          geometry,
          symbol
        })
        if (attributes) {
          feature.attributes = attributes
        }
        this._sketchStage.entityGraphic = feature
        // 更新图层图形
        this._addFeaturesToMap(feature)
      }

      /**
       * @description 获取feature实例
       * @private
       * @param {Point} point 生成面的点地理坐标集
       * @param {Symbol} symbol 点的符号样式
       */
      _getFeature(xmin, ymin, xmax, ymax) {
        xmin = xmin !== undefined ? xmin : 0
        ymin = ymin !== undefined ? ymin : 0
        xmax = xmax !== undefined ? xmax : 0
        ymax = ymax !== undefined ? ymax : 0
        const geometry = new Extent({
          xmin,
          ymin,
          xmax,
          ymax,
          spatialReference: this._spatialReference
        })
        const symbol = this._sketchStyle.fillStyle
        const circleGeometry = new Feature({
          geometry,
          symbol
        })
        return circleGeometry
      }

      /**
       * @description 捕获草图
       * @private
       * @param {Feature} feature 被选中feature对象
       */
      _hitTestFeature(feature, event) {
        if (!this._parent && this.snappingOption.showSelectBox) {
          if (this._editMode === 0) {
            this._editMode = 1
          } else if (this._editMode === 2) {
            // 临时，把clickMap的事件删掉，否则在图形都被删掉时会被触发
            this._mapView.off(ViewEventType.immediateClick, this._mapClickEvent)
            this._mapClickEvent = null
            this._editMode = 1
          }
          // 进入图形编辑状态，高亮点元素,用新图形代替高亮，展示选中图形时的辅助图形
          this.selectFeature(feature)
        }
      }

      /**
       * @description 选中草图feature
       * @param {Feature} feature 被选中草图feature对象
       */
      selectFeature(feature) {
        if (!this.snappingOption.showSelectBox) return
        // 1.删除当前编辑图形状态的辅助图形
        // 2.添加顶点编辑状态的辅助图形
        this._clearEditGraphics(2)
        // 加载选时的辅助图形，外包盒
        const extent = feature.geometry
        const polygonDrawTool = new SketchPolygonDrawTool({
          mapView: this._mapView,
          layer: this._layer,
          sketchStyle: new SketchStyle({
            fillStyle: this._sketchStyle._selectBoxStyle,
            isShowSegmentLength: true,
            isShowArea: true
          }),
          snappingOption: {
            showSelectBox: false,
            _hitTestMode: 1
          },
          _parent: this // 或者只传父级相应pan的事件
        })
        // 注册hitTest事件移动图形
        this._drawTools.push(polygonDrawTool)
        polygonDrawTool.addFeature([
          [extent.xmax, extent.ymax],
          [extent.xmax, extent.ymin],
          [extent.xmin, extent.ymin],
          [extent.xmin, extent.ymax],
          [extent.xmax, extent.ymax]
        ])

        this._sketchStage.selectBoxGraphics = [
          polygonDrawTool._sketchStage.entityGraphic
        ]
        // 外包盒顶点和终点
        let boxVertexPoints = []
        boxVertexPoints = [
          {
            point: new Point({
              coordinates: [extent.xmax, extent.ymax],
              spatialReference: this._spatialReference
            }),
            direction: 'ne'
          },
          {
            point: new Point({
              coordinates: [extent.xmax, extent.ymin],
              spatialReference: this._spatialReference
            }),
            direction: 'se'
          },
          {
            point: new Point({
              coordinates: [extent.xmin, extent.ymin],
              spatialReference: this._spatialReference
            }),
            direction: 'sw'
          },
          {
            point: new Point({
              coordinates: [extent.xmin, extent.ymax],
              spatialReference: this._spatialReference
            }),
            direction: 'nw'
          }
        ]
        if (this._sketchEditor && this._sketchEditor.getCenterCoordinate) {
          const midVertexPoints = [
            // midPoint
            {
              point: new Point({
                coordinates: this._sketchEditor.getCenterCoordinate(
                  [extent.xmax, extent.ymax],
                  [extent.xmax, extent.ymin]
                ),
                spatialReference: this._spatialReference
              }),
              direction: 'e',
              type: 'midVertex'
            },
            {
              point: new Point({
                coordinates: this._sketchEditor.getCenterCoordinate(
                  [extent.xmax, extent.ymin],
                  [extent.xmin, extent.ymin]
                ),
                spatialReference: this._spatialReference
              }),
              direction: 's',
              type: 'midVertex'
            },
            {
              point: new Point({
                coordinates: this._sketchEditor.getCenterCoordinate(
                  [extent.xmin, extent.ymin],
                  [extent.xmin, extent.ymax]
                ),
                spatialReference: this._spatialReference
              }),
              direction: 'w',

              type: 'midVertex'
            },
            {
              point: new Point({
                coordinates: this._sketchEditor.getCenterCoordinate(
                  [extent.xmin, extent.ymax],
                  [extent.xmax, extent.ymax]
                ),
                spatialReference: this._spatialReference
              }),
              direction: 'n',
              type: 'midVertex'
            }
          ]
          boxVertexPoints = boxVertexPoints.concat(midVertexPoints)
        }
        const pointDrawTools = []
        const boxVertexGraphics = []
        boxVertexPoints.forEach((item) => {
          const pointDrawTool = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            sketchStyle: new SketchStyle({
              vertexStyle: this._sketchStyle._selectBoxVertexStyle
            }),
            snappingOption: {
              showSelectBox: false,
              _hitTestMode: 1
            },
            _parent: this // 或者只传父级相应pan的事件
          })
          // 注册hitTest事件移动图形
          // this._hitTestDrawToolStack.push(pointDrawTool)
          this._drawTools.push(pointDrawTool)
          pointDrawTool.addFeature(item.point, this._sketchStage, {
            direction: item.direction,
            type: item.type
          })
          pointDrawTools.push(pointDrawTool)
          boxVertexGraphics.push(pointDrawTool._sketchStage.entityGraphic)
        })
        this._sketchStage.selectBoxVertexGraphics = boxVertexGraphics
        if (this._otherDrawTools) {
          this._otherDrawTools.push(polygonDrawTool)
        } else {
          this._otherDrawTools = [polygonDrawTool]
        }
        this._otherDrawTools = this._otherDrawTools.concat(pointDrawTools)

        // 添加到undoRedoManager中
        if (this.undoRedoManager) {
          this.undoRedoManager.addProcess('add', this._sketchStage)
        }

        // 点击到地图没有feature图形区域，退出编辑
        if (
          !this._mapClickEvent &&
          (!this._parent || (this._parent && !this._parent._mapClickEvent))
        ) {
          this._mapClickEvent = () => {
            const removedFeatures = this._sketchStage.selectBoxGraphics
              .concat(this._sketchStage.selectBoxVertexGraphics)
              .concat(this._sketchStage.vertexGraphics)
              .concat(this._sketchStage.midVertexGraphics)
            removedFeatures.forEach((feature) => {
              this._removeFeatureFromMap(feature)
            })
            this._mapView.off(ViewEventType.immediateClick, this._mapClickEvent)
            this._mapView._mapActionControl('drag-pan', true)
            this._mapClickEvent = null
            // 发送草图没有被选中状态
            this.fire('selected', { isSelected: false }, self)
            this._sketchStage.selectBoxGraphics = []
            this._sketchStage.selectBoxVertexGraphics = []
            this._sketchStage.vertexGraphics = []
            this._sketchStage.midVertexGraphics = []
          }
          setTimeout(() => {
            this._hitTestEventHandlers.push(this._mapClickEvent)
            this._mapView.on(ViewEventType.immediateClick, this._mapClickEvent)
          }, 200)
        }
      }

      /**
       * @description 响应图形平移事件
       * @private
       * @param {Object} event 拾取事件参数
       */
      _processEvent(event) {
        if (event.type === 'pan') {
          // 处理平移逻辑
          this._handlerPanEvent(event)
        } else if (event.type === 'vertexScale') {
          // 处理顶点缩放逻辑
          this._handlerVertexScaleEvent(event)
        } else if (event.type === 'midVertexScale') {
          // 处理中点缩放逻辑
          this._handlerMidVertexScaleEvent(event)
        }
      }

      /**
       * @description 响应平移事件
       * @private
       * @param {Object} event 拾取事件参数
       */
      _handlerPanEvent(event) {
        // 更新当前草图的图形位置
        const extent = this._sketchStage.entityGraphic.geometry
        extent.xmin += event.deltaPosition.x
        extent.ymin += event.deltaPosition.y
        extent.xmax += event.deltaPosition.x
        extent.ymax += event.deltaPosition.y
        // 更新同级的辅助草图的图形位置
        if (this._otherDrawTools) {
          this._otherDrawTools.forEach((drawTool) => {
            drawTool._processEvent(event)
          })
        }
      }

      /**
       * @description 响应顶点缩放事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerVertexScaleEvent(event) {
        if (event.action === 'scale') {
          const geometry = this._sketchStage.entityGraphic.geometry
          // 更新当前草图的图形位置
          if (!this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            const oriCoordinates = [
              [geometry.xmin, geometry.ymin],
              [geometry.xmax, geometry.ymax]
            ]
            this._sketchStage.entityGraphic.attributes.lastCoordinates =
              oriCoordinates
          }
          this._sketchStage.entityGraphic.attributes = this._sketchStage
            .entityGraphic.attributes
            ? this._sketchStage.entityGraphic.attributes
            : {}
          const newCoordinates = this.getScaleCoordinates(
            [
              [geometry.xmin, geometry.ymin],
              [geometry.xmax, geometry.ymax]
            ],
            event.direction,
            event.extent,
            event.startPoint,
            event.movePoint,
            this._sketchStage.entityGraphic.attributes.lastCoordinates
          )
          geometry.xmin = newCoordinates[0][0]
          geometry.ymin = newCoordinates[0][1]
          geometry.xmax = newCoordinates[1][0]
          geometry.ymax = newCoordinates[1][1]

          // 更新同级的辅助草图的图形位置
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // 传给子草图的extent应该是草图改变前的，不是草图改变后的extent
              // event.extent = extent
              drawTool._processEvent(event)
            })
          }
        } else if (event.action === 'stop') {
          if (this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            this._sketchStage.entityGraphic.attributes.lastCoordinates = undefined
          }
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // if (drawTool._sketchStage.entityGraphic.id !== event.feature.id) {
              drawTool._processEvent(event)
              // }
            })
          }
        }
      }

      /**
       * @description 响应中点缩放事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerMidVertexScaleEvent(event) {
        if (event.action === 'scale') {
          // 更新当前草图的图形位置
          const geometry = this._sketchStage.entityGraphic.geometry
          if (!this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            const oriCoordinates = [
              [geometry.xmin, geometry.ymin],
              [geometry.xmax, geometry.ymax]
            ]
            this._sketchStage.entityGraphic.attributes.lastCoordinates =
              oriCoordinates
          }
          const newCoordinates = this.getMidScaleCoordinates(
            [
              [geometry.xmin, geometry.ymin],
              [geometry.xmax, geometry.ymax]
            ],
            event.direction,
            event.extent,
            event.startPoint,
            event.movePoint,
            this._sketchStage.entityGraphic.attributes.lastCoordinates
          )
          geometry.xmin = newCoordinates[0][0]
          geometry.ymin = newCoordinates[0][1]
          geometry.xmax = newCoordinates[1][0]
          geometry.ymax = newCoordinates[1][1]

          // 更新同级的辅助草图的图形位置
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // 传给子草图的extent应该是草图改变前的，不是草图改变后的extent
              // event.extent = extent
              drawTool._processEvent(event)
            })
          }
        } else if (event.action === 'stop') {
          if (this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            this._sketchStage.entityGraphic.attributes.lastCoordinates = undefined
          }
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // if (drawTool._sketchStage.entityGraphic.id !== event.feature.id) {
              drawTool._processEvent(event)
              // }
            })
          }
        }
      }

      /**
       * 图形捕获，捕获重合点、点在线上、平行线、垂直线
       * @private
       */
      getSnapGraphics() {}

      /**
       * @description 选中图形顶点
       * @private
       */
      selectVertex() {}
    }
    export default SketchExtentDrawTool