<template>
  <PageWrapper :class="prefixCls">
    <div class="btn-box">
      <a-button type="primary" @click="confimReading" class="ml-2" v-if="props.isRead == 1"
        >确认阅读
      </a-button>
      <a-button type="primary" @click="closePage" class="ml-2" danger>关闭 </a-button>
    </div>
    <a-layout>
      <a-layout>
        <a-layout-content>
          <a-tabs v-model:activeKey="activeName" @change="changeActive">
            <a-tab-pane key="form" tab="表单信息" v-if="formVisble">
              <FormViewer
                ref="formBoxRef"
                :formConfig="formConfig"
                :processId="designerData.process.id"
                :formVerison="designerData.formCurrentNode.formVerison"
                :formRelationId="designerData.formCurrentNode.formRelationId"
                :instanceInfo="designerData.process.instanceInfo"
                v-if="formVisble"
              />
            </a-tab-pane>
            <a-tab-pane key="flow" tab="流程信息" force-render>
              <div class="process-design" :style="'display: flex; height:' + designerData.height">
                <process-viewer
                  v-if="processVisble"
                  :key="`designer-${id}`"
                  :events="['element.click']"
                  @element-click="elementClick"
                  :xml="flowContent"
                  :flowViewer="flowViewer"
                />
              </div>
            </a-tab-pane>
            <a-tab-pane key="record" tab="流转记录" force-render>
              <a-timeline>
                <a-timeline-item
                  v-for="(item, index) in designerData.logs"
                  :key="index"
                  :color="item.type"
                >
                  <div class="title">{{ item.time }}</div>
                  <a-card hoverable size="small">
                    <div class="type-title">{{ item.name }}</div>
                    <div class="content">
                      <span
                        class="link"
                        v-for="(userName, index2) in item.userNames"
                        :key="index2"
                        >{{ userName }}</span
                      >
                      {{ item.des }}
                    </div>
                  </a-card>
                </a-timeline-item>
              </a-timeline>
            </a-tab-pane>
          </a-tabs>
        </a-layout-content>
        <!-- <a-divider type="vertical" /> -->
        <a-layout-sider v-if="props.isRead == 0">
          <a-tabs v-model:activeKey="auditName">
            <a-tab-pane key="audit" tab="审批栏">
              <div class="approval-column">
                <a-form
                  ref="formRef"
                  :rules="rules"
                  :model="formData"
                  labelAlign="left"
                  :label-col="labelCol"
                  :wrapper-col="wrapperCol"
                >
                  <a-form-item
                    :label="designerData.isCreateAgain ? '备注' : '审批意见'"
                    name="des"
                  />
                  <a-form-item label="">
                    <a-textarea
                      v-model:value="formData.des"
                      placeholder="请输入"
                      :auto-size="{ minRows: 5, maxRows: 8 }"
                    />
                  </a-form-item>
                  <a-form-item label="" class="l-task-btns">
                    <a-button
                      v-for="(btn, index) in designerData.taskBtns"
                      :key="index"
                      :color="btn.type"
                      :type="btn.type ? btn.type : 'primary'"
                      @click="handleBtnClick(btn)"
                      >{{ btn.name }}</a-button
                    >
                  </a-form-item>
                </a-form>
                <auditInfo :data="designerData.userLogs" />
              </div>
            </a-tab-pane>
          </a-tabs>
        </a-layout-sider>
      </a-layout>
    </a-layout>

    <!-- 节点记录信息 -->
    <div class="info-box" v-if="designerData.nodeLogs.length > 0">
      <a-drawer v-model:open="infoOpen" class="custom-class" title="记录信息" placement="right">
        <a-timeline>
          <a-timeline-item
            v-for="(item, index) in designerData.nodeLogs"
            :key="index"
            :color="item.type"
          >
            <div class="title">{{ item.time }}</div>
            <a-card hoverable size="small">
              <div class="type-title">{{ item.name }}</div>
              <div class="content">
                <span class="link" v-for="(userName, index2) in item.userNames" :key="index2">{{
                  userName
                }}</span>
                {{ item.des }}
              </div>
            </a-card>
          </a-timeline-item>
        </a-timeline>
      </a-drawer>
    </div>
  </PageWrapper>
