<template>
  <transition name="n-popup">
    <div class="n-popup" v-show="value" :class="classes">
      <n-drag class="n-popup-header" :draggable="!isMaximize && draggable" target="n-popup">
        <h2 class="n-popup-title">{{title}}</h2>
        <slot name="header"></slot>
        <n-icon v-if="maximize && isMaximize" type="minimize" size="16" scene="default" @click="isMaximize = false"></n-icon>
        <n-icon v-if="maximize && !isMaximize" type="maximize" size="16" scene="default" @click="isMaximize = true"></n-icon>
        <n-icon type="x" size="16" scene="default" @click="onClose"></n-icon>
      </n-drag>
<!--      <u-slide-navigation v-if="navigation" class="uif-popup-navigation" mode="dark"></u-slide-navigation>-->
      <div class="n-popup-center">
        <div class="n-popup-content" :class="[classes, contentClasses]">
          <slot></slot>
        </div>
      </div>
      <div class="n-popup-footer" v-if="hasFooter">
        <slot name="popup-footer">
          <slot name="footer"></slot>
          <n-button type="default" outline size="middle" @click="onClose">取消</n-button>
          <n-button type="primary" size="middle" :disabled="onConfirmDisabled" :loading="loading" @click="onConfirm">确认</n-button>
        </slot>
      </div>
    </div>
  </transition>
</template>

<script>
import NDrag from '@uif/next/lib/components/drag'
import NIcon from '@uif/next/lib/components/icon'
import NButton from '@uif/next/lib/components/button'
import { inArray, addListener, removeListener} from '@uif/next/lib/utils/tools'

export default {
  name: 'n-popup',
  components: {
    NDrag,
    NIcon,
    NButton
  },
  props: {
    value: {
      type: Boolean,
      default: false
    },
    // 标题
    title: {
      type: String
    },
    // 高度
    height: {
      validator (value) {
        return inArray(['middle', 'large'], value)
      },
      default: 'middle'
    },
    // 宽度
    width: {
      validator (value) {
        return inArray(['small', 'middle', 'large', 'auto'], value)
      },
      default: 'large'
    },
    // 弹性布局
    flex: {
      type: Boolean,
      default: false
    },
    // 最大化
    maximize: {
      type: Boolean,
      default: false
    },
    // 能否拖拽
    draggable: {
      type: Boolean,
      default: true
    },
    // navigation: {
    //   type: Boolean,
    //   default: false
    // },
    // 禁用确认按钮
    onConfirmDisabled: {
      type: Boolean,
      default: false
    },
    // 是否有footer
    hasFooter: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      loading: false,
      isMaximize: false
    }
  },
  computed: {
    // 窗口类名
    classes () {
      return {
        [`height-${this.height}`]: this.height,
        maximize: this.isMaximize
      }
    },
    contentClasses () {
      return {
        [`width-${this.width}`]: this.width,
        flex: this.flex,
        'has-footer': this.hasFooter
      }
    }
  },
  watch: {
    value: {
      immediate: true,
      handler (value, oldValue) {
        if (value) {
          this.afterVisible() // 显示回调
        } else if (oldValue) {
          this.afterDestroy() // 关闭回调
        }
      }
    }
  },
  mounted () {
    this.stateChangeListener(addListener)
  },
  beforeDestroy () {
    this.stateChangeListener(removeListener)
  },
  methods: {
    // 确认事件
    onConfirm (event) {
      this.$emit('confirm', event)
    },
    // 关闭弹窗
    close () {
      if (this.value) {
        this.$emit('input', false)
      }
    },
    /**
     * 内部事件
     * **/
    // 关闭弹窗
    onClose () {
      if (!this.loading) {
        this.close()
      }
    },
    findWrapper () {
      return this.$root.$refs.wrap
    },
    /**
     * 回调
     * **/
    // 显示
    afterVisible () {
      const wrap = this.findWrapper()
      if (wrap) wrap.onLoaded()
    },
    // 销毁
    afterDestroy () {
      const wrap = this.findWrapper()
      if (wrap) wrap.destroy()
    },
    // 绑定/解除 state change 事件
    stateChangeListener (fn) {
      const wrap = this.findWrapper()
      if (wrap && wrap.$el) {
        fn(wrap.$el, 'state-pending', this.onStartLoading)
        fn(wrap.$el, 'state-fulfilled', this.onEndLoading)
        fn(wrap.$el, 'state-rejected', this.onEndLoading)
      }
    },
    onStartLoading () {
      this.loading = true
    },
    onEndLoading () {
      this.loading = false
    }
  }
}
</script>
