import { createApp } from 'vue'
import Message from './message.vue'
import { CMessageOptions } from './message'

const createInstance = (cfg: CMessageOptions) => {
  const config = cfg || {}

  let targetElementId = ''
  let targetHTMLElement: HTMLElement | null = null

  if (config.to && config.to[0] === '#') {
    targetElementId = config.to.slice(1)
    targetHTMLElement = document.getElementById(targetElementId)
  }

  // 创建包裹容器
  const messageNode = document.createElement('div')

  const attr = document.createAttribute('class')

  if (targetHTMLElement) {
    attr.value = 'message'
  } else {
    attr.value = 'message message-body'
  }

  messageNode.setAttributeNode(attr)

  let messageList: HTMLCollectionOf<HTMLElement>

  let messageContainerHeight = 0
  const offsetTop = 12

  if (targetElementId && targetHTMLElement) {
    messageList = document
      .getElementById(targetElementId)
      ?.getElementsByClassName('message') as HTMLCollectionOf<HTMLElement>
  } else {
    messageList = document.getElementsByClassName('message-body') as HTMLCollectionOf<HTMLElement>
  }

  for (let i = 0; i < messageList.length; i++) {
    messageContainerHeight += messageList[i].offsetHeight
  }

  messageNode.style.top = `${messageContainerHeight + (messageList.length + 1) * offsetTop}px`

  // 创建实例并挂载
  const app: any = createApp(Message, {
    config,
    remove() {
      handleRemove()
    },
  })

  app.vm = app.mount(messageNode)

  if (targetHTMLElement) {
    targetHTMLElement.style.position = 'relative'
    messageNode.style.position = 'absolute'
    targetHTMLElement.appendChild(messageNode)
  } else {
    document.body.appendChild(messageNode)
  }

  app.close = () => {
    handleRemove()
  }

  // 取消挂载
  const handleRemove = () => {
    app.unmount(messageNode)

    if (targetHTMLElement) {
      targetHTMLElement.removeChild(messageNode)
    } else {
      document.body.removeChild(messageNode)
    }

    resetMsgTop()
  }

  const resetMsgTop = () => {
    for (let i = 0; i < messageList.length; i++) {
      messageList[i].style.top = `${offsetTop + i * (messageList[i].offsetHeight + offsetTop)}px`
    }
  }

  return app
}

export default createInstance
