<template>
  <div class="n-slide-block" :class="{visible: nValue}" @u-validate-error="setValue(true)">
    <div class="n-slide-block-header">
      <div class="n-slide-block-trigger" :title="nValue ? '收起' : '展开'" @click="onTriggerClick">
        <div class="n-slide-block-bar"></div>
        <h4 class="n-slide-block-title">{{title}}</h4>
        <n-loading-icon v-if="loading" size="16" color="#919293"></n-loading-icon>
        <n-icon v-else class="n-slide-block-arrow" :class="{visible: nValue}" size="16" type="drop-down"></n-icon>
      </div>
      <div class="n-slide-block-prefix" v-show="nValue">
        <slot name="header"></slot>
      </div>
    </div>
    <n-slide-down :value="nValue" ref="slide">
      <div class="n-slide-block-space"></div>
      <div :class="'n-slide-block-mode-' + mode">
        <slot></slot>
      </div>
    </n-slide-down>
  </div>
</template>

<script>
import NLoadingIcon from '@uif/next/lib/components/loading-icon'
import NIcon from '@uif/next/lib/components/icon'
import NSlideDown from '@uif/next/lib/components/slide-down'
import {prop, promisify, findParentComponents} from '@uif/next/lib/utils/tools'
import vModel from '_common/vModel'

export default {
  name: 'n-slide-block',
  mixins: [vModel],
  components: {
    NIcon,
    NLoadingIcon,
    NSlideDown
  },
  props: {
    // 标题
    title: prop.string(''),
    // 显示状态（可以使用v-model双向绑定数据）
    value: prop.boolean(true),
    // mode(未实现) 自定义模式，用于设置展开面板样式
    mode: prop.inArray(['none', 'block', 'table', 'form'], 'none'),
    // 等待模式
    await: prop.boolean()
  },
  data () {
    return {
      nValue: this.await ? false : this.value,
      loading: this.await
    }
  },
  created () {
    this.broadcast(nav => {
      nav.$emit('u-created', {instance: this})
    })
  },
  methods: {
    onTriggerClick () {
      if (!this.loading) {
        this.nValue = !this.nValue
        this.$emit('u-change', this.nValue)
        this.broadcast(nav => {
          nav.$emit('u-change', {instance: this, value: this.nValue})
        })
      }
    },
    setValue (value) {
      this.nValue = value
    },
    // await 模式下，远程调用
    setLoaded () {
      if (this.await && !this.nValue) {
        const receiver = this.$refs.slide
        const promise = promisify(receiver.$once, receiver)('after')
        this.nValue = true
        this.loading = false
        return promise
      }
      return Promise.resolve()
    },
    broadcast (callback) {
      findParentComponents(this, 'n-slide-navs').forEach(callback)
    }
  }
}
</script>
