<template>
  <div
    v-if="visible"
    :class="[{ 'is-fullscreen': fullscreen }]"
  >
    <el-dialog
      ref="dialog"
      :title="title"
      :visible="visible"
      :top="fullscreen? '0': top"
      :width="fullscreen ? '100%' : width"
      :modal="false"
      lock-scroll
      :z-index="dialogZIndex"
      class="esv-dialog"
      :before-close="handleClose"
    >
      <slot />
    </el-dialog>
    <div v-if="modalVisible" class="esv-modal" :style="modalStyle" />
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { addClass, getStyle, hasClass, removeClass } from 'element-ui/src/utils/dom'
import getScrollBarWidth from 'element-ui/src/utils/scrollbar-width'
let scrollBarWidth
export default {
  name: 'EsvDialog',
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: ''
    },
    // eslint-disable-next-line vue/require-default-prop
    width: String,
    top: {
      type: String,
      default: '15vh'
    },
    fullscreen: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogZIndex: 2000,
      modalStyle: {
        zIndex: 1999
      },
      modalVisible: true,
      currentRouteName: null
    }
  },
  computed: {
    routeName() {
      return this.$route.name
    },
    ...mapState({
      dialogs: state => state.esvDialog.dialogs
    })
  },
  created() {
    const routeName = this.$route.name
    this.currentRouteName = routeName
    if (this.dialogs[routeName] && this.dialogs[routeName].length > 0) {
      this.dialogZIndex = this.dialogs[routeName][0].dialogZIndex + 2
      this.modalStyle.zIndex = this.dialogs[routeName][0].modalStyle.zIndex + 2
      this.modalVisible = this.dialogs[routeName][0].modalVisible
    }
    this.$store.dispatch('esvDialog/setDialog', {
      name: routeName,
      data: {
        dialogZIndex: this.dialogZIndex,
        modalStyle: this.modalStyle,
        modalVisible: this.modalVisible
      }
    })
    this.$store.dispatch('esvDialog/addDialogCache', routeName)
    this.opened()
  },
  beforeDestroy() {
    this.close()
  },
  methods: {
    handleClose(done) {
      this.close()
      done()
    },
    close() {
      const routeName = this.currentRouteName
      this.$emit('update:visible', false)
      this.$store.dispatch('esvDialog/removeDialog', {
        name: routeName,
        index: this.dialogs[routeName].length - 1
      })
      this.$store.dispatch('esvDialog/delCachedDialog', routeName)
      document.body.style.paddingRight = this.bodyPaddingRight
      removeClass(document.body, 'el-popup-parent--hidden')
    },
    opened() {
      this.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden')
      if (this.withoutHiddenClass) {
        this.bodyPaddingRight = document.body.style.paddingRight
        this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10)
      }
      scrollBarWidth = getScrollBarWidth()
      const bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight
      const bodyOverflowY = getStyle(document.body, 'overflowY')
      if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) {
        document.body.style.paddingRight = this.computedBodyPaddingRight + scrollBarWidth + 'px'
      }
      addClass(document.body, 'el-popup-parent--hidden')
    }
  }
}
</script>

<style scoped lang="scss">
  .esv-modal{
    position: fixed;
    top: 50px;
    left: 210px;
    width: 100%;
    height: 100%;
    opacity: .5;
    background: #000;
    z-index: 1999;
    transition: left 0.28s;
  }

</style>
