<template>
  <div class="uif-slide-block" :class="{visible}" @u-validate-error="onValidateError">
    <div class="uif-slide-block-header" @click="handleHeaderClick">
      <div class="uif-slide-block-title" :class="{visible}" :title="visible ? '收起' : '展开'" @click="handleTitleClick">
        <u-icon class="trigger" scene="action" type="chevron-s-right"></u-icon>
        <span>{{title}}</span>
      </div>
      <u-icon class="uif-loading" type="spinner" scene="none" v-if="loading"></u-icon>
      <slot name="header"></slot>
    </div>
    <u-slide-down :value="visible" ref="slide">
      <div :class="'uif-slide-block-' + mode"><slot></slot></div>
    </u-slide-down>
  </div>
</template>

<script>
import {oneOf} from '@uif/core/lib/utils/assist'
import USlideDown from '@uif/core/lib/components/slide-down'
import UIcon from '@uif/core/lib/components/icon'
export default {
  name: 'u-slide-block',
  components: {UIcon, USlideDown},
  props: {
    value: {
      type: Boolean,
      default: true
    },
    title: {
      type: String,
      default: ''
    },
    // 等待模式
    await: {
      type: Boolean,
      default: false
    },
    trigger: {
      validator (value) {
        return oneOf(value, ['header', 'title'])
      },
      default: 'title'
    },
    // normal
    mode: {
      type: String,
      default: 'default'
    }
  },
  data () {
    return {
      visible: this.await ? false : this.value,
      loading: this.await
    }
  },
  watch: {
    visible (value) {
      if (this.value !== value) {
        this.$emit('input', value)
        this.$emit('change', value)
      }
    },
    value (value) {
      if (this.visible !== value) {
        this.visible = value
      }
    },
    await () {
      if (!this.await && this.loading) {
        this.setLoaded()
      }
    }
  },
  methods: {
    handleHeaderClick () {
      if (this.trigger === 'header') {
        this.setVisible(!this.visible)
      }
    },
    handleTitleClick () {
      if (this.trigger === 'title') {
        this.setVisible(!this.visible)
      }
    },
    setVisible (value) {
      this.visible = value
    },
    // await 模式下，远程调用
    setLoaded () {
      if (this.await && !this.visible) {
        return new Promise((resolve, reject) => {
          this.$refs.slide.$once('after', () => resolve(this))
          this.visible = true
          this.loading = false
        })
      }
      return Promise.resolve()
    },
    onValidateError () {
      this.setVisible(true)
    }
  }
}
</script>
