import { TextEditor } from './text_editor';
import { ImageEditor } from './image_editor';
import AddText from './add_text.js';
import AddImage from './add_image.js';

export class ContentContainer {
  constructor(options) {
    this.pageViewer = options.pageViewer
    this.eventBus = options.eventBus
    this.pageIndex = options.pageIndex
    this.pagePtr = options.pagePtr
    this.messageHandler = options.messageHandler
    this.pageDiv = options.pageDiv
    this.viewport = options.viewport
    this.scale = options.scale
    this.$t = options.$t

    this._cancelled = false
    this.destroyed = false
    this.rendered = false
    this.frameEditorList = []
    this.tool = this.pageViewer.tool || ''
    this.color = this.pageViewer.color || ''
    this._selectedFrameIndex = -1

    this.onHandleTool = this.handleTool.bind(this)
    this.onKeydown = this.handleKeyDown.bind(this)
  }

  async init() {
    const { editPagePtr } = await this.messageHandler.sendWithPromise('InitEditPage', {
      pagePtr: this.pagePtr
    })
    this.editPagePtr = editPagePtr

    // await this.messageHandler.sendWithPromise('SetFontCallBackForEditPage', {
    //   editPagePtr: this.editPagePtr,
    //   fontFile: this.pageViewer.fontFile,
    //   fontName: 'DroidSansFallbackFull'
    // })
  }

  async render () {
    if (this._cancelled || this.contentContainer) {
      return;
    }

    const contentContainer = document.createElement('div')
    contentContainer.className = 'contentContainer'
    this.contentContainer = contentContainer
    this.pageDiv.append(this.contentContainer)

    await this.init()
    
    this.eventBus._on('toolChanged', this.onHandleTool)
    document.addEventListener('keydown', this.onKeydown)

    const result = await this.messageHandler.sendWithPromise('BeginEdit', {
      editPagePtr: this.editPagePtr,
      type: 1 | 2
    })

    if (result && result.code) {
      console.log(result.message)
      alert(result.message)
      return false
    }

    const editAreaCount = await this.messageHandler.sendWithPromise('GetEditAreaCount', this.editPagePtr)
    
    for (let i = 0; i < editAreaCount; i++) {
      const editAreaPtr = await this.messageHandler.sendWithPromise('GetEditArea', {
        editPagePtr: this.editPagePtr,
        index: i
      })
      if (!editAreaPtr) continue

      const isTextPtr = await this.messageHandler.sendWithPromise('IsTextArea', editAreaPtr)
      if (isTextPtr) {
        const frameEditor = new TextEditor({
          eventBus: this.eventBus,
          contentContainer: this,
          container: this.contentContainer,
          pagePtr: this.pagePtr,
          editPagePtr: this.editPagePtr,
          editAreaPtr,
          editAreaIndex: i,
          viewport: this.viewport,
          scale: this.scale,
          messageHandler: this.messageHandler,
          pageViewer: this.pageViewer,
          hidden: this.tool === 'addImage' || this.tool === 'editImage'
        })
        this.frameEditorList.push(frameEditor)
        continue
      }

      const isImagePtr = await this.messageHandler.sendWithPromise('IsImageArea', editAreaPtr)
      if (isImagePtr) {
        const frameEditor = new ImageEditor({
          eventBus: this.eventBus,
          contentContainer: this,
          container: this.contentContainer,
          pagePtr: this.pagePtr,
          editPagePtr: this.editPagePtr,
          editAreaPtr,
          editAreaIndex: i,
          viewport: this.viewport,
          scale: this.scale,
          messageHandler: this.messageHandler,
          pageViewer: this.pageViewer,
          $t: this.$t,
          hidden: this.tool === 'addText' || this.tool === 'editText'
        })
        this.frameEditorList.push(frameEditor)
      }
    }

    if (this.tool === 'addText') {
      this.addTextManager()
    }
    if (this.tool === 'addImage') {
      this.addImageManager()
    }

    this.destroyed = false
    this.rendered = true
  }

  show () {
    this.contentContainer.style.display = 'block'
  }

  hide () {
    this.contentContainer.style.display = 'none'
    this.resetTools()
  }
  
  cancel () {
    this._cancelled = true
    this.destroy()
  }

  destroy () {
    if (this.destroyed || !this.rendered) return

    this.contentContainer?.remove()
    this.contentContainer = null

    this.resetTools()

    this.destroyed = true

    this.eventBus._off('toolChanged', this.onHandleTool)
    document.removeEventListener('keydown', this.onKeydown)

    this.messageHandler.sendWithPromise('ClearEditPage', this.editPagePtr)
  }

