<template>
  <span @click="approval"
    ><slot></slot>
    <LoadingBox v-if="showLoading" />
    <ProcessLayout class="wrap" v-if="showVisible" @click.stop="">
      <template #title> {{ t('审批流程') }}【{{ data.item.name }}】 </template>
      <template #close>
        <a-button type="primary" class="clean-icon" @click.stop="close">{{ t('关闭') }}</a-button>
      </template>
      <template #left>
        <FlowPanel
          :xml="data.xml"
          :taskRecords="data.taskRecords"
          :predecessorTasks="selectedPredecessorTasks"
          :processId="props.processId"
          position="top"
        >
          <FormInformation
            :processId="processId"
            :opinionsComponents="data.opinionsComponents"
            :opinions="data.opinions"
            :disabled="false"
            :formInfos="data.formInfos"
            :formAssignmentData="data.formAssignmentData"
            ref="formInformation"
            @get-form-configs="
              (config) => {
                formConfigs = config;
                data.submitLoading = false;
              }
            "
          />
        </FlowPanel>
      </template>
      <template #right>
        <a-tabs
          class="process-right-Tab"
          :tabBarStyle="{ height: '50px', borderBottom: '1px solid #EEEEEE' }"
        >
          <a-tab-pane key="1" :tab="t('审批信息')">
            <NodeHead class="ml-10px" :nodeName="t('基础信息')" />

            <div class="description-box">
              <ProcessInfo class="item-box" :item="data.item">
                <NodeHead
                  class="ml-10px pt-4 mb-4"
                  :nodeName="t('审批信息')"
                  style="border-top: 1px solid #eee"
                />
                <div
                  class="text-box"
                  v-if="approvalData.buttonConfigs && approvalData.buttonConfigs.length > 0"
                >
                  <div class="text-label">{{ t('审批结果：') }}</div>
                  <div class="text-box-right">
                    <a-radio-group
                      class="approve-group"
                      v-model:value="approvedType"
                      name="approvedType"
                      @change="changeApprovedType"
                    >
                      <span v-for="(item, index) in approvalData.buttonConfigs" :key="index">
                        <a-radio
                          v-if="
                            item.approveType !== ApproveType.OTHER &&
                            item.approveType !== ApproveType.STAGING
                          "
                          :value="item.approveType"
                        >
                          {{ item.buttonName }}
                        </a-radio>
                      </span>
                    </a-radio-group>
                    <a-radio-group
                      class="approve-group"
                      v-model:value="approvedType"
                      name="buttonCode"
                    >
                      <span v-for="(item, index) in approvalData.buttonConfigs" :key="index">
                        <a-radio
                          v-if="item.approveType === ApproveType.OTHER"
                          :value="item.buttonCode"
                          @change="changeButtonCodeType"
                        >
                          {{ item.buttonName }}
                        </a-radio>
                      </span>
                    </a-radio-group>
                  </div>
                </div>
                <div class="text-box pb-4" v-if="approvalData.approvedType === ApproveType.REJECT">
                  <div class="text-label pt-7px">{{ t('驳回节点：') }}</div>
                  <div class="text-box-right !text-left">
                    <a-select
                      class="w-full flex-1"
                      v-model:value="approvalData.rejectNodeActivityId"
                    >
                      <a-select-option
                        v-for="(item, index) in approvalData.rejectNodeActivityIds"
                        :key="index"
                        :value="item.activityId"
                        >{{ item.activityName }}</a-select-option
                      >
                    </a-select>
                  </div>
                </div>
                <div class="text-box">
                  <div class="text-label">{{ t('审批内容：') }}</div>
                  <div class="text-box-right">
                    <a-textarea
                      class="flex-1"
                      v-model:value="approvalData.approvedContent"
                      :rows="6"
                      :maxlength="100"
                    />
                  </div>
                </div>
              </ProcessInfo>
            </div>
            <a-form
              class="approval-form"
              :model="approvalData.stampInfo"
              :label-col="{ span: 6 }"
              :wrapper-col="{ span: 18 }"
              @finish="onFinish"
              @finish-failed="onFinishFailed"
            >
              <!-- 电子签章 -->
              <a-form-item
                :label="t('电子签章')"
                name="stampId"
                :rules="[{ required: true, message: t('请选择电子签章') }]"
                v-if="data.hasStamp"
              >
                <SelectStamp
                  v-if="data.hasStamp"
                  v-model:stampId="approvalData.stampInfo.stampId"
                />
              </a-form-item>
              <a-form-item
                :label="t('签章密码')"
                name="password"
                :rules="[{ required: true, message: t('请输入签章密码') }]"
                v-if="data.hasStampPassword"
              >
                <a-input-password v-model:value="approvalData.stampInfo.password" />
              </a-form-item>

              <ApproveUser
                v-if="approveUserData.visible"
                :taskList="approveUserData.list"
                :schemaId="approveUserData.schemaId"
                @change="changeApproveUserData"
              />
              <div class="button-box">
                <a-button
                  type="primary"
                  html-type="submit"
                  class="!mx-10px !mt-0 !mb-10px"
                  :loading="data.submitLoading"
                  >{{ t('审批') }}</a-button
                >
                <!-- 转办 -->
                <TransferUser
                  :taskId="props.taskId"
                  :isSetTransferUser="approvalData.isSetTransferUser"
                  @close="close"
                />
                <a-button
                  type="primary"
                  class="!mx-10px !mt-0 !mb-10px"
                  :loading="data.submitLoading"
                  v-debounce:click="handleStaging"
                  v-if="stagingInfo?.checked"
                  >{{ stagingInfo.buttonName }}</a-button
                >
                <!-- 加签减签 -->
                <AddOrSubtract
                  v-if="approvalData.isAddOrSubSign"
                  :schemaId="props.schemaId"
                  :taskId="props.taskId"
                />
              </div>
            </a-form>
          </a-tab-pane>
          <a-tab-pane key="2" :tab="t('传阅信息')" force-render>
            <MemberTable
              v-model:memberList="approvalData.circulateConfigs"
              :isCommonType="true"
              :isApiApprover="true"
              btnstyle="block"
            />
          </a-tab-pane>
          <a-tab-pane key="3" :tab="t('打印表单')" force-render>
            <PrintProperty :formConfigs="formConfigs" :disabled="false" />
          </a-tab-pane>
        </a-tabs>
      </template>
    </ProcessLayout>
  </span>
