<!--
 * @Author: 曹捷
 * @Date: 2021-12-07 16:19:13
 * @LastEditors: 曹捷
 * @LastEditTime: 2021-12-27 16:45:17
 * @Description:  单个折叠面板
 -待优化

  重复点击问题
  解决方案 ： 点击事件 防抖
-->
<template>
  <div class="obit-collapse">
    <div class="obit-collapse-header flex-l-r" ref="collapseHeader" :class="{ 'disable-header': !allowOpen }" @click="collapseOpen">
      <span class="header-info" v-if="!hasSlotHeader && !hasSlotTitle">
        {{ title }}
      </span>
      <slot name="title" v-if="!title"></slot>

      <span class="head-icon p-r-5" v-if="!hasSlotHeader">
        <i class="iconfont icon-arrow-right-bold" :class="{ openicon: panelOpen }"></i>
      </span>
      <slot name="header"></slot>
    </div>
    <div class="obit-collapse-content" ref="collapseContent" :class="{ 'collapse-open': panelOpen }" :style="height !== '' ? `height:${height}px` : ''">
      <slot></slot>
    </div>
  </div>
</template>

<script>
import { reactive, toRefs, nextTick, watch } from "vue";
export default {
  props: {
    border: {
      type: Boolean,
      default: false,
    },
    /**
     * * type String slot
     * * String优先级高于slot       */ title: {
      type: String,
      default: "",
    },
    /**       *
     * 当前面板是打开还是关闭状态
     *  */ open: {
      type: Boolean,
      default: false,
    },
    /**
     * *
     * 组件内部是否可以通过点击header区域 打开和关闭面板
     *  */
    allowOpen: {
      type: Boolean,
      default: true,
    },
    // 点击title区域 是否可以打开面板
    titleOpen: {
      type: Boolean,
      default: true,
    },
  },
  setup (props, context) {
    let _data = reactive({
      collapseContent: null,
      height: "",
      panelOpen: props.open,
      moveStatus: props.open,
      time: 200,
      num: 10,
      hasSlotHeader: false,
      hasSlotTitle: false,
      collapseHeader: null,
    });
    if (context.slots.header) {
      _data.hasSlotHeader = true;
    }
    if (context.slots.title) {
      _data.hasSlotTitle = true;
    }
    let _methods = {
      hasFirstChild (e) {
        let firstDom = _data.collapseHeader.firstElementChild;
        let dom = e.target;
        let result = false;
        while (
          dom.className.indexOf("obit-collapse-header") === -1 &&
          !result
        ) {
          if (dom === firstDom) {
            result = true;
          }
          dom = dom.parentElement;
        }
        return result;
      },
      collapseOpen (e) {
        if (!props.allowOpen) return;
        if (!props.titleOpen && _methods.hasFirstChild(e)) return;
        if (_data.moveStatus !== _data.panelOpen) {
          return;
        }
        if (_data.panelOpen) {
          _methods.closePanel();
        } else {
          _methods.openPanel();
        }
      },
      openPanel () {
        // 0.2s 跑完10次 每次 0.02s
        _data.panelOpen = true;
        let height = _data.collapseContent.scrollHeight;
        let step = height / _data.num;
        _data.height = 0;
        let openTime = setInterval(() => {
          _data.height += step;
          if (_data.height >= height) {
            clearInterval(openTime);
            context.emit("update:open", true);
            _data.moveStatus = true;
            _data.height = "";
          }
        }, _data.time / _data.num);
      },
      closePanel () {
        let height = _data.collapseContent.scrollHeight;
        let step = height / _data.num;
        _data.height = height;
        let openTime = setInterval(() => {
          if (_data.height - step > 0) {
            _data.height -= step;
          } else {
            _data.height = 0;
          }
          if (_data.height <= 0) {
            clearInterval(openTime);
            context.emit("update:open", false);
            _data.moveStatus = false;
            _data.panelOpen = false;
            // nextTick(() => {
            // _data.height = ''
            // })
          }
        }, _data.time / _data.num);
      },
    };
    return {
      ...toRefs(_data),
      ..._methods,
    };
  },
};
</script>

<style lang="less">
.obit-collapse {
  border-bottom: 1px solid @borderDark;
  .head-icon {
    .iconfont {
      display: inherit;
      transition: all 0.3s;
    }
    .openicon {
      transform: rotate(90deg);
    }
  }
  .obit-collapse-header {
    height: 40px;
    line-height: 40px;
    cursor: pointer;
  }
  .disable-header {
    cursor: not-allowed;
  }
  .obit-collapse-content {
    overflow: hidden;
    visibility: hidden;
    position: absolute;
  }
  .collapse-open {
    position: relative;
    visibility: visible;
  }
}
</style>