  handleTool({
    tool,
    color
  }) {
    this.tool = tool
    this.color = color

    if (this.textManager) {
      this.textManager.tool = tool
      this.textManager.color = color
    }
    if (this.imageManager) {
      this.imageManager.tool = tool
      this.imageManager.color = color
    }

    if (tool === 'addText') {
      if (this.imageManager) {
        this.imageManager.tool = ''
        this.imageManager.reset()
      }
      this.addTextManager()
    }
    if (tool === 'addImage') {
      if (this.textManager) {
        this.textManager.tool = ''
        this.textManager.reset()
      }
      this.addImageManager()
    }

    if (this.tool === 'addText' || this.tool === 'editText') {
      this.eventBus.dispatch('showContentEditorType', 'text')
    } else if (this.tool === 'addImage' || this.tool === 'editImage') {
      this.eventBus.dispatch('showContentEditorType', 'image')
    } else {
      this.eventBus.dispatch('showContentEditorType', '')
    }
  }

  addTextManager () {
    if (this.textManager) {
      this.textManager.init()
    } else {
      this.textManager = new AddText({
        tool: this.tool,
        color: this.color,
        container: this.pageDiv,
        viewport: this.viewport,
        scale: this.scale,
        page: this.page,
        eventBus: this.eventBus,
        contentContainer: this
      })
    }
  }

  addImageManager () {
    if (this.imageManager) {
      this.imageManager.init()
    } else {
      this.imageManager = new AddImage({
        tool: this.tool,
        color: this.color,
        container: this.pageDiv,
        viewport: this.viewport,
        scale: this.scale,
        page: this.page,
        eventBus: this.eventBus,
        contentContainer: this,
        $t: this.$t
      })
    }
  }

  // 添加编辑区域
  async addTextEditor (data) {
    const { rect, fontData, alignType } = data
    const editAreaPtr = await this.messageHandler.sendWithPromise('CreateNewTextArea', {
      pagePtr: this.pagePtr,
      editPagePtr: this.editPagePtr,
      rect,
      fontData,
      alignType
    })

    if (!editAreaPtr) return

    const frameEditor = new TextEditor({
      eventBus: this.eventBus,
      contentContainer: this,
      container: this.contentContainer,
      pagePtr: this.pagePtr,
      editPagePtr: this.editPagePtr,
      editAreaPtr,
      editAreaIndex: this.frameEditorList.length,
      viewport: this.viewport,
      scale: this.scale,
      messageHandler: this.messageHandler,
      newAdd: true,
      pageViewer: this.pageViewer
    })
    this.frameEditorList.push(frameEditor)
  }

  // 添加图片区域
  async addImageEditor (data) {
    const { rect, imageBase64 } = data
    const editAreaPtr = await this.messageHandler.sendWithPromise('CreateNewImageAreaByStream', {
      pagePtr: this.pagePtr,
      editPagePtr: this.editPagePtr,
      rect,
      imageBase64
    })

    if (!editAreaPtr) return

    const frameEditor = new ImageEditor({
      eventBus: this.eventBus,
      contentContainer: this,
      container: this.contentContainer,
      pagePtr: this.pagePtr,
      editPagePtr: this.editPagePtr,
      editAreaPtr,
      editAreaIndex: this.frameEditorList.length,
      viewport: this.viewport,
      scale: this.scale,
      messageHandler: this.messageHandler,
      newAdd: true,
      pageViewer: this.pageViewer,
      $t: this.$t
    })
    this.frameEditorList.push(frameEditor)
  }

  get selectedFrameIndex () {
    return this._selectedFrameIndex
  }

  set selectedFrameIndex (index) {
    this._selectedFrameIndex = index
  }

  removeEditor (index) {
    this.frameEditorList.splice(index, 1)
    this.frameEditorList.forEach((editor, i) => editor.editAreaIndex = i)
  }

  resetTools () {
    if (this.textManager) {
      this.textManager.tool = ''
      this.textManager.reset()
    }
    if (this.imageManager) {
      this.imageManager.tool = ''
      this.imageManager.reset()
    }
  }

  handleKeyDown (e) {
    const selectedEditor = this.frameEditorList[this._selectedFrameIndex]
    if (!selectedEditor || selectedEditor.state !== 1) return

    const keyCode = e.keyCode || e.which
    if (keyCode === 8 || keyCode === 46) { // 8 delete键，46 backspace键
      selectedEditor.remove()
    }
  }
}