</template>

<script setup lang="ts">
  import { computed, reactive, ref, defineAsyncComponent, onMounted, provide, Ref } from 'vue';
  import ProcessLayout from './flow/Layout.vue';
  import FormInformation from './flow/FormInformation.vue';
  import FlowPanel from './flow/FlowPanel.vue';
  import ProcessInfo from './flow/ProcessInfo.vue';

  import PrintProperty from './print/PrintProperty.vue';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import {
    getApprovalProcess,
    getApprovalProcessAssist,
    getRejectNode,
    postApproval,
    stagingProcess,
  } from '/@/api/workflow/task';
  import userTaskItem from './../hooks/userTaskItem';
  import { ApproveTask, PostApprovalData, rejectNodeItem } from '/@/model/workflow/bpmnConfig';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import { ButtonConfigItem } from '/@/model/workflow/workflowConfig';
  import { MemberConfig } from '/@/model/workflow/memberSetting';
  import { ApproveCode, ApproveType } from '/@/enums/workflowEnum';
  import { separator } from '../../design/bpmn/config/info';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { notification } from 'ant-design-vue';
  import { useExclusiveApprovalProcess } from '/@/hooks/web/useExclusiveApprovalProcess';

  const ApproveUser = defineAsyncComponent(() => import('./flow/ApproveUser.vue'));
  const AddOrSubtract = defineAsyncComponent(() => import('./flow/AddOrSubtract.vue'));
  const TransferUser = defineAsyncComponent(() => import('./flow/TransferUser.vue'));
  const MemberTable = defineAsyncComponent(
    () => import('../../design/bpmn/components/member/MemberTable.vue'),
  );
  const SelectStamp = defineAsyncComponent(() => import('./stamp/SelectStamp.vue'));
  const { handleOpenExclusiveApprovalProcess, handleCLoseExclusiveApprovalProcess } =
    useExclusiveApprovalProcess();
  const { t } = useI18n();
  const props = withDefaults(
    defineProps<{
      schemaId: string;
      processId: string;
      taskId: string;
      visible?: boolean;
    }>(),
    {
      schemaId: '',
      processId: '',
      taskId: '',
      visible: false,
    },
  );
  let emits = defineEmits(['close']);

  let formInformation = ref();
  let showVisible = ref(false);
  let showLoading = ref(false);
  let approvedType = ref(ApproveType.AGREE);
  let approvalData: {
    isCountersign: Boolean; //是否会签节点
    isAddOrSubSign: Boolean; //是否加签减签
    stampInfo: {
      stampId: string;
      password: string;
    };
    buttonConfigs: Array<ButtonConfigItem>;
    approvedType: ApproveType;
    approvedContent: string;
    approvedResult: string;
    rejectNodeActivityId: string;
    rejectNodeActivityIds: Array<rejectNodeItem>;
    circulateConfigs: Array<MemberConfig>;
    isSetTransferUser: boolean;
  } = reactive({
    isCountersign: false,
    isAddOrSubSign: false,
    stampInfo: {
      stampId: '',
      password: '',
    },
    buttonConfigs: [],
    approvedType: ApproveType.AGREE,
    approvedResult: ApproveCode.AGREE,
    approvedContent: '',
    rejectNodeActivityId: '',
    rejectNodeActivityIds: [],
    circulateConfigs: [],
    isSetTransferUser: false,
  });

  const formConfigs = ref();
  const tabActiveKey = ref<number>(0);

  provide<Ref<number>>('tabActiveKey', tabActiveKey);
  const { data, approveUserData, initProcessData, notificationError, notificationSuccess } =
    userTaskItem();
  const validateSuccess = ref(false);
  onMounted(() => {
    if (props.visible) {
      approval();
    }
  });
  const selectedPredecessorTasks = computed(() => {
    return data.predecessorTasks.filter((ele) => {
      return ele.taskId;
    });
  });

  const stagingInfo = computed(() => {
    return approvalData.buttonConfigs.find((item) => {
      return item.buttonCode === ApproveCode.STAGING;
    });
  });

  // 审批
  async function approval() {
    showLoading.value = true;
    reset();
    if (props.taskId) {
      try {
        await handleOpenExclusiveApprovalProcess(props.taskId);
        let res = await getApprovalProcess(props.taskId, props.processId);
        await getApprovalProcessAssist(props.taskId);
        initProcessData(res, res.isStaging);
        if (res.buttonConfigs) {
          approvalData.buttonConfigs = res.buttonConfigs;
        }
        if (res.relationTasks) {
          data.predecessorTasks = res.relationTasks;
        }
        if (res.isAddOrSubSign) {
          approvalData.isAddOrSubSign = res.isAddOrSubSign;
        }
        approvalData.isSetTransferUser = res.isSetTransferUser || false;
        approvalData.approvedType = ApproveType.AGREE;
        approvedType.value = ApproveType.AGREE;
        approvalData.approvedContent = '';
        approvalData.rejectNodeActivityId = '';
        approvalData.rejectNodeActivityIds = [];
        approvalData.circulateConfigs = [];
        showLoading.value = false;
        showVisible.value = true;

        if (res.isStaging && res.approveDto) {
          //如果是暂存
          const approveDto = res.approveDto;
          approvalData.approvedResult = approveDto.approvedResult;
          approvalData.approvedContent = approveDto.approvedContent;
          approvedType.value = approveDto.approvedType;
          approvalData.approvedType = approveDto.approvedType;
          approvalData.stampInfo.password = approveDto.stampPassword;
          approvalData.stampInfo.stampId = approveDto.stampId;
          approvalData.circulateConfigs = approveDto.circulateConfigs;
          if (approvedType.value == ApproveType.REJECT) {
            approvalData.rejectNodeActivityIds = await getRejectNode(props.processId, props.taskId);
            approvalData.rejectNodeActivityId = approveDto.rejectNodeActivityId;
          }
        }
      } catch (error) {
        showLoading.value = false;
        emits('close');
      }
    } else {
      // 只能选一个
      showLoading.value = false;
      showVisible.value = false;
      notification.open({
        type: 'error',
        message: t('审批'),
        description: t('请选择一个流程进行审批'),
      });
      emits('close');
    }
  }

  async function changeApprovedType() {
    approvalData.approvedType = approvedType.value;
    if (approvedType.value == ApproveType.AGREE) {
      approvalData.approvedResult = ApproveCode.AGREE;
    } else if (approvedType.value == ApproveType.REJECT) {
      approvalData.rejectNodeActivityIds = await getRejectNode(props.processId, props.taskId);
      approvalData.approvedResult = ApproveCode.REJECT;
    } else if (approvedType.value == ApproveType.DISAGREE) {
      approvalData.approvedResult = ApproveCode.DISAGREE;
    } else if (approvedType.value == ApproveType.FINISH) {
      approvalData.approvedResult = ApproveCode.FINISH;
    } else {
      approvalData.approvedResult = '';
    }
  }
  function changeButtonCodeType(v) {
    approvalData.approvedType = ApproveType.OTHER;
    approvalData.approvedResult = v.target.value;
  }
  function getUploadFileFolderIds(formModels) {
    let fileFolderIds: Array<string> = [];
    let uploadComponentIds = formInformation.value.getUploadComponentIds();
    uploadComponentIds.forEach((ids) => {
      if (ids.includes(separator)) {
        let arr = ids.split(separator);
        if (arr.length == 2 && formModels[arr[0]][arr[1]]) {
          fileFolderIds.push(formModels[arr[0]][arr[1]]);
        } else if (
          arr.length == 3 &&
          formModels[arr[0]][arr[1]] &&
          Array.isArray(formModels[arr[0]][arr[1]])
        ) {
          formModels[arr[0]][arr[1]].forEach((o) => {
            fileFolderIds.push(o[arr[2]]);
          });
        }
      }
    });
    return fileFolderIds;
  }
  const onFinish = async (values: any) => {
    if (approvalData.approvedType == ApproveType.REJECT) {
      validateSuccess.value = true;
      if (approvalData.rejectNodeActivityId == '') {
        notification.open({
          type: 'error',
          message: t('审批'),
          description: t('请选择一个驳回节点'),
        });
        return false;
      }
    } else {
      await submit();
    }
    formInformation.value.sendMessageForAllIframe(); // iframe 发送消息到对应网址
    try {
      if (validateSuccess.value) {
        let formModels = await formInformation.value.getFormModels();
        let system = formInformation.value.getSystemType();
        let fileFolderIds: Array<string> = getUploadFileFolderIds(formModels);
        let params: PostApprovalData = {
          approvedType: approvalData.approvedType,
          approvedResult: approvalData.approvedResult, // approvalData.approvedType 审批结果 如果为 4 就需要传buttonCode
          approvedContent: approvalData.approvedContent,
          formData: formModels,
          rejectNodeActivityId: approvalData.rejectNodeActivityId,
          taskId: props.taskId,
          fileFolderIds,
          circulateConfigs: approvalData.circulateConfigs,
          stampId: values.stampId,
          stampPassword: values.password,
          isOldSystem: system,
        };

        let res = await postApproval(params);
        await handleCLoseExclusiveApprovalProcess();
        // 下一节点审批人
        let taskList: Array<ApproveTask> = [];
        if (res && res.length > 0) {
          taskList = res
            .filter((ele) => {
              return ele.isMultiInstance == false && ele.isAppoint == true;
            })
            .map((ele) => {
              return {
                taskId: ele.taskId,
                taskName: ele.taskName,
                provisionalApprover: ele.provisionalApprover,
                selectIds: [],
              };
            });
          if (taskList.length > 0) {
            approveUserData.list = taskList;
            approveUserData.schemaId = props.schemaId;
            approveUserData.visible = true;
            data.submitLoading = false;
          } else {
            close();
            data.submitLoading = false;
            save(true, t('审批流程'));
          }
        } else {
          close();
          data.submitLoading = false;
          save(true, t('审批流程'));
        }
      }
    } catch (error) {}
  };

  const onFinishFailed = () => {
    submit();
  };
  async function submit(info = t('审批流程')) {
    data.submitLoading = true;
    validateSuccess.value = false;
    try {
      let validateForms = await formInformation.value.validateForm();
      if (validateForms.length > 0) {
        let successValidate = validateForms.filter((ele) => {
          return ele.validate;
        });
        if (successValidate.length == validateForms.length) {
          validateSuccess.value = true;
          data.submitLoading = false;
        } else {
          data.submitLoading = false;
          notificationError(info, t('表单校验未通过'));
        }
      }
    } catch (error) {
      data.submitLoading = false;
      notificationError(info, t(`${info}失败`));
    }
  }

  function changeApproveUserData() {
    approveUserData.visible = false;
    close();
  }
  function save(res: boolean, title: string) {
    if (res) {
      notificationSuccess(title);
      close();
    } else {
      notificationError(title);
    }
  }
  async function close() {
    approvalData.approvedResult = ApproveCode.AGREE; //还原
    showVisible.value = false;
    await handleCLoseExclusiveApprovalProcess();
    emits('close');
  }
  function reset() {
    approvalData.isAddOrSubSign = false;
    approvalData.stampInfo = {
      stampId: '',
      password: '',
    };
    approvalData.buttonConfigs = [];
    approvalData.approvedType = ApproveType.AGREE;
    approvalData.approvedContent = '';
    approvalData.rejectNodeActivityId = '';
    approvalData.rejectNodeActivityIds = [];
    approvalData.circulateConfigs = [];
  }

  async function handleStaging() {
    await submit('暂存流程');
    try {
      if (validateSuccess.value) {
        let formModels = await formInformation.value.getFormModels();
        let system = formInformation.value.getSystemType();
        let fileFolderIds: Array<string> = getUploadFileFolderIds(formModels);
        let params: PostApprovalData = {
          approvedType: approvalData.approvedType,
          approvedResult: approvalData.approvedResult, // approvalData.approvedType 审批结果 如果为 4 就需要传buttonCode
          approvedContent: approvalData.approvedContent,
          formData: formModels,
          rejectNodeActivityId: approvalData.rejectNodeActivityId,
          taskId: props.taskId,
          fileFolderIds,
          circulateConfigs: approvalData.circulateConfigs,
          stampId: approvalData.stampInfo.stampId,
          stampPassword: approvalData.stampInfo.password,
          isOldSystem: system,
        };

        await stagingProcess(params);
        close();
        data.submitLoading = false;
        save(true, '暂存流程');
      }
    } catch (error) {
      save(false, '暂存流程');
    }
  }
