<script setup lang="ts">
  /**
   * 提供模板规范代码参考,请尽量保证编写代码风格跟模板规范代码一致
   * 采用vben-动态表格表单封装组件编写,采用 setup 写法
   * Copyright © 2023-2023 <a href="https://godolphinx.org">海豚生态开源社区</a> All rights reserved.
   * author wangxiang4
   */
  import { reactive, ref, toRaw, watch } from 'vue';
  import { BasicTable, useTable } from '/@/components/Table';
  import DeptTree from '/@/views/system/user/DeptTree.vue';
  import { listUser } from '/@/api/platform/system/controller/user';
  import { columns, searchFormSchema } from './userPicker.data';
  import { BasicModal, ModalProps, useModalInner } from '/@/components/Modal';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { ScrollContainer } from '/@/components/Container';
  import { useAppStore } from '/@/store/modules/app';
  import { isArray } from '/@/utils/is';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { propTypes } from '/@/utils/propTypes';

  const props = defineProps({
    limit: propTypes.number.def(0),
    title: propTypes.string.def('用户选择'),
    emitEventNameClosable: propTypes.bool.def(false)
  });

  /** 类型规范统一声明定义区域 */
  interface TableState {
    ids: string[];
    single: boolean;
    multiple: boolean;
    searchInfo: Recordable;
    tag: string;
    emitEventName: string;
  }

  /** 通用变量统一声明区域 */
  const appStore = useAppStore();
  const darkMode = appStore.getDarkMode;
  const { prefixCls } = useDesign('user-picker');
  const { createMessage } = useMessage();
  const state = reactive<TableState>({
    // 选中数组
    ids: [],
    // 非单个禁用
    single: true,
    // 非多个禁用
    multiple: true,
    // 搜索信息
    searchInfo: {},
    // 操作标签
    tag: '',
    // 组件触发的自定义名称
    emitEventName: ''
  });
  const [registerTable, { reload, clearSelectedRowKeys, getSelectRows, setSelectedRowKeys, setProps }] = useTable({
    title: '用户列表',
    api: listUser,
    rowKey: 'id',
    columns,
    formConfig: {
      compact: true,
      labelWidth: 100,
      schemas: searchFormSchema,
      autoSubmitOnEnter: true,
      showAdvancedButton: true,
      autoAdvancedLine: 3,
      fieldMapToTime: [['dateRange', ['beginTime', 'endTime'], 'YYYY-MM-DD']]
    },
    maxHeight: 450,
    rowSelection: { type: 'checkbox' },
    useSearchForm: true,
    showTableSetting: true,
    bordered: true,
    clickToRowSelect: false,
    showIndexColumn: false,
    searchInfo: state.searchInfo,
    handleSearchInfoFn: () => clearSelectedRowKeys()
  });
  watch(() => props.limit, limit => {
    const rowSelectType = limit === 1 ? 'radio' : 'checkbox';
    setProps({
      rowSelection: { type: rowSelectType },
    });
  });
  const modal = ref();
  /** https://v3.cn.vuejs.org/api/options-data.html#emits */
  const emit = defineEmits(['success', 'register'] as Recordable);
  const [registerModal, { setModalProps, closeModal, changeLoading }] = useModalInner(async (data: BoxPayload = { _tag: '' }) => {
    changeLoading(true);
    // 处理清除脏数据
    await handleRefreshTable();
    // 处理设置数据
    state.tag = data._tag;
    const { ids, emitEventName } = data.record as Recordable;
    isArray(ids) && setSelectedRowKeys(ids);
    const modalProps: Partial<ModalProps> = { title: props.title };
    state.emitEventName = emitEventName || 'success';
    // 为后续扩展做准备,采用tag标签区分操作(预留)
    switch (state.tag) {
      case 'single':
        break;
      case 'multiple':
        break;
    }
    // 尾部:设置处理后的最终配置数据
    setModalProps(modalProps);
    changeLoading(false);
  });

  /** 处理多选框选中数据 */
  function handleSelectionChange(selection?: Recordable) {
    const rowSelection = toRaw(selection?.keys) || [];
    state.ids = rowSelection;
    state.single = rowSelection.length != 1;
    state.multiple = !rowSelection.length;
  }

  /** 处理表格刷新 */
  async function handleRefreshTable() {
    clearSelectedRowKeys();
    await reload();
  }

  /** 处理部门管理点击 */
  function handleSelect(departId: string) {
    state.searchInfo.deptId = departId;
    handleRefreshTable();
  }

  /** 处理弹出框提交 */
  async function handleSubmit() {
    try {
      if (getSelectRows().length === 0) {
        return createMessage.error('请选择一个用户!');
      } else if (props.limit !== 0 && props.limit < getSelectRows().length) {
        return createMessage.error(`最多只能选择${props.limit}个用户!`);
      }
      closeModal();
      if (props.emitEventNameClosable) {
        emit('success', state.emitEventName ,(getSelectRows()));
      } else {
        emit(state.emitEventName, toRaw(getSelectRows()));
      }
    } finally {
      setModalProps({ confirmLoading: false });
    }
  }
</script>

<template>
  <div ref="modal" :class="prefixCls">
    <BasicModal
      v-bind="$attrs"
      width="1600px"
      :minHeight="600"
      :getContainer="modal"
      @ok="handleSubmit"
      @register="registerModal"
    >
      <a-layout>
        <a-layout-sider :width="250" :theme="darkMode">
          <DeptTree class="sidebar" @select="handleSelect"/>
        </a-layout-sider>
        <a-layout-content>
          <BasicTable @register="registerTable" @selection-change="handleSelectionChange"/>
        </a-layout-content>
        <a-layout-sider :theme="darkMode">
          <a-divider>选择记录</a-divider>
          <ScrollContainer class="pl-2">
            <a-tag v-for="row in getSelectRows()"
                   :key="row.id"
                   color="processing"
            >
              {{ row.username }}
            </a-tag>
          </ScrollContainer>
        </a-layout-sider>
      </a-layout>
    </BasicModal>
  </div>
</template>

<style scoped lang="less">
  @prefix-cls: ~'@{namespace}-user-picker';

  .@{prefix-cls} {
    .sidebar {
      max-height: 700px;
    }

    :deep(.ant-modal) {
      top: 20px;
    }

    .scroll-container {
      max-height: 660px;
      .ant-tag {
        margin: 0 0 5px 8px;
      }
    }
  }

</style>
