<script lang="ts" setup>
import type { Org, SelectOption, User } from '../../ts/flow.ts';
import { selectOrg, selectUser } from '@pubinfo/module-rbac';
import { postGroupFindPage } from '@/api/modules/assist/qunzujiekou.ts';
import { postBpmCategoryGetUserList } from '@/api/modules/bpmDefinition/bpMliuchengfenleikongzhiqi.ts';
import { postRbacPostFindPage } from '@/api/modules/rbac/gangweijiekou.ts';
import { postRbacRoleRolePage } from '@/api/modules/rbac/jiaosejiekou.ts';
import { postRbacOrgSearchOrgByIds } from '@/api/modules/rbac/zuzhijiekou.ts';
import { useElementsInfoStore } from '../../stores/elementsInfo.ts';
import { useSelectedInfoStore } from '../../stores/selectedInfo.ts';
import { CANDIDATE_STRATEGY, CandidateStrategy, MULTI_LEVEL_DEPT } from '../../ts/enum.ts';
import DrawerExpression from './drawer/drawerExpression.vue';

defineOptions({ name: 'UserTask' });
const lf: any = inject('lf');
const elementsInfoStore = useElementsInfoStore();
const selectedInfoStore = useSelectedInfoStore();

const formState = ref<any>({});

const drawerExpressionRef = ref<InstanceType<typeof DrawerExpression>>();

const selectedUsers = ref<User[]>([]);
const selectedDepts = ref<Org[]>([]);
onMounted(async () => {
  getRoleOptions();
  getPostOptions();
  getGroupOptions();
  getDeptGroupOptions();
  const elementInfo = elementsInfoStore.getElementById(selectedInfoStore.selectId) || {};
  formState.value = elementInfo.userTask ?? {
    candidateStrategy: '',
    userIds: [],
    roleIds: [],
    postIds: [],
    bmzd: '',
    deptIds: [],
    levelId: '',
    groupIds: [],
    yhzd: '',
    flowVar: '',
    skipExpression: '',
    rangeId: '1',
    deptLevelId: '',
    deptGrounpId: '',
    roleId: '',
  };
  if (elementInfo.userTask.userIds.length > 0) {
    const response = await postBpmCategoryGetUserList(elementInfo.userTask.userIds);
    if (response.success) {
      const userList = response.data || [];
      selectedUsers.value = userList.map((user: API.UserRespDto) => {
        return {
          userId: user.id,
          userName: user.nickname,
          orgId: user.deptId,
        };
      }) as User[];
    }
  }

  if (elementInfo.userTask.deptIds.length > 0) {
    const response = await postRbacOrgSearchOrgByIds(elementInfo.userTask.deptIds);
    if (response.success) {
      const deptList = response.data || [];
      selectedDepts.value = deptList.map((dept: API.PubOrg) => {
        return {
          orgId: dept.id,
          orgName: dept.name,
        };
      }) as Org[];
    }
  }
});

const tooltipMessage = computed(() => {
  if (formState.value.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
    return '指定部门向上';
  }
  else if (formState.value.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER) {
    return '表单内部门向上';
  }
  else {
    return '发起人部门向上';
  }
});
// 指定用户 start
function chooseUsers() {
  selectUser({
    modelValue: selectedUsers.value, // 回显时选中的数据
    multiple: true,
    onSubmit(selected = []) {
      // console.log(selected); // 点击确认后返回选中的数据
      selectedUsers.value = selected.map((user) => {
        return {
          orgId: user.orgId as string,
          userId: user.userId as string,
          userName: user.userName as string,
        };
      });
    },
  });
}
function handleUsersClose(tag: User) {
  selectedUsers.value = selectedUsers.value.filter(item => item.userId !== tag.userId);
}

watch(
  () => selectedUsers.value,
  (newVal) => {
    // todo: 这里会先触发一次elementsInfoStore.elements更改，导致xml保存；没有找到原因
    formState.value.userIds = newVal.map(item => item.userId);
  },
  { deep: true },
);
// 指定用户 end

// 指定角色 start
const roleOptions = ref<SelectOption[]>([]);
function getRoleOptions() {
  postRbacRoleRolePage({ currentPage: 1, pageSize: 1000 }).then((response) => {
    if (response.success) {
      roleOptions.value = (response.data?.records ?? []).map((item: any) => {
        return {
          label: item.name,
          value: item.id,
        };
      }) || [];
    }
  });
}
// 指定角色 end

// 指定岗位 start
const postOptions = ref<SelectOption[]>([]);
function getPostOptions() {
  postRbacPostFindPage({ currentPage: 1, pageSize: 1000 }).then((response) => {
    if (response.success) {
      postOptions.value = (response.data?.records ?? []).map((item: any) => {
        return {
          label: item.name,
          value: item.id,
        };
      }) || [];
    }
  });
}
// 指定岗位 end

