import {
  getAbsoluteCoordinate,
  createElement,
  getInitialPoint,
} from '../annotation/utils';

export default class AddSignField {
  constructor ({
    tool,
    color,
    svgElement,
    layer,
    container,
    viewport,
    page,
    eventBus
  }) {
    this.layer = layer
    this._tool = tool
    this.color = color
    this.svgElement = svgElement
    this.container = container
    this.viewport = viewport
    this.page = page
    this.eventBus = eventBus
    this.path = []

    this.initStartPoint = null
    this.initEndPoint = null
    this.shapeEle = null

    this.onMousedown = this.handleMouseDown.bind(this)
    this.onMouseup = this.handleMouseUp.bind(this)
    this.onMousemove = this.handleMouseMove.bind(this)

    this.init()
  }

  init () {
    this.container.removeEventListener('mousedown', this.onMousedown)
    this.container.removeEventListener('touchstart', this.onMousedown)

    this.container.addEventListener('mousedown', this.onMousedown)
    this.container.addEventListener('touchstart', this.onMousedown)

    document.removeEventListener('mousemove', this.onMousemove)
    document.removeEventListener('mouseup', this.onMouseup)
    document.removeEventListener('touchmove', this.onMousemove)
    document.removeEventListener('touchend', this.onMouseup)
  }

  get tool () {
    return this._tool
  }

  set tool (toolType) {
    if (toolType === this._tool) return
    if (!toolType) {
      this.reset()
      this.container.removeEventListener('mousedown', this.onMousedown)
      this.container.removeEventListener('touchstart', this.onMousedown)
    }
    this._tool = toolType
  }

  reset () {
    this.initStartPoint = null
    this.initEndPoint = null
    if (this.shapeEle) this.shapeEle.remove()
    this.shapeEle = null
    this.svgElement.innerHTML = ''
    this.path = []
    document.removeEventListener('mousemove', this.onMousemove)
    document.removeEventListener('mouseup', this.onMouseup)
    
    document.removeEventListener('touchmove', this.onMousemove)
    document.removeEventListener('touchend', this.onMouseup)

    this.container.removeEventListener('mousedown', this.onMousedown)
    this.container.removeEventListener('touchstart', this.onMousedown)

    this.eventBus._off('initTextfieldName', this.initTextfieldName)
  }

  handleMouseDown (event) {
    if (this.layer.annotationStore.selectedElementName || document.getElementById("sign-image-save")) return
    const { x, y } = getAbsoluteCoordinate(this.container, event)
    this.initStartPoint = { x, y }

    document.addEventListener('mousemove', this.onMousemove)
    document.addEventListener('mouseup', this.onMouseup)
    
    document.addEventListener('touchmove', this.onMousemove)
    document.addEventListener('touchend', this.onMouseup)
  }

  handleMouseUp () {
    let initStartPoint = this.initStartPoint
    let initEndPoint = this.initEndPoint
    if (initEndPoint && initStartPoint.x !== initEndPoint.x && initStartPoint.y !== initEndPoint.y) {
      let start = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
      let end = getInitialPoint(initEndPoint, this.viewport, this.viewport.scale)
      
      const newStart = {
        x: Math.min(start.x, end.x),
        y: Math.min(start.y, end.y)
      }
      const newEnd = {
        x: Math.max(start.x, end.x),
        y: Math.max(start.y, end.y)
      }
      
      const rect = {
        left: newStart.x,
        top: newStart.y,
        right: newEnd.x,
        bottom: newEnd.y
      }

      const annotationData = {
        operate: "add-form",
        type: 'signatureFields',
        pageIndex: this.page,
        date: new Date(),
        rect,
        isSigned: 0,
      }

      let index = 1
      if (this.layer.annotationStore.annotationsAll) {
        let annotArr = Object.values(this.layer.annotationStore.annotationsAll).reduce(function(acc, curr) {
          return acc.concat(curr);
        }, []);
    
        const textfieldArr = annotArr.filter(item => item.type === 'signatureFields')
        for (let i = 0; i <= textfieldArr.length; i++) {
          const name = 'SignatureFormField' + (i + 1)
          if (textfieldArr.every(item => item.fieldName !== name)) {
            index = i + 1
            break
          }
        }
      }
      annotationData.fieldName = 'SignatureFormField' + index

      this.eventBus.dispatch('annotationChange', {
        type: 'add',
        show: true,
        annotation: annotationData
      })
    }
    // this.reset()
    
    this.initStartPoint = null
    this.initEndPoint = null
    if (this.shapeEle) this.shapeEle.remove()
    this.shapeEle = null
    this.svgElement.innerHTML = ''
    this.path = []
    document.removeEventListener('mousemove', this.onMousemove)
    document.removeEventListener('mouseup', this.onMouseup)
    
    document.removeEventListener('touchmove', this.onMousemove)
    document.removeEventListener('touchend', this.onMouseup)

    if (this.tool === 'signatureFields') document.getElementById('createSignFieldButton').click()
  }

  handleMouseMove (event) {
    let { x, y } = getAbsoluteCoordinate(this.container, event)
    const { width, height } = this.viewport
    const scale = this.viewport.scale
    x = Math.min(width, x)
    x = Math.max(0, x)
    y = Math.min(height, y)
    y = Math.max(0, y)
    this.initEndPoint = { x, y }
    if (this.initStartPoint.x !== this.initEndPoint.x && this.initStartPoint.y !== this.initEndPoint.y) {
      if (!this.shapeEle) {
        const shapeEle = createElement('div', {
          'backgroundColor': '#93B9FD',
          'opacity': '0.3',
          'position': "absolute"
        })
        this.shapeEle = shapeEle
        this.scene = this.container.querySelector('.annotationLayer')
        this.scene.append(this.shapeEle)
      } else {
        if (event.shiftKey) {
          const { initStartPoint, initEndPoint } = this
          const distanceX = Math.abs(initEndPoint.x - initStartPoint.x)
          const distanceY = Math.abs(initEndPoint.y - initStartPoint.y)
          const distance = Math.min(distanceX, distanceY)
          if (initStartPoint.x < initEndPoint.x) {
            initEndPoint.x = initStartPoint.x + distance
          } else {
            initEndPoint.x = initStartPoint.x - distance
          }
          if (initStartPoint.y < initEndPoint.y) {
            initEndPoint.y = initStartPoint.y + distance
          } else {
            initEndPoint.y = initStartPoint.y - distance
          }
        }
        const rect = this.calculate(this.initStartPoint, this.initEndPoint)

        const shapeEle = this.shapeEle
        shapeEle.style.top = `${rect.top}px`;
        shapeEle.style.left = `${rect.left}px`;
        shapeEle.style.width = `${Math.abs(rect.width - 1)}px`;
        shapeEle.style.height = `${Math.abs(rect.height - 1)}px`;
      }
    }
  }
  
  rectCalc ({ start, end }) {
    return {
      top: start.y < end.y ? start.y : end.y,
      left: start.x < end.x ? start.x : end.x,
      width: Math.abs(end.x - start.x),
      height: Math.abs(end.y - start.y),
    };
  };

  calculate (start, end) {
    const initRect = this.rectCalc({ start, end });
    const actualbdwidth = 1 * this.viewport.scale

    return {
      top: initRect.top - actualbdwidth,
      left: initRect.left - actualbdwidth,
      width: initRect.width + actualbdwidth * 2,
      height: initRect.height + actualbdwidth * 2,
    }
  }
}
