import dayjs from 'dayjs'
import { getAbsoluteCoordinate, getInitialPoint, getHtmlToText, pastePlainText } from '../utils';

// 绘制 Freetext
export default class Freetext {

  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.freetextElement = null
    this.start = null
    this.end = null

    this.onClick = this.handleClick.bind(this)
    this.onBlur = this.handleBlur.bind(this)
    this.onPaste = this.handlePaste.bind(this)
    this.init()
  }
  // 获取当前的工具类型
  get tool() {
    return this._tool
  }

  // 设置当前的工具类型
  set tool(toolType) {
    if (toolType === this._tool) return
    if (!toolType) {
      this.reset()
    }
    this._tool = toolType
  }

  // FreeText 画布重置
  reset() {
    const freetextElement = this.freetextElement

    this.container.removeEventListener('click', this.onClick)
    if (freetextElement) {
      this.handleFreetext()
    }
    this.start = null
    this.end = null
  }

  // FreeText 画布初始化
  init() {
    this.container.removeEventListener('click', this.onClick)
    this.container.addEventListener('click', this.onClick)
  }

  // 获取左下右上坐标点
  getFreetextRectPoint() {
    const start = this.start
    const end = this.end
    const startX = start.x
    const startY = start.y
    const endX = end.x
    const endY = end.y
    return {
      start: {
        x: startX,
        y: startY
      },
      end: {
        x: endX,
        y: endY
      }
    }
  }

  // 获取 FreeText 基于PDF规范坐标点
  getFreetextRect() {
    const viewport = this.viewport
    const { scale } = this.viewport
    const freetextRectPoint = this.getFreetextRectPoint()
    const actualStartPoint = getInitialPoint(freetextRectPoint.start, viewport, scale)
    const actualEndPoint = getInitialPoint(freetextRectPoint.end, viewport, scale)
    return {
      left: actualStartPoint.x,
      top: actualStartPoint.y,
      right: actualEndPoint.x,
      bottom: actualEndPoint.y
    }
  }

  // 失去焦点添加 FreeText
  handleFreetext() {
    const freetextElement = this.freetextElement
    if (freetextElement.innerText) {
      const elementRect = freetextElement.getBoundingClientRect()
      this.end = {
        x: this.start.x + elementRect.width,
        y: this.start.y + elementRect.height
      }
      const rect = this.getFreetextRect()

      const text = getHtmlToText(freetextElement)

      const annotation = {
        operate: "add-annot",
        type: 'freetext',
        pageIndex: this.page,
        date: new Date(),
        color: '#000000',
        fontSize: 16,
        fillTransparency: 1,
        fontName: 'Helvetica',
        opacity: 1,
        textAlignment: 'left',
        contents: text,
        rect
      }

      this.eventBus.dispatch('annotationChange', {
        type: 'add',
        show: true,
        annotation
      })
    }
    this.layer.addMode = false
    freetextElement.removeEventListener('blur', this.onBlur)
    freetextElement.removeEventListener('paste', this.onPaste)
    freetextElement.remove()
    this.freetextElement = null
  }

  // 失去焦点
  handleBlur() {
    this.handleFreetext()
  }

  // 处理画布上点击
  handleClick(event) {
    if (this.layer.selectedElementName) return
    const freetextElement = this.freetextElement
    if (freetextElement && event.target === freetextElement) return

    if (!freetextElement && !this.layer.selectedElementName) {
      this.layer.addMode = true
      this.renderFreetext(event)
    }
  }

  // 设置 css
  setCss(ele, cssText) {
    if (!ele) return
    if (cssText) {
      for (let key in cssText) {
        ele.style[key] = cssText[key]
      }
    }
  }

  // 画布上渲染 FreeText
  renderFreetext(event) {
    const start = getAbsoluteCoordinate(this.container, event)
    this.start = start
    if (!this.freetextElement) {
      const { width, height } = this.viewport
      const maxWidth = width - this.start.x
      const maxHeight = height - this.start.y

      let freetextElement = document.createElement('div')
      freetextElement.setAttribute('role', 'textbox')
      freetextElement.setAttribute('contenteditable', true)
      freetextElement.setAttribute('spellcheck', false)
      this.setCss(freetextElement, {
        position: 'absolute',
        left: start.x - 4 + 'px',
        top: start.y - 2 + 'px',
        maxWidth: maxWidth + 'px',
        maxHeight: maxHeight + 'px',
        minWidth: '20px',
        fontSize: '16px',
        textAlign: 'left',
        whiteSpace: 'pre-wrap',
        color: '#000',
        lineHeight: '1.2em',
        padding: '2px 4px',
        border: '1px solid #1460F3',
        overflow: 'auto',
        '-webkit-user-select': 'text'
      })
      freetextElement.className = 'freetext'
      freetextElement.addEventListener('blur', this.onBlur)
      freetextElement.addEventListener('paste', this.onPaste)

      this.freetextElement = freetextElement
      this.container.append(freetextElement)
      freetextElement.focus()
    }
  }

  handlePaste (event) {
    pastePlainText(event)
  }
}
