<!--
文件: detail.vue
功能: 流程实例详情页，用于展示单个流程实例的审批详情、流程图和流转记录，并提供相关操作按钮。
主要逻辑:
- 在组件挂载时通过路由参数读取 `processInstanceId` 与 `taskId`，并调用 `postBpmProcessInstanceGetApprovalDetail` 加载审批详情，包括基础信息、活动节点、待办任务和流程定义信息。
- 通过 `getBpmProcessInstanceGetBpmnModelView` 获取 BPMN XML 字符串和视图样式，用于 `FlowModelViewer` 渲染流程图。
- 通过 `getBpmTaskListByProcessInstanceId` 加载流转记录表格数据，并在表格中使用 `millisecondsToDayHourMinuteSecond` 格式化耗时。
- 根据 `processDefinition.formType` 动态注册并渲染业务表单组件（`registerComponent`），支持自定义表单视图或默认表单字段展示。
- 使用 `TimeLineComponent` 渲染审批时间线，使用 `OperateButton` 提供对待办任务的操作入口（如审批、转办等），并将获取到的 `todoTask`、`processInstance`、`processDefinition` 数据传递给操作按钮组件。
- 页面只负责数据加载与展示，具体的后端接口在 `@/api/modules/...` 中实现，视图和操作组件通过组合式 API 进行交互。
-->

<script setup lang="ts">
import { getBpmTaskListByProcessInstanceId } from '@/api/modules/bpmTask/guanlihoutailiuchengrenwushili';
import { getBpmProcessInstanceGetBpmnModelView, postBpmProcessInstanceGetApprovalDetail } from '@/api/modules/bpmTask/guanlihoutailiuchengshili';
import { millisecondsToDayHourMinuteSecond } from '@/utils/fun';
import registerComponent from '@/utils/registerComponent';
import FlowModelViewer from '../flow-create/flow-model/createComponents/flow/view.vue';
import OperateButton from './components/operateButton.vue';
import TimeLineComponent from './components/timeLine.vue';
import { BPM_TASK_STATUS } from './enum';

defineOptions({
  name: 'ProcessDetail',
});
const route = useRoute();
const optType = ref<string>('');
const processInstanceId = ref<string>('');
const taskId = ref<string>('');
const operationButtonRef = ref<any>(null);
const activeTab = ref<string>('1');

/** 加载流程实例 */
const BusinessFormComponent = shallowRef<any>(null); // 异步组件

const baseInfo = ref<any>({});
const activityNodes = ref<any[]>([]);
const bpmnXmlString = ref<string>('');
const viewStyle = ref<object>({});
const todoTask = ref<any>(null);
const processDefinition = ref<any>({}); // 流程定义

const typeMap = {
  sj: '事假',
  bj: '病假',
};
const logTableData = ref<any[]>([]);
const logTableColumns = [{
  title: '审批节点',
  dataIndex: 'name',
}, {
  title: '审批人',
  dataIndex: 'assigneeUser',
}, {
  title: '开始时间',
  dataIndex: 'createTime',
}, {
  title: '结束时间',
  dataIndex: 'endTime',
}, {
  title: '审批状态',
  dataIndex: 'status',
}, {
  title: '审批建议',
  dataIndex: 'reason',
}, {
  title: '耗时',
  dataIndex: 'durationInMillis',
}];

const router = useRouter();

function fetchApprovalDetail() {
  postBpmProcessInstanceGetApprovalDetail({ processInstanceId: processInstanceId.value, taskId: taskId.value }).then((res) => {
    // console.log('Approval Detail for instanceId', res);
    baseInfo.value = res.data?.processInstance;
    activityNodes.value = res.data?.activityNodes || [];
    todoTask.value = res.data?.todoTask || null;
    // 获取待办任务显示操作按钮
    operationButtonRef.value?.loadTodoTask(todoTask.value);
    // 操作按钮获取流程实例信息
    operationButtonRef.value?.loadProcessInstance(res.data?.processInstance);
    // 操作按钮获取流程定义信息
    operationButtonRef.value?.loadProcessDefinition(res.data?.processDefinition);

    processDefinition.value = res.data?.processDefinition;
    if (processDefinition.value.formType === 20) {
      const formCustomViewPath = processDefinition.value.formCustomViewPath;
      BusinessFormComponent.value = registerComponent(formCustomViewPath!);
    }
  });
}

