<template>
  <a-modal
    v-model:visible="myVisible"
    title="选择成员"
    :unmount-on-close="true"
    :footer="false"
    :width="width"
    :mask-closable="false"
    modal-class="user-select-modal"
  >
    <div class="user-select-modal-body flex-row">
      <div class="tree-box flex-1">
        <div class="search-box">
          <a-input
            :allow-clear="true"
            placeholder="搜索"
            @input="inputChange"
            @clear="inputChange('')"
          >
            <template #prefix>
              <icon-search />
            </template>
          </a-input>
        </div>
        <div
          v-if="realTreeData.length === 0"
          :style="{ height: `${height - 20}px` }"
          class="justify-center"
        >
          <a-empty description="没有匹配的部门/成员"></a-empty>
        </div>
        <a-tree
          v-else
          :checked-keys="checkedKeys"
          :checkable="checkedKeys.length < limit"
          :data="realTreeData"
          :field-names="{
            key: 'id',
            title: 'name'
          }"
          :block-node="true"
          :default-expand-all="true"
          :virtual-list-props="{
            height: `${height - 20}px`,
            fixedSize: true,
            buffer: 30
          }"
          :disabled="checkedKeys.length === limit"
          @check="handleCheck"
          @select="handleSelect"
        >
          <template #icon="{ node }">
            <div v-if="node.id === '0'" class="iconfont icon-enterprise dept-tree-icon"></div>
            <f-user-avatar
              v-else-if="node.type === 'user'"
              custom-class="dept-tree-icon"
              :text="node.name"
              :src="node.avatarUrl"
            ></f-user-avatar>
            <icon-user-group class="dept-tree-icon" v-else />
          </template>
          <template #title="nodeData">
            <item-node :item-data="nodeData" :search-key="searchKey" title-field="name"></item-node>
          </template>
        </a-tree>
      </div>
      <div class="list-box flex-1">
        <div>
          <div style="margin-bottom: 10px">
            <a-typography-text>
              {{
                checkedKeys.length === 0
                  ? '请从左侧选择成员'
                  : `已选择了${checkedKeys.length}位成员`
              }}{{ checkedKeys.length === limit ? `，` : '' }} </a-typography-text
            ><a-typography-text type="danger">
              {{ checkedKeys.length === limit ? `最多选择${limit}位` : '' }}
            </a-typography-text>
          </div>
          <a-scrollbar
            style="overflow-y: auto; padding-right: 20px"
            :style="{ height: `${height - 54}px` }"
          >
            <div
              v-for="node in checkedNodes"
              :key="node.id"
              class="align-center flex-row justify-between"
              style="padding: 6px 0"
            >
              <div class="align-center flex-row">
                <a-avatar style="margin-right: 10px" shape="square" :size="20"
                  >{{ node.name.substring(0, 1) }}
                </a-avatar>
                <a-typography-text>{{ node.name }}</a-typography-text>
              </div>
              <div style="padding: 0 4px; cursor: pointer" @click="handleUncheck(node)">
                <icon-close-circle-fill />
              </div>
            </div>
          </a-scrollbar>
          <div class="flex-row justify-end" style="padding-right: 20px; margin-top: 10px">
            <a-space>
              <a-button @click="handleCancel">取消</a-button>
              <c-button type="primary" @click="handleSubmit">确定</c-button>
            </a-space>
          </div>
        </div>
      </div>
    </div>
  </a-modal>
</template>
<script setup lang="ts">
import { computed, nextTick, ref, watch, watchEffect, withDefaults } from 'vue'
import { IconCloseCircleFill, IconUserGroup } from '@arco-design/web-vue/es/icon'
import _ from 'lodash'
import useSearch from '../_hooks/use-tree-search'
import { fetchUserTree } from '@/api/upms/dept'
import useCheck from './use-check'
import useAdaptSize from '@/components/f-user-select-modal/use-adapt-size'
import FUserAvatar from '../f-user-avatar/index.vue'
import { searchUserList } from './use-search'
import ItemNode from './f-user-select-modal-item-node.vue'

const props = withDefaults(
  defineProps<{
    visible: boolean
    limit?: number
    selectIds?: string[]
    /**
     * 忽略的ids
     */
    ignoreIds?: string[]
    autoClose?: boolean
  }>(),
  {
    limit: 99,
    selectIds: () => [],
    ignoreIds: () => [],
    autoClose: true
  }
)
const emit = defineEmits<{
  (event: 'update:visible', val: boolean): void
  (event: 'userListChange', val: any[]): void
  (event: 'change', checkKeys: string[], checkNodes: any[]): void
  (event: 'change', checkKeys: string[], checkNodes: any[], done: Function): void
}>()
// search
const { searchKey, treeData, realTreeData, inputChange } = useSearch(props.ignoreIds)
const userListData = computed(() => searchUserList(treeData.value))
// check
const { handleSelect, handleCheck, handleUncheck, synchronize, checkedKeys, checkedNodes } =
  useCheck(treeData, props.limit)
// load data
const load = () => {
  fetchUserTree().then((res) => {
    treeData.value = res
    nextTick(() => {
      emit('userListChange', userListData.value)
    })
    synchronize()
  })
}
load()
// v-model:select-ids
watch(
  () => props.selectIds,
  () => {
    checkedKeys.value = _.cloneDeep(props.selectIds)
    synchronize()
  },
  {
    immediate: true,
    deep: true
  }
)
// cal height
const { width, height } = useAdaptSize()

// modal visible
const myVisible = ref(false)
const backSelectIds = ref<string[]>([])
watchEffect(() => {
  emit('update:visible', myVisible.value)
})
watch(
  () => props.visible,
  () => {
    myVisible.value = props.visible
    // 打开对话框记录下此时选择的ids
    if (myVisible.value) {
      backSelectIds.value = _.cloneDeep(checkedKeys.value)
    }
    searchKey.value = ''
  }
)
// operation
const handleCancel = () => {
  myVisible.value = false
  // 如果点击了取消，重置为之前选择的ids
  checkedKeys.value = backSelectIds.value
  synchronize()
}
const handleSubmit = (done: Function) => {
  emit('change', _.cloneDeep(checkedKeys.value), _.cloneDeep(checkedNodes.value), (flag: any) => {
    if (flag !== false) {
      myVisible.value = false
      load()
    }
    done()
  })
  if (props.autoClose) {
    myVisible.value = false
    done()
    load()
  }
}

defineExpose({
  load
})
</script>
<style lang="scss">
.user-select-modal {
  .arco-modal-header {
    display: none;
  }

  .arco-modal-body {
    padding: 0;
    width: 100%;
    max-height: 100vh;
    overflow: hidden;
  }

  .tree-box,
  .list-box {
    padding: 20px 0 20px 20px;
  }

  .tree-box {
    border-right: 1px solid var(--color-neutral-3);

    .search-box {
      padding-right: 20px;
      padding-bottom: 8px;
    }
  }
}

.user-select-modal-body {
  .arco-virtual-list {
    overflow-x: hidden !important;
  }
  .arco-tree-node-selected {
    // .arco-avatar {
    //   background-color: rgb(var(--primary-5));
    // }
    .arco-tree-node-title {
      color: var(--color-text-1);
    }
  }
  .arco-card-body {
    padding: 0;
  }
  .arco-tree-node-title-text {
    min-width: 80px;
  }
}
</style>