// 指定部门 start
function chooseDepts() {
  selectOrg({
    multiple: true,
    modelValue: selectedDepts.value,
    onSubmit: (selectedOrgs: any[]) => {
      selectedDepts.value = selectedOrgs.map((org) => {
        return {
          orgId: org.orgId,
          orgName: org.orgName,
        };
      });
    },
  });
}
function handleDeptsClose(tag: Org) {
  selectedDepts.value = selectedDepts.value.filter(item => item.orgId !== tag.orgId);
}
watch(
  () => selectedDepts.value,
  (newVal) => {
    formState.value.deptIds = newVal.map(item => item.orgId);
  },
  { deep: true },
);
// 指定部门 end

// 指定用户组 start
const groupOptions = ref<SelectOption[]>([]);
function getGroupOptions() {
  postGroupFindPage({ currentPage: 1, pageSize: 1000, type: '2' }).then((response) => {
    if (response.success) {
      groupOptions.value = (response.data?.records ?? []).map((item: any) => {
        return {
          label: item.name,
          value: item.id,
        };
      }) || [];
    }
  });
}

// 指定用户组 end

// 指定部门组 start
const deptGrounpOptions = ref<SelectOption[]>([]);
function getDeptGroupOptions() {
  postGroupFindPage({ currentPage: 1, pageSize: 1000, type: '1' }).then((response) => {
    if (response.success) {
      deptGrounpOptions.value = (response.data?.records ?? []).map((item: any) => {
        return {
          label: item.name,
          value: item.id,
        };
      }) || [];
    }
  });
}

// 指定部门组 end

// 表单内用户字段选项
const yhzdOptions = ref<SelectOption[]>([]);
// 表单内部门字段选项
const bmzdOptions = ref<SelectOption[]>([]);

// 部分类型使用相同的字段，选择前需要清空或设置成默认值
function handleChange() {
  if (formState.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER
    || formState.value.candidateStrategy === CandidateStrategy.DEPT_LEADER) {
    formState.value.deptIds = [];
    selectedDepts.value = [];
  }
  if (formState.value.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
    formState.value.deptIds = [];
    selectedDepts.value = [];
    formState.value.levelId = 1;
  }
  if (formState.value.candidateStrategy === CandidateStrategy.START_USER_DEPT_LEADER
    || formState.value.candidateStrategy === CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
    || formState.value.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER) {
    formState.value.levelId = 1;
  }
  if (formState.value.candidateStrategy === CandidateStrategy.ROLE_IN_START_USER_DEPT) {
    formState.value.rangeId = '1';
    formState.value.deptLevelId = '';
    formState.value.deptGrounpId = '';
    formState.value.roleIds = [];
  }
}

function handleRangeChange() {
  if (formState.value.rangeId === '1') {
    formState.value.deptLevelId = 1;
  }
  if (formState.value.rangeId === '2') {
    formState.value.deptGrounpId = '';
  }
}

function getExcontent(excontent: string) {
  formState.value.flowVar = excontent;
}

function formStateToProps() {
  const props: any = {
    candidateStrategy: formState.value.candidateStrategy,
    candidateParam: '',
    skipExpression: formState.value.skipExpression || '',
  };
  switch (formState.value.candidateStrategy) {
    case CandidateStrategy.ROLE:
      props.candidateParam = formState.value.roleIds.join(',');
      break;
    case CandidateStrategy.DEPT_MEMBER:
    case CandidateStrategy.DEPT_LEADER:
      props.candidateParam = formState.value.deptIds.join(',');
      break;
    case CandidateStrategy.POST:
      props.candidateParam = formState.value.postIds.join(',');
      break;
    case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER:
      props.candidateParam = `${formState.value.deptIds.join(',')}|${formState.value.levelId}`;
      break;
    case CandidateStrategy.USER:
      props.candidateParam = formState.value.userIds.join(',');
      break;
    case CandidateStrategy.START_USER_DEPT_LEADER:
    case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER:
      props.candidateParam = formState.value.levelId;
      break;
    case CandidateStrategy.USER_GROUP:
      props.candidateParam = formState.value.groupIds.join(',');
      break;
    case CandidateStrategy.FORM_USER:
      props.candidateParam = formState.value.yhzd;
      break;
    case CandidateStrategy.FORM_DEPT_LEADER:
      props.candidateParam = `${formState.value.bmzd}|${formState.value.levelId}`;
      break;
    case CandidateStrategy.EXPRESSION:
      props.candidateParam = formState.value.flowVar;
      break;
    case CandidateStrategy.ROLE_IN_START_USER_DEPT:
      if (formState.value.rangeId === '1') {
        props.candidateParam = `1|${formState.value.deptLevelId}|${formState.value.roleId}`;
      }
      else {
        props.candidateParam = `2|${formState.value.deptGrounpId}|${formState.value.roleId}`;
      }
      break;
    default:
      props.candidateParam = '';
  }
  return props;
}