</template>

<script lang="ts" setup>
  import { ref, reactive, onBeforeMount } from 'vue';
  import { ProcessViewer } from '@/components/ProcessViewer';
  import { PageWrapper } from '@/components/Page';
  import { createAgain, signAudit, audit, ReadFlow } from '@/api/sys/WFProcess';
  import { getBPMNTask } from '@/api/sys/WFTask';
  import { dateFormat } from '@/utils/base';
  import { flowStore } from '@/store/modules/flow';
  import { functionsaveForm, LoadFormScheme } from '@/api/demo/formScheme';
  import { FormViewer } from '@/components/FormViewer';
  import {
    designerDataType,
    logsType,
    taskBtnsType,
    currentNodeObject,
    nodeUsersType,
  } from './processModel';
  import { auditInfo } from './page';
  import { IFormConfig } from '@/views/demo/form-design/typings/v-form-component';
  import { useMessage } from '@/hooks/web/useMessage';

  const { createMessage } = useMessage();
  const formBoxRef = ref<any>();
  const emit = defineEmits(['closeModel']);
  const keyValue = ref('');

  const flowWfDataStore = flowStore();
  const prefixCls = 'preview-box';
  const flowContent = ref('');
  const flowViewer = ref({});
  const formRef = ref();
  const labelCol = { span: 7 };
  const wrapperCol = { span: 24 };
  const infoOpen = ref(true);
  const formVisble = ref(false);
  const processVisble = ref(false);
  const props = defineProps({
    processId: String,
    taskId: String,
    type: String,
    isRead: String,
  });
  const formData = ref({
    des: '',
  });
  const rules: any = ref({
    des: [{ required: true, message: '请填写审批意见', trigger: 'blur' }],
  });
  if (props.type == 4) {
    rules.value = {};
  }
  // 表单数据
  const formConfig = ref<IFormConfig>({
    // 表单配置
    schemas: [],
    layout: 'horizontal',
    labelLayout: 'flex',
    labelWidth: 100,
    labelCol: {},
    wrapperCol: {},
    currentItem: {
      component: '',
      componentProps: {},
    },
    activeKey: 1,
  });
  const designerData: designerDataType = reactive({
    loading: false,
    xmlString: '',
    height: document.documentElement.clientHeight - 200.5 + 'px;',
    midVisible: false,
    isCustmerTitle: false,
    nodeUsers: [],
    selectUsersVisible: false,
    selectTUserVisible: false,
    tUserType: 1, // 1 转移 2 加签,
    isDraft: false,
    delegateUsers: [],
    task: {},
    process: {},
    logs: [], // 流程日志信息
    nodeMap: {}, // 需要处理的任务
    userLogs: [], // 人员日志信息
    nodeLogs: [],
    taskBtns: [],
    currentNode: {},
    stampList: [],
    currentBtn: {
      code: '',
      name: '',
      isNextAuditor: false,
    },
    wfData: [],
    isCreateAgain: props.type == 4 ? true : false,
    selectRejectNodeVisible: false,
    selectSignVisible: false,
    formCurrentNode: {},
  });
  const activeName = ref('form');
  const auditName = ref('audit');
  function changeActive(activeKey) {
    if (activeKey == 'flow') {
      processVisble.value = true;
    }
  }
  function elementClick(element: { id: string | number }) {
    if (element) {
      designerData.nodeLogs = designerData.nodeMap[element.id] || [];
      infoOpen.value = true;
    } else {
      designerData.nodeLogs = [];
    }
  }

  async function getTaskInfo() {
    let query: any = {
      id: props.taskId,
    };
    let data = await getBPMNTask(query);
    flowContent.value = data.flowContent;
    flowViewer.value = data.flowViewer;
    designerData.process = data.process;
    designerData.task = data.task;
    let content = JSON.parse(data.scheme.content);
    let wfData = content.wfData;
    const currentNode = wfData.find((t) => t.type == 'bpmn:StartEvent');
    console.log(currentNode);
    if (currentNode.authFields.length > 0) {
      formVisble.value = true;
    } else {
      activeName.value = 'flow';
      processVisble.value = true;
    }
    designerData.formCurrentNode = currentNode;
    formConfig.value = currentNode.authFields;
    getFormHistory();
    if (props.isRead == 0) {
      setLogsAndTasks(data.logs, data.tasks);
      getBtns();
    }
  }
  function setLogsAndTasks(logs: any[], tasks: any[]) {
    const res: logsType[] = [];
    const taskMap = {};
    const nodeMap = {};
    const userLogs: any[] = [];

    tasks.forEach(
      (task: {
        unitId: string | number;
        unitName: any;
        createDate: any;
        type: number;
        userId: any;
        userName: any;
      }) => {
        nodeMap[task.unitId] = nodeMap[task.unitId] || [
          {
            unitId: task.unitId,
            name: task.unitName,
            userIds: [],
            userNames: [],
            des: '正在审核',
            time: `当前-创建时间:${dateFormat(task.createDate)}`,
            type: 'blue',
            isFinish: false,
          },
        ];

        if (task.type == 2) {
          taskMap[task.unitId + task.type] = taskMap[task.unitId + task.type] || {
            unitId: task.unitId,
            name: task.unitName,
            userIds: [],
            userNames: [],
            des: '正在查阅',
            time: `当前-创建时间:${dateFormat(task.createDate)}`,
            type: 'blue',
          };
          taskMap[task.unitId + task.type].userIds.push(task.userId);
          taskMap[task.unitId + task.type].userNames.push(task.userName);

          if (nodeMap[task.unitId].length == 1) {
            nodeMap[task.unitId].push({
              unitId: task.unitId,
              name: task.unitName,
              userIds: [],
              userNames: [],
              des: '正在查阅',
              time: `当前-创建时间:${dateFormat(task.createDate)}`,
              type: 'blue',
              isFinish: true,
            });
          }
          nodeMap[task.unitId][1].userIds.push(task.userId);
          nodeMap[task.unitId][1].userNames.push(task.userName);
        } else {
          taskMap[task.unitId] = taskMap[task.unitId] || {
            unitId: task.unitId,
            name: task.unitName,
            userIds: [],
            userNames: [],
            des: '正在审核',
            time: `当前-创建时间:${dateFormat(task.createDate)}`,
            type: 'blue',
          };
          taskMap[task.unitId].userIds.push(task.userId);
          nodeMap[task.unitId][0].userIds.push(task.userId);
          taskMap[task.unitId].userNames.push(task.userName);
          nodeMap[task.unitId][0].userNames.push(task.userName);
        }
      },
    );

    for (let key in taskMap) {
      res.push(taskMap[key]);
    }

    for (let key in nodeMap) {
      nodeMap[key] = nodeMap[key].filter((t: { userIds: string | any[] }) => t.userIds.length > 0);
    }

    logs.forEach(
      (log: {
        unitId: string;
        unitName: any;
        userId: string;
        userName: string;
        des: string;
        operationName: string;
        createDate: any;
        taskType: number;
        operationCode: string;
        stampImg: any;
      }) => {
        res.push({
          unitId: log.unitId,
          name: log.unitName,
          userIds: [log.userId],
          userNames: [log.userName],
          des: log.des ? log.des : log.operationName,
          time: dateFormat(log.createDate),
          type: 'gray',
        });

        nodeMap[log.unitId] = nodeMap[log.unitId] || [];
        nodeMap[log.unitId].push({
          unitId: log.unitId,
          name: log.unitName,
          userIds: [log.userId],
          userNames: [log.userName],
          time: dateFormat(log.createDate),
          des: log.des ? log.des : log.operationName,
          type: 'gray',
          isFinish: true,
        });

        if (log.taskType == 1 && !['sign'].includes(log.operationCode)) {
          // 右侧显示审核记录
          // const userLogIndex = userLogs.findIndex((t) => t.id == log.unitId);
          // if (userLogIndex == -1) {
          userLogs.push({
            id: log.unitId,
            name: log.unitName,
            user: log.userName,
            time: dateFormat(log.createDate),
            des: log.des,
            img: log.stampImg,
          });
          // }
        }
      },
    );

    designerData.logs = res;
    designerData.nodeMap = nodeMap;
    designerData.userLogs = userLogs.sort(function (a, b) {
      return b.time < a.time ? -1 : 1;
    });
  }
  async function validateForm() {
    let res = await formRef.value
      .validate()
      .then(() => {
        return true;
      })
      .catch(() => {
        return false;
      });
    return res;
  }
  function getBtns() {
    const wfData = flowWfDataStore.getWfData;
    designerData.wfData = wfData;
    const currentNode: currentNodeObject =
      wfData.find((t) => t.id == designerData.task.unitId) || {};
    designerData.currentNode = currentNode;
    // 设置审核按钮
    const btns: taskBtnsType[] = [];
    if (currentNode.type == 'bpmn:StartEvent') {
      btns.push({
        code: 'learun_create',
        name: '提交',
        type: '',
      });
    } else {
      currentNode.btnlist.forEach((btn: taskBtnsType) => {
        if (btn.code == 'agree') {
          btn.type = '';
        } else if (btn.code == 'disagree') {
          btn.type = 'error';
        }
        btns.push(btn);
      });

      if (currentNode.isAddSign) {
        btns.push({
          code: 'learun_sign',
          name: '加签',
          type: 'success',
        });
      }

      if (currentNode.isTransfer) {
        btns.push({
          code: 'learun_transfer',
          name: '转移',
          type: 'success',
        });
      }
    }
    designerData.taskBtns = btns;
  }
  async function handleBtnClick(btn) {
    // 验证审批栏必填项
    const data = await validateForm();
    if (!data) {
      return;
    }
    // 有表单先提交表单数据
    if (formVisble.value) {
      var querys = {
        schemeId: designerData.formCurrentNode.formVerison,
        isUpdate: true,
        pkey: keyValue.value,
        pkeyValue: props.processId,
      };
      formBoxRef.value
        .getForm()
        .then(async (res) => {
          res[designerData.formCurrentNode.formRelationId] = props.processId;
          for (var item in res) {
            if (res[item] == null) {
              res[item] = '';
            }
          }
          querys.data = JSON.stringify(res);
          const formValue = await functionsaveForm(querys);
          if (formValue) {
            handleSubmit(btn);
          }
        })
        .catch((error) => {
          console.log(error);
          activeName.value = 'form';
          return;
        });
    } else {
      handleSubmit(btn);
    }
  }
  async function handleSubmit(btn) {
    const currentBtn = btn;
    designerData.currentBtn = currentBtn;
    let res: any;
    switch (btn.code) {
      case 'learun_create':
        res = await createAgain({
          processId: props.processId,
          des: `重新提交${formData.value.des ? '-' : ''}${formData.value.des}`,
        });
        break;
      case 'learun_sign':
        designerData.tUserType = 2;
        designerData.selectTUserVisible = true;
        break;
      case 'learun_transfer':
        designerData.tUserType = 1;
        designerData.selectTUserVisible = true;
        break;
      default:
        if (designerData.task.type == 6) {
          // 加签审核
          res = await signAudit(props.taskId, {
            code: btn.code,
            name: btn.name,
            des: formData.value.des,
          });
        } else {
          if (designerData.currentNode.rejectType == '2' && btn.code == 'disagree') {
            designerData.selectRejectNodeVisible = true;
            return;
          }

          if (btn.isSign) {
            // 加载签章数据
            // const stampList = await this.$awaitWraper(apiStamp.getList(this.loginInfo.f_UserId));
            // if (stampList && stampList.length > 0) {
            //   designerData.stampList = stampList;
            //   designerData.selectSignVisible = true;
            //   return;
            // }
          }
          res = await auditFun();
        }
        break;
    }
    if (res) {
      closePage();
      return createMessage.success('成功');
    } else {
      return createMessage.error('失败');
    }
  }
  async function auditFun() {
    // 获取接下来节点审核人
    if (designerData.currentBtn.isNextAuditor) {
      const res = await getLoadNextAuditors({
        processId: props.processId,
        nodeId: designerData.currentNode.id,
      });
      const nodeUserMap = res.data.data;
      const nodeUsers: nodeUsersType[] = [];
      for (let key in nodeUserMap) {
        const nodeUserItem = nodeUserMap[key];
        if (nodeUserItem.length > 1) {
          nodeUsers.push({
            name: designerData.wfData.find((t) => t.id == key).name,
            id: key,
            options: nodeUserItem.map((t: { id: any; name: any }) => {
              return { value: t.id, label: t.name };
            }),
          });
        }
      }

      designerData.nodeUsers = nodeUsers;

      if (designerData.nodeUsers.length > 0) {
        designerData.selectUsersVisible = true;
        return;
      }
    }
    const data = await audit(props.taskId, {
      code: designerData.currentBtn.code,
      name: designerData.currentBtn.name,
      des: formData.value.des,
    });
    if (data) {
      closePage();
      return createMessage.success('成功');
    } else {
      return createMessage.error('失败');
    }
  }
  function closePage() {
    emit('closeModel');
    // tabStore.closeTabByKey(
    //   '/dashboard/task_audit_preview/detail?processId=' +
    //     processId +
    //     '&taskId=' +
    //     taskId +
    //     '&type=' +
    //     type +
    //     '&isRead=' +
    //     isRead,
    //   router,
    // );
  }
  async function confimReading() {
    const data = await ReadFlow(props.taskId);
    if (data) {
      closePage();
      return createMessage.success('成功');
    } else {
      return createMessage.error('失败');
    }
  }
  async function getFormHistory() {
    const data = await LoadFormScheme({
      schemeId: designerData.formCurrentNode.formVerison,
    });
    if (data) {
      const scheme = JSON.parse(data.scheme);
      scheme.formInfo.schemas.forEach((element) => {
        if (element.field == designerData.formCurrentNode.formRelationId) {
          keyValue.value = element.componentProps.fieldName;
        }
      });
    }
  }
  onBeforeMount(() => {
    getTaskInfo();
  });
