"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _vue = require("vue");
var _comp = require("../../ui/src/comp");
var _ui = require("../../ui");
var _dom = require("../../ui/src/dom");
var _vn = require("../../ui/src/vn");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function createReactData() {
  return {
    staticPanes: [],
    cachePaneMaps: {},
    activeKeyFlag: 0,
    openKeyFlag: 0
  };
}
function createInternalData() {
  return {
    // esTime: null,
    activeKeyMaps: {},
    openKeyMaps: {}
  };
}
var _default = exports.default = (0, _comp.defineVxeComponent)({
  name: 'VxeCollapse',
  props: {
    modelValue: Array,
    options: Array,
    padding: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().collapse.padding
    },
    border: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().collapse.border
    },
    expandConfig: Object,
    size: {
      type: String,
      default: () => (0, _ui.getConfig)().collapse.size || (0, _ui.getConfig)().size
    }
  },
  emits: ['update:modelValue', 'load', 'change', 'toggle-expand'],
  setup(props, context) {
    const {
      emit,
      slots
    } = context;
    const xID = _xeUtils.default.uniqueId();
    const {
      computeSize
    } = (0, _ui.useSize)(props);
    const refElem = (0, _vue.ref)();
    const reactData = (0, _vue.reactive)(createReactData());
    const internalData = createInternalData();
    const refMaps = {
      refElem
    };
    const computeItemOptions = (0, _vue.computed)(() => {
      const {
        options
      } = props;
      return (options || []).filter(item => handleFilterItem(item));
    });
    const computeItemStaticOptions = (0, _vue.computed)(() => {
      const {
        staticPanes
      } = reactData;
      return staticPanes.filter(item => handleFilterItem(item));
    });
    const computeExpandOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().collapse.expandConfig, props.expandConfig);
    });
    const computeMaps = {};
    const $xeCollapse = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, (0, _ui.createEvent)(evnt, {
        $collapse: $xeCollapse
      }, params));
    };
    const collapseMethods = {
      dispatchEvent
    };
    const emitModel = value => {
      emit('update:modelValue', value);
    };
    const handleFilterItem = item => {
      const {
        permissionCode
      } = item;
      if (permissionCode) {
        if (!_ui.permission.checkVisible(permissionCode)) {
          return false;
        }
      }
      return true;
    };
    const updateModel = () => {
      const {
        modelValue
      } = props;
      const {
        openKeyMaps
      } = internalData;
      const activeMaps = {};
      if (modelValue) {
        modelValue.forEach(name => {
          if (!openKeyMaps[name]) {
            openKeyMaps[name] = true;
          }
          activeMaps[name] = true;
        });
      }
      internalData.activeKeyMaps = activeMaps;
      reactData.activeKeyFlag++;
      reactData.openKeyFlag++;
    };
    const handleOpen = name => {
      const {
        openKeyMaps
      } = internalData;
      if (name && !openKeyMaps[name]) {
        openKeyMaps[name] = true;
        dispatchEvent('load', {
          name
        }, null);
        return true;
      }
      return false;
    };
    const initDefaultName = list => {
      const {
        activeKeyMaps
      } = internalData;
      const nameMaps = {};
      if (list && list.length) {
        list.forEach(item => {
          const {
            name,
            preload
          } = item || {};
          if (name) {
            const isActive = activeKeyMaps[name];
            nameMaps[name] = {
              height: 0,
              loading: false
            };
            if (isActive || preload) {
              handleOpen(name);
            }
          }
        });
      }
      reactData.cachePaneMaps = nameMaps;
      reactData.openKeyFlag++;
    };
    const callSlot = (slotFunc, params) => {
      if (slotFunc) {
        if (_xeUtils.default.isString(slotFunc)) {
          slotFunc = slots[slotFunc] || null;
        }
        if (_xeUtils.default.isFunction(slotFunc)) {
          return (0, _vn.getSlotVNs)(slotFunc(params));
        }
      }
      return [];
    };
    const handleClickEvent = (evnt, item) => {
      let {
        activeKeyMaps
      } = internalData;
      const {
        esTime
      } = internalData;
      const expandOpts = computeExpandOpts.value;
      const {
        accordion
      } = expandOpts;
      const {
        name
      } = item;
      if (esTime) {
        clearTimeout(esTime);
      }
      if (name) {
        const headEl = evnt.currentTarget;
        const bodyEl = headEl.nextElementSibling;
        let expanded = false;
        if (activeKeyMaps[name]) {
          delete activeKeyMaps[name];
        } else {
          if (accordion) {
            activeKeyMaps = {};
          }
          expanded = true;
          activeKeyMaps[name] = true;
        }
        const startAnimation = () => {
          const itemEl = bodyEl.firstElementChild;
          if (itemEl) {
            bodyEl.style.height = (0, _dom.toCssUnit)(itemEl.scrollHeight);
            if (expanded) {
              internalData.esTime = setTimeout(() => {
                bodyEl.style.height = '';
                internalData.esTime = undefined;
              }, 200);
            } else {
              (0, _vue.nextTick)(() => {
                requestAnimationFrame(() => {
                  bodyEl.style.height = '';
                });
              });
            }
          }
        };
        const value = Object.keys(activeKeyMaps);
        internalData.activeKeyMaps = activeKeyMaps;
        handleOpen(name);
        reactData.activeKeyFlag++;
        reactData.openKeyFlag++;
        if (bodyEl) {
          const itemEl = bodyEl.firstElementChild;
          if (itemEl) {
            startAnimation();
          } else {
            bodyEl.style.height = '0';
            (0, _vue.nextTick)(startAnimation);
          }
        }
        emitModel(value);
        dispatchEvent('change', {
          value,
          name
        }, evnt);
        dispatchEvent('toggle-expand', {
          value,
          name,
          expanded
        }, evnt);
      }
    };
    const collapsePrivateMethods = {};
    Object.assign($xeCollapse, collapseMethods, collapsePrivateMethods);
    const renderList = itemList => {
      const {
        activeKeyFlag,
        openKeyFlag
      } = reactData;
      const {
        activeKeyMaps,
        openKeyMaps
      } = internalData;
      const expandOpts = computeExpandOpts.value;
      return itemList.map(item => {
        const {
          icon,
          name,
          title,
          slots
        } = item;
        const titleSlot = slots ? slots.title : null;
        const defaultSlot = slots ? slots.default : null;
        const isActive = name && activeKeyFlag && activeKeyMaps[name];
        return (0, _vue.h)('div', {
          class: 'vxe-collapse-item'
        }, [(0, _vue.h)('div', {
          class: 'vxe-collapse--item-header',
          onClick(evnt) {
            handleClickEvent(evnt, item);
          }
        }, [expandOpts.showIcon ? (0, _vue.h)('span', {
          class: 'vxe-collapse--item-switch'
        }, [(0, _vue.h)('i', {
          class: isActive ? (0, _ui.getIcon)().COLLAPSE_OPEN : (0, _ui.getIcon)().COLLAPSE_CLOSE
        })]) : (0, _ui.renderEmptyElement)($xeCollapse), icon ? (0, _vue.h)('span', {
          class: 'vxe-collapse--item-icon'
        }, [(0, _vue.h)('i', {
          class: icon
        })]) : (0, _ui.renderEmptyElement)($xeCollapse), (0, _vue.h)('span', {
          class: 'vxe-collapse--item-name'
        }, titleSlot ? callSlot(titleSlot, {
          name,
          title
        }) : `${title}`)]), (0, _vue.h)('div', {
          class: ['vxe-collapse--item-content', {
            'is--visible': isActive,
            'is--hidden': !isActive
          }]
        }, [name && openKeyFlag && openKeyMaps[name] ? (0, _vue.h)('div', {
          class: 'vxe-collapse--item-inner'
        }, [defaultSlot ? callSlot(defaultSlot, {
          name,
          title
        }) : '']) : (0, _ui.renderEmptyElement)($xeCollapse)])]);
      });
    };
    const renderVN = () => {
      const {
        padding,
        border
      } = props;
      const vSize = computeSize.value;
      const itemOptions = computeItemOptions.value;
      const itemStaticOptions = computeItemStaticOptions.value;
      const defaultSlot = slots.default;
      const itemList = defaultSlot ? itemStaticOptions : itemOptions;
      return (0, _vue.h)('div', {
        ref: refElem,
        class: ['vxe-collapse', {
          [`size--${vSize}`]: vSize,
          'is--padding': padding,
          'is--border': border
        }]
      }, [(0, _vue.h)('div', {
        class: 'vxe-collapse-slots'
      }, defaultSlot ? defaultSlot({}) : []), renderList(itemList)]);
    };
    const valFlag = (0, _vue.ref)(0);
    (0, _vue.watch)(() => props.modelValue ? props.modelValue.length : -1, () => {
      valFlag.value++;
    });
    (0, _vue.watch)(() => props.modelValue, () => {
      valFlag.value++;
    });
    (0, _vue.watch)(valFlag, () => {
      updateModel();
    });
    const optsFlag = (0, _vue.ref)(0);
    (0, _vue.watch)(() => props.options ? props.options.length : -1, () => {
      optsFlag.value++;
    });
    (0, _vue.watch)(() => props.options, () => {
      optsFlag.value++;
    });
    (0, _vue.watch)(optsFlag, () => {
      initDefaultName(props.options);
    });
    const stFlag = (0, _vue.ref)(0);
    (0, _vue.watch)(() => reactData.staticPanes ? reactData.staticPanes.length : -1, () => {
      stFlag.value++;
    });
    (0, _vue.watch)(() => reactData.staticPanes, () => {
      stFlag.value++;
    });
    (0, _vue.watch)(stFlag, () => {
      initDefaultName(reactData.staticPanes);
    });
    updateModel();
    initDefaultName(reactData.staticPanes.length ? reactData.staticPanes : props.options);
    (0, _vue.onUnmounted)(() => {
      const {
        esTime
      } = internalData;
      if (esTime) {
        clearTimeout(esTime);
      }
      _xeUtils.default.assign(reactData, createReactData());
      _xeUtils.default.assign(internalData, createInternalData());
    });
    (0, _vue.provide)('$xeCollapse', $xeCollapse);
    $xeCollapse.renderVN = renderVN;
    return $xeCollapse;
  },
  render() {
    return this.renderVN();
  }
});