<template>
  <el-dialog
    ref="dialog"
    :width="width"
    :title="title"
    :before-close="handleClose"
    :visible.sync="childVisible"
    @open="handleOpen">
    <slot></slot>
  </el-dialog>
</template>

<script>

export default {
  props: {
    value: {
      type: Boolean,
      default: false
    },
    modelValue: {
      type: Boolean,
      default: undefined
    },
    title: {
      type: String,
      default: '标题'
    },
    width: {
      type: String,
      default: '50%'
    }
  },
  data () {
    return {
      childVisible: false
    }
  },
  watch: {
    value (val) {
      if (typeof this.modelValue === 'boolean') return
      this.childVisible = val
    },
    modelValue (val) {
      if (typeof val !== 'boolean') return
      this.childVisible = val
    }
  },
  created () {
    const visible = typeof this.modelValue === 'boolean' ? this.modelValue : this.value
    this.childVisible = !!visible
  },
  methods: {
    getChildComponent () {
      const dialog = this.$refs.dialog
      if (!dialog || !Array.isArray(dialog.$children) || !dialog.$children.length) {
        return null
      }
      return dialog.$children.find(child => child && child.$options && child.$options.name !== 'ElDialog') || dialog.$children[0] || null
    },
    finalizeClose (done) {
      const child = this.getChildComponent()
      this.childVisible = false
      this.$emit('input', false)
      this.$emit('update:modelValue', false)
      this.$nextTick(() => {
        if (child) {
          child.visible = false
        }
      })
      if (typeof done === 'function') {
        done()
      }
    },
    handleClose (done) {
      const child = this.getChildComponent()
      if (!child) {
        this.finalizeClose(done)
        return
      }

      // 子元素需要验证表单
      if (child.verify) {
        child.verify.then(val => {
          if (val) {
            this.finalizeClose(done)
          }
        }).catch(e => {
          this.$message.error('输入的信息有误，请检查')
        })
      } else {
        this.finalizeClose(done)
      }
    },
    handleOpen () {
      // 通知slot 弹出打开了
      this.$nextTick(() => {
        const child = this.getChildComponent()
        if (child) {
          child.visible = true
        }
      })
    }
  }
}
</script>

<style scoped>

</style>
