import context from './context'
import manager from './manager'
import SafeAreaPatch from '../../safe-area-patch'
import { addEvent, removeEvent } from '../../../src/utils/event'

const MODAL_OPEN_CLASS = 'bx-overlay-open'

export default {
  props: {
    // 和emit('input')配合
    value: Boolean,
    // 遮罩背景是否显示
    overlay: {
      type: Boolean,
      default: true,
    },
    // 点击遮罩是否关闭
    closeOnClickOverlay: {
      type: Boolean,
      default: true,
    },
    // 禁止document滚动
    lockScroll: {
      type: Boolean,
      default: false,
    },
    // 防止滚动穿透，页面会有轻微闪动
    preventScrollThrough: {
      type: Boolean,
      default: false,
    },
    // 是否兼容iphoneX，解决在app内不满一屏情况下的bug，废弃，改为补丁的方式
    supportIphoneX: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      // 记住打开overlay时 body 的位置
      scrollTop: 0,
      // Vue挂载的节点
      appNode: null,
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(val) {
        this[val ? 'open' : 'close']()
      },
    },
    overlay() {
      this.renderOverlay()
    },
  },
  beforeDestroy() {
    this.close()
  },
  deactivated() {
    this.close()
  },
  methods: {
    open() {
      if (this.opened) {
        return false
      }
      this.openBefore()
      this.renderOverlay()
      this.opened = true
      return this.opened
    },
    openBefore() {
      // 禁止滚动，在弹出层无需滚动时使用
      if (this.lockScroll) {
        addEvent(document, 'touchmove', this.onTouchMove)
      }
    },
    openAfter() {
      // 防止滚动穿透
      if (this.preventScrollThrough) {
        this.scrollTop =
          document.documentElement.scrollTop ||
          window.pageYOffset ||
          document.body.scrollTop
        if (!this.appNode) {
          this.appNode = this.findRootElement(this.$el)
        }
        this.appNode.classList.add(MODAL_OPEN_CLASS)
        this.appNode.style.top = `${-1 * this.scrollTop}px`
        // 增加了「MODAL_OPEN_CLASS」导致Body高度变化，因此需要更新安全区域补丁
        SafeAreaPatch.update()
      }
    },
    close() {
      if (!this.opened) {
        return false
      }
      this.closeBefore()
      manager.close(this)
      this.opened = false
      return this.opened
    },
    closeBefore() {
      if (this.lockScroll) {
        removeEvent(document, 'touchmove', this.onTouchMove)
      }
      if (this.preventScrollThrough && this.appNode) {
        this.appNode.classList.remove(MODAL_OPEN_CLASS)
        this.appNode.style.top = '0'
        window.scrollTo(0, this.scrollTop)
      }
    },
    // 透明遮罩动画结束后，调用
    closeAfter() {
      if (this.preventScrollThrough) {
        // 移除了「MODAL_OPEN_CLASS」导致Body高度变化，因此需要更新安全区域补丁
        SafeAreaPatch.update()
      }
    },
    renderOverlay() {
      if (this.overlay) {
        context.zIndex += 1
        manager.open(this, {
          zIndex: context.zIndex,
        })
      } else {
        manager.close(this)
      }
      this.$nextTick(() => {
        context.zIndex += 1
        this.$el.style.zIndex = context.zIndex
      })
    },
    onTouchMove(e) {
      e.preventDefault()
      e.stopPropagation()
    },
    // 查找Vue挂载的节点
    findRootElement($el) {
      let $rootNode = $el
      while ($rootNode.parentNode && $rootNode.parentNode.tagName !== 'BODY') {
        $rootNode = $rootNode.parentNode
      }
      if ($rootNode.parentNode && $el === $rootNode) {
        $rootNode = $rootNode.parentNode
      }
      return $rootNode
    },
  },
}
