<template>
  <Cascader
    :value="innerValue"
    :options="options"
    placeholder="全部"
    :field-names="{
      label: 'departName',
      value: 'id',
      children: 'childDepart',
    }"
    :show-search="showSearch"
    :allow-clear="allowClear"
    :change-on-select="changeOnSelect"
    @change="handleChange"
  >
    <template #clearIcon>
      <slot name="clearIcon"></slot>
    </template>
    <template #displayRender="{ labels }">
      {{ labels[labels.length - 1] }}
    </template>
  </Cascader>
  <!-- <a-input>{{ shownText }}</a-input> -->
</template>

<script lang="ts">
  import { last } from 'lodash-es';
  import { defineComponent, ref, watch } from 'vue';
  // import { useMessage } from '/@/hooks/web/useMessage';
  import { propTypes } from '/@/utils/propTypes';
  import { useMineDepartmentStore } from '/@/store/modules/mine';
  import { Cascader } from 'ant-design-vue';

  /**
   * 矿区级联选择器，该组件会根据配置从store中获取初始数据
   *
   * 组件数据流梳理：初始化数据及选项 -> 更新数据 -> 同步STORE -> 计算组件内依赖
   *
   * 本组件在初始化后不再监听STORE中的数据变化，因为这样可能导致用户通过Tabs切换时出现数据混乱
   */
  export default defineComponent({
    name: 'MineCascader',
    components: { Cascader },
    props: {
      value: propTypes.string.def(''),
      placeholder: propTypes.string.def('全部'),
      /** 根节点ID，如果传入，组件将过滤该节点下的节点 */
      rootId: propTypes.string,
      /** 是否从已存储的信息中初始化组件值 */
      initFromStore: propTypes.bool.def(true),
      /** 是否在全局部门变化后主动提交change事件 */
      syncFromStore: propTypes.bool.def(true),
      showSearch: propTypes.bool.def(true),
      allowClear: propTypes.bool.def(true),
      changeOnSelect: propTypes.bool.def(true),
      // clearOnDestroy: propTypes.bool.def(false),
    },
    emits: ['change', 'update:value'],
    setup(props, { emit }) {
      // const { createMessage } = useMessage();
      const mineStore = useMineDepartmentStore();
      const innerValue = ref<string[]>([]);
      const options = ref(mineStore.getDepartTree);

      // if (props.clearOnDestroy) {
      //   const raw = getDepartId.value;
      //   onUnmounted(() => {
      //     mineStore.setDepartById(raw);
      //   });
      // }

      if (props.rootId) {
        options.value = mineStore.filterDepartTree((e) => e.parentId === props.rootId);
      }

      // 如果从STORE里初始化数据需要触发一次watcher以初始化组件状态
      if (props.initFromStore) {
        handleWatch(mineStore.getDepartId);
        // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值，手动触发一次emit
        handleChange([mineStore.getDepartId]);
      } else {
        handleWatch(props.value);
        // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值，手动触发一次emit
        handleChange([props.value]);
      }

      /**
       * change事件
       * @param e
       */
      function handleChange(value: any[] = []) {
        if (!mineStore.findDepartById(last(value), options.value)) {
          console.warn('[Change] The value provided is not included in MineOptions');
          const val = props.rootId || mineStore.getRootId;
          emit('update:value', val);
          emit('change', val);
        } else {
          emit('update:value', last(value));
          emit('change', last(value));
        }
      }

      function handleWatch(id: string = '') {
        if (id === '') {
          // 当监听到的数据为空时，99%的情况是外部操作导致，因此触发一次 change -> watch
          return handleChange([]);
        }
        // rootId提供了选项过滤功能，任何传入的值都应该检查
        if (!mineStore.findDepartById(id, options.value)) {
          console.warn('[Watch] The id provided is not included in MineOptions');
          innerValue.value = [];
        } else {
          const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
          innerValue.value = path;
        }

        const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
        innerValue.value = path;
      }

      watch(() => props.value, handleWatch);

      if (props.syncFromStore) {
        watch(
          () => mineStore.getDepartId,
          (v) => handleChange([v])
        );
      }

      return {
        innerValue,
        options,
        handleChange,
      };
    },
  });
</script>
