/**
 * @description upload attachment menu
 * @author wangfupeng
 */

import { DomEditor, IDomEditor, SlateRange, t } from '@wangeditor/editor'
import { IButtonMenu } from '@wangeditor/editor'
import { ATTACHMENT_SVG } from '../../constants/icon-svg'
import { IUploadConfigForAttachment } from './config'
import $ from '../../utils/dom'
import { insertAttachment, uploadAttachments } from './helper'

class UploadAttachmentMenu implements IButtonMenu {
  readonly title = t('attachment.upload')
  readonly iconSvg = ATTACHMENT_SVG
  readonly tag = 'button'

  getValue(editor: IDomEditor): string | boolean {
    // 无需获取 val
    return ''
  }

  isActive(editor: IDomEditor): boolean {
    // 任何时候，都不用激活 menu
    return false
  }

  exec(editor: IDomEditor, value: string | boolean) {
    const { allowedFileTypes = [], customBrowseAndUpload } = this.getMenuConfig(editor)

    // 自定义选择文件、并上传，如图床
    if (customBrowseAndUpload) {
      customBrowseAndUpload((fileName: string, link: string) =>
        insertAttachment(editor, fileName, link)
      )
      return
    }

    // 设置选择文件的类型
    let acceptAttr = ''
    if (allowedFileTypes.length > 0) {
      acceptAttr = `accept="${allowedFileTypes.join(', ')}"`
    }

    // 添加 file input（每次重新创建 input）
    const $body = $('body')
    const $inputFile = $(`<input type="file" ${acceptAttr} multiple/>`)
    $inputFile.hide()
    $body.append($inputFile)
    $inputFile.click()
    // 选中文件
    $inputFile.on('change', () => {
      const files = ($inputFile[0] as HTMLInputElement).files
      uploadAttachments(editor, files) // 上传文件
    })
  }

  isDisabled(editor: IDomEditor): boolean {
    const { selection } = editor
    if (selection == null) return true
    if (SlateRange.isExpanded(selection)) return true // 选区非折叠，禁用

    const selectedElems = DomEditor.getSelectedElems(editor)

    const hasVoidElem = selectedElems.some(elem => editor.isVoid(elem))
    if (hasVoidElem) return true // 选中了 void 元素，禁用

    const hasPreElem = selectedElems.some(elem => DomEditor.getNodeType(elem) === 'pre')
    if (hasPreElem) return true // 选中了 pre 原则，禁用

    return false
  }

  private getMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {
    // 获取配置，见 `./config.js`
    return editor.getMenuConfig('uploadAttachment') as IUploadConfigForAttachment
  }
}

export default UploadAttachmentMenu
