import { getHtmlToText, getAbsoluteCoordinate, getInitialPoint, pastePlainText } from '../utils';
import { hexToRgb, onClickOutside } from '../../ui_utils';

// 绘制 Text
export default class Text {
  constructor ({
    tool,
    svgElement,
    layer,
    container,
    viewport,
    page,
    eventBus
  }) {

    this.textNoteStr = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
      <path fill-rule="evenodd" clip-rule="evenodd" d="M2.39961 3.60004H21.5996V18H11.9996L5.99961 21.6V18H2.39961V3.60004Z" fill="currentColor"/>
      <rect x="5.99902" y="7.20001" width="7.2" height="1.8" fill="white"/>
      <rect x="5.99902" y="11.4" width="12" height="1.8" fill="white"/>
    </svg>`
    this.deleteSvgStr = `<path xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" d="M14 1.5V4.5H19V5.5H16.5V18.5H3.5V5.5H1V4.5H6V1.5H14ZM4.5 5.5V17.5H15.5V5.5H4.5ZM13 2.5V4.5H7V2.5H13ZM8.5 8V15H7.5V8H8.5ZM12.5 15V8H11.5V15H12.5Z" fill="#333333"/>
    `
    this.layer = layer
    this._tool = tool
    this.color = '#FF0000'
    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
  }

  // Text 画布重置
  reset () {
    this.start = null
    this.end = null

    this.container.removeEventListener('click', this.onClick)
    const textElement = this.textElement
    const textEditorElement = this.textEditorElement
    if (textEditorElement) {
      textEditorElement.remove()
      textEditorElement.removeEventListener('blur', this.onBlur)
      textEditorElement.removeEventListener('paste', this.onPaste)
      this.textEditorElement = null
    }
    if (textElement) {
      textElement.remove()
      this.textElement = null
    }
  }

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

    this.container.addEventListener('click', this.onClick)
  }

  getTextRect () {
    const viewport = this.viewport
    const { scale } = this.viewport
    const actualStartPoint = getInitialPoint(this.start, viewport, scale)
    const actualEndPoint = getInitialPoint(this.end, viewport, scale)
    return {
      left: actualStartPoint.x,
      top: actualStartPoint.y,
      right: actualEndPoint.x,
      bottom: actualEndPoint.y
    }
  }

  // 失去焦点添加 Text
  handleText () {
    const textEditorElement = this.textEditorElement
    if (textEditorElement.innerText) {
      this.end = {
        x: this.start.x + 24,
        y: this.start.y - 24
      }
      const rect = this.getTextRect()
      
      let color = this.color

      const text = getHtmlToText(textEditorElement)
      const annotation = {
        operate: "add-annot",
        type: 'text',
        pageIndex: this.page,
        date: new Date(),
        color,
        opacity: 1,
        contents: text,
        rect
      }
      this.eventBus.dispatch('annotationChange', {
        type: 'add',
        annotation
      })
    }

    this.layer.addMode = false
    textEditorElement.remove()
    textEditorElement.removeEventListener('blur', this.onBlur)
    textEditorElement.removeEventListener('paste', this.onPaste)
    this.textElement.remove()
    this.textElement = null
    this.textEditorElement = null
  }

  // 失去焦点
  handleBlur (event) {
    if (this.textEditorElement) {
      this.handleText(event)
    }
  }

  // 处理画布上点击
  handleClick (event) {
    if (!this.textElement && !this.layer.selectedElementName) {
      this.layer.addMode = true
      this.renderTextElement(event)
      this.container.append(this.textElement)
      this.textEditorElement.focus()
    }
  }

  // 画布上渲染 FreeText 编辑框
  setTextEditor () {
    const textElementContainer = document.createElement('div')
    this.textElementContainer = textElementContainer
    this.setCss(textElementContainer, {
      position: 'absolute',
      left: '16px',
      top: '28px',
      border: '2px solid #FF0000',
      outline: 'none',
      padding: '0 8px 28px',
      borderRadius: '4px',
      background: '#FFFFFF',
      whiteSpace: 'pre-wrap',
      textAlign: 'left'
    })

    const title = document.createElement('div')
    title.className = 'text-title'
    title.innerText = this.layer.annotationStore.$t('header.note')

    textElementContainer.append(title)

    let textEditorElement = document.createElement('div')
    textEditorElement.setAttribute('role', 'textbox')
    textEditorElement.setAttribute('contenteditable', true)
    textEditorElement.setAttribute('spellcheck', false)
    this.setCss(textEditorElement, {
      width: '290px',
      height: '110px',
      fontSize: '16px',
      color: '#000',
      lineHeight: '1.2em',
      outline: 'none',
      overflow: 'auto',
      '-webkit-user-select': 'text'
    })
    textEditorElement.className = 'text-editor'
    this.textEditorElement = textEditorElement

    textElementContainer.append(textEditorElement)

    textEditorElement.addEventListener('paste', this.onPaste)
    onClickOutside([this.textElementContainer, this.textElement], this.onBlur.bind(this))
  }

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

  // 画布上渲染 FreeText
  renderTextElement (event) {
    const start = getAbsoluteCoordinate(this.container, event)
    this.start = {
      x: start.x - 12,
      y: start.y + 12
    }

    let textElement = document.createElement('div')
    this.setCss(textElement, {
      position: 'absolute',
      left: start.x - 12 + 'px',
      top: start.y - 12 + 'px',
      zIndex: 6,
      color: '#FF0000'
    })
    this.eventBus.dispatch('textAdd', {
      left: start.x - 12,
      top: start.y - 12,
    })
    textElement.innerHTML = this.textNoteStr

    textElement.className = 'text'

    this.textElement = textElement
    this.setTextEditor(start)
    this.textElement.append(this.textElementContainer)
  }

  handlePaste (event) {
    pastePlainText(event)
  }
}
