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

export default class AddText {
  constructor ({
    tool,
    color,
    container,
    pageViewer,
    viewport,
    page,
    eventBus,
    contentContainer
  }) {
    this._tool = tool
    this.color = color
    this.container = container
    this.pageViewer = pageViewer
    this.viewport = viewport
    this.page = page
    this.eventBus = eventBus
    this.contentContainer = contentContainer

    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.addEventListener('mousedown', this.onMousedown)
    this.container.addEventListener('touchstart', this.onMousedown)
    this.container.style.cursor = 'crosshair'
    this.container.style.touchAction = 'none'
    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.style.cursor = 'default'
      this.container.style.touchAction = ''

      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.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)
  }

  handleMouseDown (event) {
    if ((!event.target.className && !event.target.className.includes('contentContainer')) || this.contentContainer.selectedFrameIndex !== -1) 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.pageViewer.viewport, this.pageViewer.viewport.scale)
      let end = getInitialPoint(initEndPoint, this.pageViewer.viewport, this.pageViewer.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: newStart.y + 16
      }

      const data = {
        rect,
        fontData: {
          // fontName: 'DroidSansFallbackFull',
          fontName: 'Helvetica',
          fontSize: 14,
          r: 0,
          g: 0,
          b: 0,
          opacity: 1,
          isBold: 0,
          italic: 0,
        },
        alignType: 2
      }
      this.contentContainer.addTextEditor(data)
    }
    // this.reset()
    this.initStartPoint = null
    this.initEndPoint = null
    if (this.shapeEle) this.shapeEle.remove()
    this.shapeEle = null
    this.path = []
    document.removeEventListener('mousemove', this.onMousemove)
    document.removeEventListener('mouseup', this.onMouseup)
    
    document.removeEventListener('touchmove', this.onMousemove)
    document.removeEventListener('touchend', this.onMouseup)
  }

  handleMouseMove (event) {
    let { x, y } = getAbsoluteCoordinate(this.container, event)
    const { width, height } = this.pageViewer.viewport
    const scale = this.pageViewer.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': '#DDE9FF',
          'position': "absolute",
          'z-index': 3
        },
        {
          class: 'add-text'
        })
        this.shapeEle = shapeEle
        this.container.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.pageViewer.viewport.scale

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