</script>
<style lang="less" scoped>
  .description-box {
    display: flex;
    flex-direction: column;
    padding-top: 10px;
    align-items: center;
    justify-content: center;
    color: rgb(102 102 102 / 99.6%);
    margin-bottom: 16px;

    .title {
      align-self: flex-start;
      margin-bottom: 20px;
    }

    .item-box {
      align-self: flex-start;
      width: 100%;
    }

    .text-box {
      display: flex;

      .text-label {
        width: 80px;
        height: 30px;
        display: inline-flex;
        padding-left: 10px;
        line-height: 14px;
        padding-bottom: 16px;
      }

      .text-box-right {
        line-height: 14px;
        width: calc(100% - 80px);
        text-align: right;
        display: inline-block;
        padding-right: 10px;

        :deep(.ant-radio) {
          top: 0;
        }
      }
    }
  }
  // 传阅人
  :deep(.opr-box) {
    flex-direction: column !important;

    .header-box {
      flex-basis: 40px !important;
    }

    .button-box {
      flex-direction: row !important;
    }
  }

  .approve-group {
    .ant-radio-wrapper {
      margin-right: 0;
      margin-left: 12px;
      align-items: center;
      line-height: 14px;
    }
  }

  :deep(span.ant-radio + *) {
    padding-right: 0;
    padding-left: 4px;
  }

  :deep(.ant-form) {
    &.approval-form {
      border-top: 1px solid #eee;
      padding-top: 16px;

      .ant-form-item-label label {
        width: 90px;
        margin-left: -9px;
        margin-right: 14px;
      }

      .ant-form-item-control-input {
        margin-left: 2px;
      }
    }
  }
</style>
