<template>
  <div>
    <a-row v-if="!hideTrigger" class="j-select-row" type="flex" :gutter="8">
      <a-col class="left">
        <a-select
          :value="displayValue"
          :placeholder="'请选择人员'"
          :disabled="disabled"
          :open="false"
          mode="multiple"
          :maxTagCount="3"
          style="width: 100%"
        />
      </a-col>
      <a-col class="right">
        <a-button type="primary" @click="open()" :disabled="disabled">选择</a-button>
      </a-col>
    </a-row>
    <a-modal
      :width="1200"
      :title="title"
      v-model:open="visible"
      centered
      :confirm-loading="confirmLoading"
      @ok="handleOk"
      @cancel="handleCancel"
      :mask-closable="false"
    >
      <div v-if="dataLoading" style="height: 556px; display: flex; align-items: center; justify-content: center">
        <a-spin tip="加载中..." />
      </div>
      <SzCollabUserSelect
        v-show="!dataLoading"
        ref="selectRef"
        :secLevel="secLevel"
        :departId="innerDepartId"
        :role="role"
        :isSpecial="isSpecial"
        :editableUsers="innerEditable"
        :readonlyUsers="innerReadonly"
        :excludedUserIds="excludedUserIds"
        @update:editableUsers="(v) => (tempEditable = v)"
        @update:readonlyUsers="(v) => (tempReadonly = v)"
      />
      <template #footer>
        <a-button @click="handleCancel">取消</a-button>
        <a-button type="primary" :loading="confirmLoading" @click="handleOk">确定</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useUserStore } from '/@/store/modules/user';
import SzCollabUserSelect from './SzCollabUserSelect.vue';
import type { UserItem, CollabConfirmResult } from './types';

const props = withDefaults(
  defineProps<{
    editableUserIds?: string;
    readonlyUserIds?: string;
    departId?: string;
    secLevel?: any;
    role?: string | number;
    isSpecial?: number;
    disabled?: boolean;
    title?: string;
    hideTrigger?: boolean;
    excludedUserIds?: string;
  }>(),
  {
    editableUserIds: '',
    readonlyUserIds: '',
    departId: '',
    secLevel: 0,
    role: 1,
    isSpecial: 0,
    disabled: false,
    title: '选择协作人',
    hideTrigger: false,
    excludedUserIds: '',
  }
);

const emit = defineEmits(['confirm']);

const userStore = useUserStore();
const selectRef = ref<InstanceType<typeof SzCollabUserSelect> | null>(null);
const visible = ref(false);
const dataLoading = ref(false);
const confirmLoading = ref(false);
let loadSeq = 0;
const innerEditable = ref<UserItem[]>([]);
const innerReadonly = ref<UserItem[]>([]);
const tempEditable = ref<UserItem[]>([]);
const tempReadonly = ref<UserItem[]>([]);

const innerDepartId = computed(() => {
  return props.departId || userStore.getUserInfo?.orgCode || '';
});

const displayValue = computed(() => {
  const names: string[] = [];
  for (const u of innerEditable.value) names.push(`[编]${u.realname}`);
  for (const u of innerReadonly.value) names.push(`[阅]${u.realname}`);
  return names;
});

async function loadUsers(valueStr: string, permission: '2' | '3') {
  if (!valueStr) return [];
  try {
    const res: any = await defHttp.get({
      url: '/sys/user/queryUserComponentData',
      params: { id: valueStr, isMultiTranslate: 'true', pageNo: 1, pageSize: 9999 },
    });
    return (res.records || res) as UserItem[];
  } catch {
    return [];
  }
}

async function loadInitialUsers() {
  const [editUsers, readUsers] = await Promise.all([
    loadUsers(props.editableUserIds, '2'),
    loadUsers(props.readonlyUserIds, '3'),
  ]);
  innerEditable.value = editUsers;
  innerReadonly.value = readUsers;
}

async function open(editIds?: string, readIds?: string) {
  if (props.disabled) return;
  visible.value = true;
  confirmLoading.value = false;

  const hasExplicitData = editIds !== undefined || readIds !== undefined;
  const hasPropsData = props.editableUserIds || props.readonlyUserIds;

  if (!hasExplicitData && !hasPropsData) {
    dataLoading.value = true;
    return;
  }

  dataLoading.value = true;
  const seq = ++loadSeq;

  const loadUsersTask = (async () => {
    let editU: UserItem[] = [];
    let readU: UserItem[] = [];
    if (hasExplicitData) {
      [editU, readU] = await Promise.all([loadUsers(editIds || ''), loadUsers(readIds || '')]);
    } else {
      [editU, readU] = await Promise.all([loadUsers(props.editableUserIds), loadUsers(props.readonlyUserIds)]);
    }
    if (seq !== loadSeq) return;
    innerEditable.value = editU;
    innerReadonly.value = readU;
    tempEditable.value = [...editU];
    tempReadonly.value = [...readU];
  })();

  const tableTask = selectRef.value?.resetSearch?.();

  await Promise.all([loadUsersTask, tableTask]);
  if (seq !== loadSeq) return;
  dataLoading.value = false;
}

function handleOk() {
  const result: CollabConfirmResult = selectRef.value?.getResult() || {
    editableIds: '', editableNames: '', readonlyIds: '', readonlyNames: '',
  };
  emit('confirm', result);
  visible.value = false;
}

function handleCancel() {
  visible.value = false;
}

defineExpose({ open, loadInitialUsers });
</script>

<style lang="less" scoped>
.j-select-row {
  @width: 82px;

  .left {
    width: calc(100% - @width - 8px);
  }

  .right {
    width: @width;
  }

  :deep(.ant-select-search__field) {
    display: none !important;
  }
}
</style>