watch(() => formState, (newVal) => {
  // console.log('formState changed:', newVal);
  const props = formStateToProps();
  elementsInfoStore.updateElement(selectedInfoStore.selectId, {
    userTask: newVal,
  });
  lf.value.setProperties(selectedInfoStore.selectId, { userTask: props });
}, { deep: true });
</script>

<template>
  <a-form
    :model="formState"
    name="basic"
    :label-col="{ style: { width: '130px' } }"
    autocomplete="off"
  >
    <a-form-item
      label="规则类型"
      name="candidateStrategy"
    >
      <a-select
        v-model:value="formState.candidateStrategy"
        :options="CANDIDATE_STRATEGY"
        @change="handleChange"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.USER"
      label="指定用户"
      name="userIds"
    >
      <a-tag v-for="(tag, index) in selectedUsers" :key="index" class="mb-4px!" closable @close="handleUsersClose(tag)">
        {{ tag.userName }}
      </a-tag>
      <a-button size="small" type="primary" @click="chooseUsers">
        选择人员
      </a-button>
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.ROLE_IN_START_USER_DEPT"
      label="类型"
      name="rangeId"
    >
      <a-select
        v-model:value="formState.rangeId"
        style="width: 100%;"
        placeholder="请选择类型"
        :options="[{ label: '级别', value: '1' }, { label: '群组', value: '2' }]"
        @change="handleRangeChange"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.ROLE_IN_START_USER_DEPT
        && formState.rangeId === '1'"
      label="部门级别"
      name="deptLevelId"
    >
      <a-select
        v-model:value="formState.deptLevelId"
        style="width: 100%;"
        placeholder="请选择部门级别"
        :options="MULTI_LEVEL_DEPT"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.ROLE_IN_START_USER_DEPT
        && formState.rangeId === '2'"
      label="部门群组"
      name="deptGrounpId"
    >
      <a-select
        v-model:value="formState.deptGrounpId"
        style="width: 100%;"
        placeholder="请选择部门群组"
        :options="deptGrounpOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.ROLE_IN_START_USER_DEPT"
      label="指定角色"
      name="roleIds"
    >
      <a-select
        v-model:value="formState.roleId"
        style="width: 100%;"
        placeholder="请选择指定角色"
        :options="roleOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.ROLE"
      label="指定角色"
      name="roleIds"
    >
      <a-select
        v-model:value="formState.roleIds"
        mode="tags"
        style="width: 100%;"
        placeholder="请选择指定角色"
        :options="roleOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.POST"
      label="指定岗位"
      name="postIds"
    >
      <a-select
        v-model:value="formState.postIds"
        mode="tags"
        style="width: 100%;"
        placeholder="请选择指定岗位"
        :options="postOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.DEPT_MEMBER
        || formState.candidateStrategy === CandidateStrategy.DEPT_LEADER
        || formState.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER"
      label="指定部门"
      name="deptIds"
    >
      <a-tag v-for="(tag, index) in selectedDepts" :key="index" closable @close="handleDeptsClose(tag)">
        {{ tag.orgName }}
      </a-tag>
      <a-button size="small" type="primary" @click="chooseDepts">
        选择部门
      </a-button>
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER"
      label="表单内部门字段"
      name="bmzd"
    >
      <a-select
        v-model:value="formState.bmzd"
        :options="bmzdOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
        || formState.candidateStrategy === CandidateStrategy.START_USER_DEPT_LEADER
        || formState.candidateStrategy === CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
        || formState.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER"
      label="部门负责人来源"
      name="levelId"
      :tooltip="tooltipMessage"
    >
      <a-select
        v-model:value="formState.levelId"
        style="width: 100%;"
        placeholder="请选择部门负责人来源"
        :options="MULTI_LEVEL_DEPT"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.USER_GROUP"
      label="指定用户组"
      name="groupIds"
    >
      <a-select
        v-model:value="formState.groupIds"
        mode="tags"
        style="width: 100%;"
        placeholder="请选择指定用户组"
        :options="groupOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.FORM_USER"
      label="表单内用户字段"
      name="yhzd"
    >
      <a-select
        v-model:value="formState.yhzd"
        :options="yhzdOptions"
      />
    </a-form-item>
    <a-form-item
      v-if="formState.candidateStrategy === CandidateStrategy.EXPRESSION"
      label="流程表达式"
      name="flowVar"
    >
      <a-textarea v-model:value="formState.flowVar" show-count :maxlength="300" />
      <a-button type="link" @click="drawerExpressionRef?.open()">
        选择表达式
      </a-button>
    </a-form-item>
    <a-form-item
      label="跳过表达式"
      name="skipExpression"
    >
      <a-textarea v-model:value="formState.skipExpression" show-count :maxlength="300" />
    </a-form-item>
    <DrawerExpression ref="drawerExpressionRef" @submit="getExcontent" />
  </a-form>
</template>