</script>
<style lang="less" scoped>
  ::v-deep .ant-tabs-nav-wrap {
    padding-left: 10px;
  }
  ::v-deep .ant-layout {
    height: 100%;
    background-color: @component-background;
  }
  ::v-deep .ant-layout-sider-children {
    border-left: 1px solid rgba(5, 5, 5, 0.06);
  }
  ::v-deep .ant-divider-vertical {
    height: 100%;
  }
  .info-box {
    display: inline-block;
    width: 300px;
    position: absolute;
    right: 0;
    margin-top: 40px;
  }

  .ant-timeline-item-content {
    .title {
      color: #909399;
      line-height: 1;
      margin-bottom: 8px;
      font-size: 13px;
    }

    .type-title {
      font-size: 12px;
      font-weight: bold;
      margin-bottom: 8px;
    }

    .link {
      color: #409eff;
    }
  }

  .preview-box {
    height: 100%;

    .btn-box {
      padding: 10px;
      justify-content: flex-end;
      display: flex;
    }
  }
  ::v-deep .vben-page-wrapper-content {
    height: 100%;
    // margin: 0 0 0 16px;
  }
  .form-box {
    width: 480px;
  }

  .approval-column {
    padding: 10px;
  }
  ::v-deep .ant-layout .ant-layout-sider {
    padding-left: 10px;
    background-color: @component-background;
    flex: 0 0 360px !important;
    max-width: 360px !important;
    min-width: 360px !important;
    width: 360px !important;
  }
  ::v-deep .vben-page-wrapper .vben-page-wrapper-content {
    height: 98%;
  }
  .l-task-btns {
    .ant-btn {
      margin: 0;
      margin-top: 8px;
      margin-right: 8px;
    }
  }
</style>