function getXMLInfo() {
  getBpmProcessInstanceGetBpmnModelView({ id: processInstanceId.value }).then((res) => {
    // console.log('BPM XML Info:', res);
    bpmnXmlString.value = res.data?.bpmnXml || '';
    viewStyle.value = res.data ?? {};
  });
}

function fetchLogTableData() {
  getBpmTaskListByProcessInstanceId({ processInstanceId: processInstanceId.value }).then((res) => {
    logTableData.value = res.data || [];
  });
}

onMounted(() => {
  processInstanceId.value = route.params.processInstanceId as string;
  taskId.value = route.query.taskId as string;
  optType.value = route.query.type as string;
  fetchApprovalDetail();
  getXMLInfo();
  fetchLogTableData();
});

function refreshDetail() {
  fetchApprovalDetail();
  getXMLInfo();
  fetchLogTableData();
}
</script>

<template>
  <div
    py-10px
    px-10px
    w-full
    h-full
  >
    <div size-full bg="#fff" p-10px flex flex-col>
      <div>
        <div>编号：{{ processInstanceId }}</div>
        <div text-16px font-bold>
          {{ baseInfo.name }}
        </div>
        <div flex items-center>
          <span>{{ baseInfo.startUser?.nickname }}</span>
          <span ml-16px>{{ baseInfo.startTime }}</span>
        </div>
      </div>
      <div flex-1 overflow-auto>
        <a-tabs v-model:active-key="activeTab" class="h-full">
          <a-tab-pane key="1" tab="审批详情">
            <div flex flex-row>
              <div v-if="processDefinition.formType === 20" class="w-40%">
                <BusinessFormComponent :detail="baseInfo.formVariables" />
              </div>
              <div v-else class="w-40%">
                <div>请假类型：{{ typeMap[baseInfo.formVariables?.type as 'bj'|'sj'] }}</div>
                <div>请假天数：{{ baseInfo.formVariables?.day }}</div>
                <div>请假原因：{{ baseInfo.formVariables?.reason }}</div>
              </div>
              <div flex-1>
                <TimeLineComponent :activity-nodes="activityNodes" />
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="2" tab="流程图">
            <FlowModelViewer :xml-string="bpmnXmlString" :view-style="viewStyle" />
          </a-tab-pane>
          <a-tab-pane key="3" tab="流转记录">
            <a-table
              :columns="logTableColumns"
              :data-source="logTableData"
              :pagination="false"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.dataIndex === 'assigneeUser'">
                  <span>
                    {{ record.assigneeUser?.nickname || record.ownerUser?.nickname }}
                  </span>
                </template>
                <template v-if="column.dataIndex === 'status'">
                  <span>
                    {{ BPM_TASK_STATUS.find(item => item.value === record.status)?.label || record.status }}
                  </span>
                </template>
                <template v-if="column.dataIndex === 'durationInMillis'">
                  {{ millisecondsToDayHourMinuteSecond(record.durationInMillis) }}
                </template>
              </template>
            </a-table>
          </a-tab-pane>
        </a-tabs>
      </div>
      <div h-60px flex items-center pl-20px border-0px border-t-1px border-solid class="border-#f0f0f0" :class="optType !== 'view' ? 'justify-between' : 'justify-end'">
        <div>
          <OperateButton v-if="optType !== 'view'" ref="operationButtonRef" @refresh="refreshDetail" />
        </div>
        <a-button @click="router.back()">
          返回
        </a-button>
      </div>
    </div>
  </div>
</template>

<style scoped>
:deep(.ant-tabs-content) {
  height: 100%;
}
</style>
