<template>
  <div class="run-detail-page">
    <div class="run-title-box" v-show="!leftFullScreen && !rightFullScreen">
      <div class="task-info">
        <div class="task-name">{{ currentRunNodeInfo?.runName }}</div>
        <div class="task-status">
          任务状态：
          <div class="status">
            <el-icon class="upload" title="进行中" v-if="runFlowPocesInfo?.status === 'running'">
              <HelpFilled />
            </el-icon>
            <el-icon
              class="success"
              title="已完成"
              v-else-if="runFlowPocesInfo?.status === 'completed'"
            >
              <SuccessFilled />
            </el-icon>
            <el-icon
              class="upload"
              title="挂起中"
              v-else-if="runFlowPocesInfo?.status === 'suspended'"
            >
              <UploadFilled />
            </el-icon>
            <el-icon
              class="upload"
              title="等待操作"
              v-else-if="runFlowPocesInfo?.status === 'waiting_for_user'"
            >
              <UploadFilled />
            </el-icon>
            <el-icon class="warn" title="异常" v-else-if="runFlowPocesInfo?.status === 'error'">
              <WarningFilled />
            </el-icon>
            <el-icon class="info" title="未开始" v-else>
              <InfoFilled />
            </el-icon>
            <span class="status-title">{{
              runFlowPocesInfo?.status ? statusList[runFlowPocesInfo?.status] : '未开始'
            }}</span>
          </div>
        </div>
        <div class="task-time">
          作业流执行时间：
          <el-icon class="blue">
            <Odometer />
          </el-icon>
          <span class="name"> {{ runFlowPocesInfo?.durationFormatted || '--' }}</span>
        </div>
      </div>
      <div class="task-operate">
        <!-- runInfo.status === RUN_STATUS.UNSTART -->
        <el-button
          type="primary"
          v-if="!runInfo.status"
          :disabled="uploadFileFlag"
          @click="startTaskRunJobFun"
          >开始</el-button
        >
        <el-button type="primary" @click="visible = true">HPC列表</el-button>

        <el-button @click="refreshFun">刷新</el-button>
      </div>
    </div>

    <div class="run-flow-box" v-show="!leftFullScreen && !rightFullScreen">
      <div class="flow-box-inner" v-if="runInfo.flowTemplate && showPage">
        <runFlowPage
          :run-info="runInfo"
          @change="changeCurrentFlowNodeFun"
          @update="updateFlowPageParamListFun"
          @execute="executeFun"
        >
        </runFlowPage>
      </div>
    </div>

    <div :class="leftFullScreen || rightFullScreen ? 'run-info-box is-all-page' : 'run-info-box'">
      <div
        v-if="!rightFullScreen"
        :class="leftFullScreen ? 'info-box-left allpage ' : 'info-box-left'"
      >
        <div class="bottom-title">
          <div class="title-name">节点详情</div>
          <div class="title-operate">
            <el-icon
              v-if="!leftFullScreen"
              @click="leftFullScreen = !leftFullScreen"
              class="icon-style"
              ><FullScreen
            /></el-icon>
            <el-icon v-else @click="leftFullScreen = !leftFullScreen" class="icon-style"
              ><Close
            /></el-icon>
          </div>
        </div>

        <div class="bottom-info-content">
          <div class="tabs-box left-tab">
            <el-tabs v-model="nodeActiveName" class="demo-tabs" @tab-change="handleLeftClickFun">
              <el-tab-pane label="节点信息" name="info"></el-tab-pane>
              <el-tab-pane label="输入数据" name="input"></el-tab-pane>
              <el-tab-pane label="仿真参数" name="param"></el-tab-pane>
              <el-tab-pane label="输出数据" name="output"></el-tab-pane>
            </el-tabs>
          </div>
          <div class="operate-box">
            <!-- <el-switch
              v-model="executeMode"
              class="mr10"
              active-value="AUTO"
              inactive-value="MANUAL"
              active-text="自动执行"
              inactive-text="手动执行"
              @change="FlowNodeExecuteModeChangeFun"
            /> -->
            <!-- <el-button
              type=""
              v-if="flowNodeParamData?.nodeTypeValue === '1'"
              @click="startLocalAppFun"
              >启动</el-button
            > -->
            <!-- <el-button type="primary" @click="startLocalAppFun">执行</el-button> -->
            <!-- <el-button
              type="primary"
              v-if="flowNodeData.nodeStatus === RUN_NODE_STATUS.WAITING_FOR_USER"
              @click="continueStartRunJobFun"
              >执行手动节点</el-button
            > -->
            <!-- <el-button
              type="primary"
              @click="skipCurrentNodeFlowFun"
              v-if="flowNodeParamData?.nodeTypeValue === '1'"
              >跳过当前本地节点</el-button
            > -->
          </div>
          <div class="tabs-info-content">
            <!-- <paramSetting
              :current-run-flow-node="flowNode"
              :node-param-data="nodeParamDataList"
              :node-data="flowNodeParamData"
              :node-info="flowNodeData"
              :run-info="runInfo"
              :online-file-param="onlineFileParam"
              v-if="nodeActiveName === 'param' && showPage"
              @update="refreshFlowNodeParamFun"
            >
            </paramSetting> -->
            <!-- v-if="nodeActiveName === 'param' && showPage" -->

            <flowNodeParamTable
              ref="flowNodeParamTableRef"
              v-show="nodeActiveName === 'param' && showPage"
              :node-params="nodeParamDataList"
              :current-node="flowNode"
              :page-info="flowNodeData"
              :run-info="runInfo"
              :online-file-param="onlineFileParam"
              :flow-node-param-data="flowNodeParamData"
              :flow-node-data="flowNodeData"
              @confirm="refreshFlowNodeParamFun"
              @update="updateFlowNodeParamFun"
              @flowclick="flowclickFun"
            ></flowNodeParamTable>
            <runDataPage
              v-show="nodeActiveName === 'input' || nodeActiveName === 'output'"
              :file-id="
                nodeActiveName === 'input' ? flowNodeData?.inputDirId : flowNodeData?.outputDirId
              "
              :node-info="flowNodeData"
            ></runDataPage>

            <div class="bottom-info-content-tab" v-show="nodeActiveName === 'info'">
              <div class="node-img">
                <img :src="flowNodeParamData.iconUrl" alt="" />
              </div>
              <div class="node-content">
                <!-- <div class="button-box">
                  <el-button
                    type="primary"
                    v-if="flowNodeParamData.nodeTypeValue === '1'"
                    @click="justStartLocalAppFun"
                    >启动</el-button
                  >
                  <el-button type="primary" v-else @click="startOtherNodeFun">启动</el-button>
                  <el-button
                    type="primary"
                    v-if="
                      flowNodeData.nodeStatus === 'waiting_for_user' ||
                      flowNodeData.nodeStatus === 'active'
                    "
                    @click="continueStartRunJobFun"
                    >完成</el-button
                  >
                </div> -->
                <el-form>
                  <el-form-item label="节点名称">
                    <span>{{ flowNodeData.nodeName }}</span>
                  </el-form-item>
                  <el-form-item label="节点类型">
                    <el-tag v-if="flowNodeParamData.nodeTypeValue === '3'" type="primary">{{
                      getTypeNameFun(flowNodeParamData.nodeTypeValue)
                    }}</el-tag>
                    <el-tag v-else-if="flowNodeParamData.nodeTypeValue === '2'" type="success">{{
                      getTypeNameFun(flowNodeParamData.nodeTypeValue)
                    }}</el-tag>
                    <el-tag v-else-if="flowNodeParamData.nodeTypeValue === '1'" type="warning">{{
                      getTypeNameFun(flowNodeParamData.nodeTypeValue)
                    }}</el-tag>
                    <el-tag v-else type="primary">{{
                      getTypeNameFun(flowNodeParamData.nodeTypeValue)
                    }}</el-tag>

                    <!-- {{ flowNodeParamData?.nodeTypeValue }} -->
                  </el-form-item>
                  <el-form-item label="节点状态">
                    <div class="app-status">
                      <div
                        class="round"
                        :style="{
                          background: getStyleFun(flowNodeData?.nodeStatus).color,
                        }"
                      ></div>
                      <div class="text">
                        {{ getStyleFun(flowNodeData?.nodeStatus).title }}
                      </div>
                    </div>

                    <!-- {{ flowNodeData?.nodeDetailInfo?.status }} -->
                  </el-form-item>
                  <el-form-item label="执行时间">
                    <el-icon class="icon-style mr5"><Timer /></el-icon>
                    <span class="gl-text-ellipsis">
                      {{ flowNodeData?.nodeDetailInfo?.durationFormatted || '--' }}
                    </span>
                  </el-form-item>
                  <el-form-item label="开始时间">
                    <el-icon class="icon-style mr5"><Calendar /></el-icon>
                    <span class="gl-text-ellipsis">
                      {{ flowNodeData?.nodeDetailInfo?.startTime || '--' }}
                    </span>
                  </el-form-item>
                  <el-form-item label="完成时间">
                    <el-icon class="icon-style mr5"><Calendar /></el-icon>
                    <span class="gl-text-ellipsis">
                      {{ flowNodeData?.nodeDetailInfo?.endTime || '--' }}
                    </span>
                  </el-form-item>
                </el-form>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- </template> -->
      <!-- <template #right> -->
      <div
        v-if="!leftFullScreen"
        :class="rightFullScreen ? 'info-box-right allpage ' : 'info-box-right'"
      >
        <div class="bottom-title">
          <div class="title-name">作业相关</div>
          <div class="title-operate">
            <el-icon
              v-if="!rightFullScreen"
              class="icon-style"
              @click="rightFullScreen = !rightFullScreen"
              ><FullScreen
            /></el-icon>
            <el-icon v-else class="icon-style" @click="rightFullScreen = !rightFullScreen"
              ><Close
            /></el-icon>
          </div>
        </div>
        <div class="bottom-info-content">
          <div class="tabs-box">
            <el-tabs v-model="taskActiveName" class="demo-tabs" @tab-click="handleRightClickFun">
              <el-tab-pane label="作业列表" name="job-list"></el-tab-pane>
              <!-- <el-tab-pane label="日志输出" name="job-log"></el-tab-pane> -->
              <el-tab-pane label="关联任务" name="associated-run"></el-tab-pane>
              <el-tab-pane label="仿真结果" name="result"></el-tab-pane>
              <!-- <el-tab-pane label="性能指标" name="performance"></el-tab-pane> -->
              <el-tab-pane label="报告结果" name="report"></el-tab-pane>
              <el-tab-pane label="标准规范" name="standard"></el-tab-pane>
              <!-- <el-tab-pane label="3D模型预览" name="3D-model"></el-tab-pane> -->
            </el-tabs>
          </div>
          <div class="tabs-info-content">
            <resultData v-if="taskActiveName === 'result'" :current-run-ifno="runInfo"></resultData>
            <jobList v-if="taskActiveName === 'job-list'" :current-run-info="runInfo"></jobList>
            <taskPerformance
              v-if="taskActiveName === 'performance'"
              :param-type="'run'"
              :run-info="runInfo"
              :show-save-button="true"
              :full-height="true"
            ></taskPerformance>
            <runLogs v-if="taskActiveName === 'job-log'"></runLogs>
            <ModelReview v-if="taskActiveName === '3D-model'"></ModelReview>
            <runVersionTree
              v-if="taskActiveName === 'associated-run'"
              :current-task-info="runInfo"
            ></runVersionTree>
            <runStandard v-if="taskActiveName === 'standard'" :run-info="runInfo"></runStandard>
            <reportResult
              v-if="taskActiveName === 'report'"
              :current-run-ifno="runInfo"
            ></reportResult>
          </div>
        </div>
      </div>
      <!-- </template>
      </DragSplit> -->
    </div>
    <HpcList v-model="visible" />
  </div>
</template>

<script setup lang="ts">
import { onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
import resultData from './runPagecomponent/resultData.vue';
import runDataPage from './runPagecomponent/runDataPage.vue';
import jobList from './runPagecomponent/jobList.vue';
import taskPerformance from '@/components/taskDetail/taskPerformance.vue';
import runLogs from './runPagecomponent/runLogs.vue';
import ModelReview from './runPagecomponent/3DModelReview.vue';
import runVersionTree from './runPagecomponent/runVersionTree.vue';
import runFlowPage from './runPagecomponent/flow/runFlowPage.vue';
import HpcList from '@/components/task/hpcList.vue';
import {
  queryRunDirApi,
  retryFailedNodeApi,
  saveNodeParamsApi,
  startProcessInstanceApi,
  uploadRunFilesApi,
} from '@/api/project/run';
import {
  checklocalresourceApi,
  getdeviceuuidApi,
  startupPlugin,
  submittaskApi,
} from '@/api/application/application';
import { ElMessage } from 'element-plus';
import { asyncCallbackApi, continueServiceTaskApi } from '@/api/flowable/process';
import runStandard from './runPagecomponent/runStandard.vue';
import { RUN_NODE_STATUS, RUN_STATUS } from '@/utils/enum/run';
import { addApplicationCallRecordApi, queryAllApplicationApi } from '@/api/system/application';
import flowNodeParamTable from '@/components/flow/flowNodeParamTable.vue';
import { cloneDeep } from 'lodash-es';
import { WIDGET_TYPE } from '@/utils/enum/flow';
import emitter from '@/utils/eventBus';
import { getDictionaryDataApi } from '@/api/system/systemData';
import { getUserData, getUserId, getUserTenantId } from '@/utils/user';
import reportResult from './runPagecomponent/reportResult.vue';
import dayjs from 'dayjs';
import { base64ToStrFun, isJSONFun } from '@/utils/file';

const props = defineProps({
  runInfo: {
    type: Object,
    default: () => {},
  },
});

const emits = defineEmits(['update']);

const statusList = ref<any>({
  running: '进行中',
  completed: '已完成',
  suspended: '挂起中',
  error: '异常',
  waiting_for_user: '待操作',
});
const flowNodeParamTableRef = ref();
const executeMode = ref('MANUAL');
const visible = ref(false);
const nodeActiveName = ref('info');
const taskActiveName = ref('job-list');

const leftFullScreen = ref(false);
const rightFullScreen = ref(false);
const showPage = ref(true);
const refreshPage = ref(true);
const handleLeftClickFun = () => {};

const handleRightClickFun = () => {};

const nodeParamDataList = ref<any>([]);

const flowNode = ref<any>({});
const flowNodeData = ref<any>({});
const flowNodeParamData = ref<any>({});
const runFlowPocesInfo = ref<any>({});
const onlineFileParam = ref<any>({});
const changeCurrentFlowNodeFun = (info: any) => {
  refreshPage.value = false;
  const { node, data, process }: any = info;

  flowNode.value = node;
  flowNodeData.value = data;
  flowNodeData.value.copyNodeStatus = data?.nodeStatus;
  // nodeParamDataList.value = flowNode.value?.store?.data?.data?.pageConfigList || [];
  nodeParamDataList.value = cloneDeep(pageParamInfo.value[data.nodeName]) || [];
  flowNodeParamData.value = flowNode.value?.store?.data?.data || {};
  runFlowPocesInfo.value = process;
  onlineFileParam.value = {
    processDefinitionId: process.processDefinitionId,
    runId: data.runId,
    nodeId: data.uuid,
    beforeNodeId: flowNodeParamData.value?.beforeNodeId,
    regexConfig: {
      masterFileRegularStr: '^aa\\.xml$',
      inputFilesRegularStr: '^.+\\.json$',
    },
  };
  const params = data.userParams;
  if (params?.executeMode) {
    executeMode.value = params?.executeMode;
  } else {
    executeMode.value = 'MANUAL';
  }
  refreshPage.value = true;
  // taskActiveName.value = 'job-list';
  // nodeActiveName.value = 'info';
};

const pageParamInfo = ref<any>({});
const pageUserParam = ref<any>({});
const pageNodeDatas = ref<any>({});
const pageFlowNodeInfos = ref<any>({});
// 获取流程的每个节点的用户配置参数
const updateFlowPageParamListFun = (data: any) => {
  const { list, param, nodeDatas, flowNodeInfos }: any = data;
  pageParamInfo.value = list;
  pageUserParam.value = param;
  pageNodeDatas.value = nodeDatas;
  pageFlowNodeInfos.value = flowNodeInfos;
  for (const key in pageParamInfo.value) {
    resetTableDataFun(pageUserParam.value[key], pageParamInfo.value[key]);
  }
};

const resetTableDataFun = (obj: any, list: any) => {
  for (let i = 0; i < list.length; i++) {
    if (!list[i]?.englishLabel) {
      if (obj[list[i].vModel] && list[i]?.children?.length) {
        resetTableDataFun(obj[list[i].vModel], list[i].children);
      }
    } else {
      for (const key in obj) {
        if (list[i]?.englishLabel === key) {
          list[i].defaultValue = obj[key];
        }
      }
    }
  }
};

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

// 开始执行任务
const startTaskRunJobFun = async () => {
  // 在开始执行任务之前，保存每个节点的参数后再调用执行任务的接口

  // 检查每个节点的参数
  uploadFileFlag.value = 0;

  for (const key in pageParamInfo.value) {
    const params = pageUserParam.value[key];
    const list = pageParamInfo.value[key];
    const data = pageNodeDatas.value.find((item: any) => {
      return item.nodeName === key;
    });
    const node = pageFlowNodeInfos.value.find((item: any) => {
      return item.data.label === key;
    })?.data;
    await saveParamsFun(params, list, data, node);
  }

  // if (!uploadFileFlag.value) {
  const res: any = await startProcessInstanceApi({
    runId: props.runInfo.uuid,
  });
  if (res && res.code === 200) {
    ElMessage.success(res.message);
    showPage.value = false;
    refreshRunFlowInfo();
    emits('update', { status: RUN_STATUS.RUNNING });
    // }
  } else {
    // ElMessage.success('文件正在上传中，请勿进行其他操作！');
  }
};

const saveNodesParamFun = async () => {
  for (const key in pageParamInfo.value) {
    const params = pageUserParam.value[key];
    const list = pageParamInfo.value[key];
    const data = pageNodeDatas.value.find((item: any) => {
      return item.nodeName === key;
    });
    const node = pageFlowNodeInfos.value.find((item: any) => {
      return item.data.label === key;
    })?.data;
    await saveParamsFun(params, list, data, node);
  }
};

const saveParamsFun = async (params: any, list: any, data: any, node: any) => {
  const newParams: any = list;
  const inputParams: any = { ...params };
  const runNodeData = node;
  let result: any = false;
  result = checkParamRequiredFun(newParams);

  if (result) {
    inputParams.executeMode = 'MANUAL';
  } else {
    inputParams.executeMode = 'AUTO';
  }

  for (const key in node) {
    if (['inputFormat', 'outputFormat', 'slaveFormat'].includes(key)) {
      if (node[key]?.length) {
        inputParams[key] = base64ToStrFun(node[key]);
      } else {
        inputParams[key] = '';
      }
    }
  }

  await setDataToParam(newParams, inputParams, true, data.inputDirId);

  if (node.nodeType === 'HPC') {
    setSpecialParamData(inputParams, runNodeData);
  }

  if (runNodeData.nodeType === '脚本节点' && runNodeData.label.includes('报告')) {
    setReportSpecialParamDataFun(inputParams);
  }

  // 本地应用全部为手动节点
  if (node.nodeType === '本地应用') {
    inputParams.executeMode = 'MANUAL';
  }

  const param: any = {
    nodeUuid: data.uuid,
    runId: data.runId,
    inputParams,
  };

  const res: any = await saveNodeParamsApi(param);
  if (res && res.code === 200) {
  }
};

const uploadFileFlag = ref(0);
const setDataToParam = async (list: any, obj: any, isUpload?: any, inputDirId?: any) => {
  for (let i = 0; i < list.length; i++) {
    if (list[i]?.englishLabel) {
      if (list[i].tagType === WIDGET_TYPE.FILE && list[i]?.fileList?.length) {
        const fileList = list[i]?.fileList || [];
        let arrs: any = [];
        if (fileList.length) {
          uploadFileFlag.value++;
          const fileData = await runUploadRunFilesFun(fileList, inputDirId);
          arrs = fileData;
        }

        list[i].defaultValue = arrs;
      }
      obj[list[i].englishLabel] = list[i].defaultValue || '';
    } else {
      if (list[i].tagType === WIDGET_TYPE.VIEW && list[i].tagIcon === 'row') {
        if (list[i]?.children?.length) {
          obj[list[i].vModel] = {};
          setDataToParam(list[i]?.children, obj[list[i].vModel], isUpload);
        }
      }
    }
  }
};

const runUploadRunFilesFun = async (list: any, inputDirId: any) => {
  const sourceFiles = list.map((item: any) => {
    return {
      fileName: item.name,
      size: item.size,
      fileType: '',
    };
  });

  const param = {
    sourceFiles,
    uploadTaskId: new Date().getTime(),
    dirId: inputDirId,
  };

  const res: any = await uploadRunFilesApi(param);

  if (res && res.code === 200) {
    res.data.forEach((item: any, index: any) => {
      item.isSaveLocal = 'Y';
      emitter.emit('ADD_UPLOAD_FILE', {
        file: list[index].raw,
        data: {
          // 接口返回的文件目录信息，包括配置信息
          ...item,
          isApprove: 0, // 0否 1是
          taskType: 4, // 4交付物
          callbackFlag: 'START_FLOW',
        },
      });
    });
  }

  if (res.code === 200) {
    const result = res.data.map((item: any) => {
      // return item.objectKey;
      const path = item.objectKey.split('/').slice(0, -1).concat(item.sourceFileName).join('/');
      return path;
    });

    return result;
  }
};

// 检查是否必填参数都填写
const checkParamRequiredFun = (list: any) => {
  for (let i = 0; i < list.length; i++) {
    if (list[i].required) {
      if (list[i].tagType === WIDGET_TYPE.FILE) {
        if (!list[i]?.fileList?.length && !list[i].defaultValue?.length) {
          return true;
        }
      } else {
        if (!list[i].defaultValue) {
          return true;
        }
      }
    } else {
      if (list[i]?.children?.length) {
        checkParamRequiredFun(list[i]?.children);
      }
    }
  }
};

// 设置特殊的参数信息
const setSpecialParamData = (param: any, data: any) => {
  param.taskId = props.runInfo.taskId;
  param.taskName = props.runInfo.parentName;
  param.runId = props.runInfo.uuid;
  param.runName = props.runInfo.runName;
  param.projectname = props.runInfo.projectName;
  // param.software = '电池仿真';
  // param.jobName = '测试任务' + new Date().getTime();
  if (!param.jobName) {
    param.jobName = '测试任务' + new Date().getTime();
  }
  param.software = data.label;
  const keys = Object.keys(param);
  if (keys.includes('masterFileRegularStr') && keys.includes('inputFilesRegularStr')) {
    param.explicitInputFiles = {
      masterFileRegularStr: param.masterFileRegularStr.length ? param.masterFileRegularStr : [],
      inputFilesRegularStr: param.inputFilesRegularStr.length ? param.inputFilesRegularStr : [],
    };
  }
};

// 报告脚本生成参数填写
const setReportSpecialParamDataFun = (param: any) => {
  const projectInfo = JSON.parse(
    localStorage.getItem('CURRENT_FILTER_RUN_TASK_TREE_PARAM') as string
  );

  param.reportName = '算例报告_' + dayjs().format('YYYY_MM_DD_HH_mm');
  param.applicants = getUserData().nickname;
  param.date = dayjs().format('YYYY-MM-DD HH:mm:ss');
  param.loadcaseName = props.runInfo.parentName;
  param.projectNum = projectInfo?.projectCode;
  param.formulateTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  param.checkTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  param.approveTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  param.workspace = '';
  param.workspaceNum = '';
};

const continueStartRunJobFun = async () => {
  if (uploadFileFlag.value) {
    ElMessage.warning('等待文件上传完毕后再执行流程!');
    return;
  }

  if (flowNodeData.value.nodeStatus === 'active') {
    await skipCurrentNodeFlowFun();
  }

  const res: any = await continueServiceTaskApi({
    processInstanceId: flowNodeData.value.processInstanceId,
    taskDefinitionKey: flowNodeData.value.nodeId,
    flowelementType: flowNodeData.value.nodeDetailInfo.type,
  });
  if (res && res.code === 200) {
    showPage.value = false;
    refreshRunFlowInfo();
  }
};

// 启动应用
const startLocalAppFun = async () => {
  if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.WAITING_FOR_USER) {
    continueStartRunJobFun();
  } else if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.ERROR) {
    // 重新执行失败的流程节点
    // 重新保存该流程节点的参数
    await flowNodeParamTableRef.value.saveNodeParamFun('RESTART_FLOW_NODE');
    // 调用重新执行的接口
  } else {
    // 本地节点拉起应用
    if (flowNodeParamData.value?.nodeTypeValue === '1') {
      await justStartLocalAppFun();
    }
  }
};

const getAppInfo = async (uuid: any) => {
  const param = {
    appName: '',
    current: 1,
    size: 999,
  };
  try {
    const res: any = await queryAllApplicationApi(param);
    if (res && res.code === 200) {
      for (let i = 0; i < res.data.data.length; i++) {
        const paths = isJSONFun(res.data.data[i].appPath)
          ? JSON.parse(res.data.data[i].appPath as string)
          : res.data.data[i].appPath;

        if (paths && paths instanceof Object) {
          const keys = Object.keys(paths);
          if (keys.includes(getUserId())) {
            res.data.data[i].appPath = paths[getUserId()];
          } else {
            res.data.data[i].appPath = '';
          }
        }
      }

      const appPath = res.data.data.find((item: any) => {
        return item.uuid === uuid;
      })?.appPath;
      return appPath;
    } else {
      return '';
    }
  } catch {
    return '';
  }
};

const justStartLocalAppFun = async () => {
  if (uploadFileFlag.value) {
    ElMessage.success('等待文件传输完成后再进行操作');
    return;
  }

  // if (flowNodeParamData.value?.nodeTypeValue === '1') {
  // const appPath = flowNodeParamData.value.appPath || '';

  const appUuid = flowNodeParamData.value.uuid;
  const appPath = (await getAppInfo(appUuid)) || '';

  await getdeviceuuidFun();
  const uuid = localStorage.getItem('USER_UUID');

  if (uuid) {
    const result: any = await checklocalresourceFun(appPath);
    if (result) {
      const params = await getSubmitParamFun(appPath);
      const res: any = await submittaskApi(params);
      if (res && res.code === 200) {
        const res2: any = await addApplicationCallRecordApi({
          appName: flowNodeParamData.value.label,
          appType: flowNodeParamData.value.nodeTypeValue,
          creator: flowNodeParamData.value.creator,
        });
        if (res2 && res2.code === 200) {
        }
        ElMessage.success('应用正在启动中，请等待');
        refreshFun();
      } else {
      }
    }
  } else {
    return;
  }
  // }
};

// 启动其他应用
const startOtherNodeFun = async () => {
  if (uploadFileFlag.value) {
    ElMessage.success('等待文件传输完成后再进行操作');
    return;
  }
  if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.WAITING_FOR_USER) {
    continueStartRunJobFun();
  } else if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.ERROR) {
    await flowNodeParamTableRef.value.saveNodeParamFun('RESTART_FLOW_NODE');
  }
};

// 重新执行节点按钮
const retryFailedNodeFun = async () => {
  const param = {
    processInstanceId: flowNodeData.value.processInstanceId,
    failNodeId: flowNodeData.value.nodeId,
  };

  try {
    const res: any = await retryFailedNodeApi(param);
    if (res && res.code === 200) {
      ElMessage.success('节点已重新执行!');
      showPage.value = false;
      refreshRunFlowInfo();
    }
  } catch (error) {
    console.error(error);
  }
};

// 获取插件提交计算的参数信息
const getSubmitParamFun = async (appPath: any) => {
  const taskName = props.runInfo?.parentName;
  const taskId = props.runInfo?.taskId;
  const taskCmd = appPath;
  const taskPreCmd = flowNodeParamData.value.preExeCommand;
  const taskPostCmd = flowNodeParamData.value.postExeCommand;
  const runId = props.runInfo?.uuid;
  const runName = props.runInfo?.runName;
  const taskPreCmdParam = {
    'load.py': '',
  };
  const taskPostCmdParam = {
    'pptx.py': '',
  };
  const { fileIds, fileNames, taskCmdParam }: any = await getNodeFileIdAndNames();

  const fileType = await getfileTypeList();
  const uploadId = flowNodeData.value.userParams.outputDirId.toString();
  const owner = getUserData()?.nickname;
  const tenantId = getUserTenantId().toString();
  const userId = getUserId().toString();
  const localAppName = flowNodeData.value.nodeName;
  const localAppVersion = '';
  const creatorId = getUserId().toString();
  const subRunId = flowNodeData.value.nodeId;
  const asyncTaskId = flowNodeData.value.nodeDetailInfo?.asyncTaskId;
  const outputFormat = flowNodeParamData.value.outputFormat;
  return {
    runId,
    runName,
    taskName,
    taskId,
    taskCmd,
    taskPreCmd,
    taskPostCmd,
    taskCmdParam,
    taskPostCmdParam,
    taskPreCmdParam,
    fileIds,
    fileNames,
    fileType,
    uploadId,
    owner,
    tenantId,
    userId,
    localAppName,
    localAppVersion,
    creatorId,
    subRunId,
    asyncTaskId,
    outputFormat,
  };
};

const getNodeFileIdAndNames = async () => {
  const dirId = flowNodeData.value.userParams.inputDirId;
  const fileIds: any = [];
  const fileNames: any = [];
  const taskCmdParam: any = {};

  // 本地应用执行的脚本也需要下载下来
  if (flowNodeParamData.value?.postScripts?.length) {
    for (let i = 0; i < flowNodeParamData.value?.postScripts?.length; i++) {
      fileIds.push(flowNodeParamData.value?.postScripts[i].fileId);
      fileNames.push(flowNodeParamData.value?.postScripts[i].name);
    }
  }

  if (flowNodeParamData.value?.preScripts?.length) {
    for (let i = 0; i < flowNodeParamData.value?.preScripts?.length; i++) {
      fileIds.push(flowNodeParamData.value?.preScripts[i].fileId);
      fileNames.push(flowNodeParamData.value?.preScripts[i].name);
    }
  }

  try {
    const res: any = await queryRunDirApi({
      current: 1,
      fileId: dirId,
      size: 999,
    });

    if (res && res.code === 200) {
      const list = res.data.data;
      for (let i = 0; i < list.length; i++) {
        fileIds.push(list[i].id.toString());
        fileNames.push(list[i].originalName);
      }
      // if (flowNodeParamData.value.nodeExeCommand) {
      //   taskCmdParam[flowNodeParamData.value.nodeExeCommand] = './' + fileNames.join(',');
      //   // = fileNames.map((item: any) => {
      //   //   return { [flowNodeParamData.value.nodeExeCommand]: item };
      //   // });
      // } else {
      //   taskCmdParam = {};
      // }

      if (Object.keys(flowNodeData.value.userParams).includes('--export')) {
        taskCmdParam['--export'] = flowNodeData.value.userParams['--export'];
      }
      if (Object.keys(flowNodeData.value.userParams).includes('--import')) {
        taskCmdParam['--import'] = './' + fileNames.join(',');
      }
      return {
        fileIds,
        fileNames,
        taskCmdParam,
      };
    } else {
      return {
        fileIds,
        fileNames,
        taskCmdParam,
      };
    }
  } catch {
    return {
      fileIds,
      fileNames,
      taskCmdParam,
    };
  }
};

const getfileTypeList = async () => {
  try {
    const res: any = await getDictionaryDataApi({ dictClass: 'FILE_UPLOAD_ALLOCATION_TYPE' });
    if (res && res.code === 200) {
      // const types: any = res.data.map((item: any) => {
      //   const obj: any = {};
      //   obj[item.dictName] = item.dictValue.split(',');
      //   return obj;
      // });
      const obj: any = {};
      for (let i = 0; i < res.data.length; i++) {
        obj[res.data[i].dictName] = res.data[i].dictValue.split(',');
      }

      const outPutFile = flowNodeData.value?.userParams?.outputFileType?.split(',') || [];
      if (outPutFile?.length) {
        const list: any = [];
        for (let i = 0; i < outPutFile.length; i++) {
          let isReturnFile = true;
          for (const key in obj) {
            if (obj[key].includes(outPutFile[i])) {
              isReturnFile = false;
            }
          }

          if (isReturnFile) {
            list.push(outPutFile[i]);
          }
        }

        obj['1'] = obj['1'].concat(list);
      }

      return obj;
    } else {
      return {};
    }
  } catch {
    return {};
  }
};

// 检查资源是否合法
const checklocalresourceFun = async (path: any) => {
  try {
    const res: any = await checklocalresourceApi({ resource: [path] });
    if (res && res.code === 200) {
      if (res.data.returnCode.includes('Operate Success')) {
        return true;
      } else {
        return false;
      }
    }
  } catch {
    return false;
  }
};

const getdeviceuuidFun = async () => {
  try {
    const res: any = await getdeviceuuidApi();
    if (res && res.code === 200) {
      const uuid = res.data.returnCode
        .replace('UUID', '')
        .replace(/\ +/g, '')
        .replace(/[\r\n]/g, '');

      localStorage.setItem('USER_UUID', uuid);
    }
  } catch {
    startupPlugin();
  }
};

// 刷新节点页面信息
const refreshRunFlowInfo = () => {
  setTimeout(() => {
    showPage.value = true;
  });
};

const refreshFun = () => {
  showPage.value = false;
  refreshRunFlowInfo();
};

// const FlowNodeExecuteModeChangeFun = async () => {
//   const inputParams = {
//     ...flowNodeData.value.userParams,
//     executeMode: executeMode.value,
//   };
//   const params = {
//     nodeUuid: flowNodeParamData.value?.flowNodeInfo?.uuid,
//     runId: props.runInfo.uuid,
//     inputParams,
//   };
//   try {
//     const res: any = await saveNodeParamsApi(params);
//     if (res && res.code === 200) {
//       ElMessage.success('操作成功');
//       refreshFun();
//     } else {
//     }
//   } catch {}
// };

const refreshFlowNodeParamFun = async (data: any) => {
  const { flag }: any = data;
  if (flag === false) {
    await retryFailedNodeFun();
    showPage.value = false;
    refreshRunFlowInfo();
  }

  if (flag === true) {
    ElMessage.success('文件正在上传中，请等待文件上传完成后再操作');
  }
};
const newNodeData = ref<any>({});
const updateFlowNodeParamFun = (data: any) => {
  for (let i = 0; i < pageParamInfo.value[flowNodeData.value.nodeName].length; i++) {
    for (const key in data[i]) {
      pageParamInfo.value[flowNodeData.value.nodeName][i][key] = data[i][key];
    }
  }
  newNodeData.value[flowNodeData.value.nodeName] = data;
  // nodeParamDataList.value = data;
};

const getStyleFun = (flag: any) => {
  const styles: any = {
    active: {
      color: '#409eff',
      title: '进行中',
    },
    waiting_for_user: {
      color: '#409eff',
      title: '进行中',
    },
    finished: {
      color: '#67c23a',
      title: '已完成',
    },
    pending: {
      color: '#909399',
      title: '未开始',
    },
  };

  if (styles[flag]) {
    return styles[flag];
  } else {
    return {
      color: '#f56c6c',
      title: '异常',
    };
  }
};

const getTypeNameFun = (type: any) => {
  const str =
    appTypeList.value.find((item: any) => {
      return item.dictValue === type;
    })?.dictName || '';

  return str;
};

const appTypeList = ref<any>([]);
const getDictionaryDataFun = async () => {
  const res: any = await getDictionaryDataApi({
    dictClass: 'APP_TYPE',
  });
  if (res && res.code === 200) {
    appTypeList.value = res.data;
  }
};

const skipCurrentNodeFlowFun = async () => {
  const params = {
    asyncTaskId: flowNodeData.value?.nodeDetailInfo.asyncTaskId,
    resultJson: 'success',
    status: 'SUCCESS',
  };

  try {
    const res: any = await asyncCallbackApi(params);
    if (res && res.code === 200) {
      // refreshFun();
    }
  } catch (error) {
    console.error(error);
  }
};

// 双击两次执行当前应用节点
const executeFun = () => {
  if (uploadFileFlag.value) {
    ElMessage.success('文件未上传完整，请等待稍后再进行操作');
    return;
  }

  startLocalAppFun();
};

// 文件上传完成后的回调事件
const uploadFinishedFun = async (data: any) => {
  // 开始任务执行
  if (data.callbackFlag === 'START_FLOW') {
    uploadFileFlag.value--;

    // const res: any = await startProcessInstanceApi({
    //   runId: props.runInfo.uuid,
    // });
    // if (res && res.code === 200) {
    //   ElMessage.success(res.message);
    //   showPage.value = false;
    //   refreshRunFlowInfo();
    //   emits('update', { status: RUN_STATUS.RUNNING });
    // }
  }

  // 重复执行失败节点
  if (data.callbackFlag === 'RESTART_FLOW_NODE') {
    await retryFailedNodeFun();
  }
};

const flowclickFun = async (flag: any) => {
  await saveNodesParamFun();

  if (flag === 'justStartLocalAppFun') {
    await justStartLocalAppFun();
  }
  if (flag === 'startOtherNodeFun') {
    await startOtherNodeFun();
  }
  if (flag === 'continueStartRunJobFun') {
    await continueStartRunJobFun();
  }
};

watch(
  () => props.runInfo,
  (newVal) => {
    if (newVal) {
      currentRunNodeInfo.value = newVal;
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

const timer = ref<any>(null);

onMounted(async () => {
  await getDictionaryDataFun();
  emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
  // 5分钟自动刷新一次流程信息
  timer.value = setInterval(
    () => {
      refreshFun();
    },
    5 * 60 * 1000
  );
});

onBeforeUnmount(() => {
  emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
  clearInterval(timer.value);
});

onActivated(() => {
  emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
});

onDeactivated(() => {
  emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
});
</script>

<style lang="scss" scoped>
.run-detail-page {
  width: 100%;
  height: 100%;
  position: relative;

  .run-title-box {
    width: 100%;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: #fff;
    padding-right: 10px;
    padding-left: 10px;
    margin-bottom: 10px;
    border-radius: 2px;

    .task-info {
      height: 100%;
      display: flex;
      align-items: center;

      .task-name {
        padding-left: 10px;
        border-left: 3px solid var(--el-color-primary);
        font-size: 16px;
        font-weight: 600;
        margin-right: 20px;
      }

      .task-executor {
        height: 100%;
        display: flex;
        align-items: center;
        font-size: 14px;
        margin-right: 20px;
      }

      .task-status {
        height: 100%;
        display: flex;
        align-items: center;
        font-size: 14px;
        margin-right: 20px;

        .status {
          height: 100%;
          display: flex;
          align-items: center;
        }
      }

      .task-time {
        height: 100%;
        display: flex;
        align-items: center;
        font-size: 14px;
        margin-right: 20px;
      }

      .name {
        font-weight: 600;
      }
    }
  }

  .run-flow-box {
    width: 100%;
    height: 200px;
    background-color: #fff;
    margin-bottom: 10px;
    border-radius: 2px;
    overflow: hidden;

    .flow-box-inner {
      width: 100%;
      height: 100%;
    }
  }

  .run-info-box {
    width: 100%;
    height: calc(100% - 270px);
    display: flex;
    align-items: center;
    justify-content: space-between;

    .run-flow-info-box {
      width: 100%;
      height: 180px;
      margin-bottom: 10px;
      border-radius: 2px;
      background-color: #fff;

      .bottom-title {
        width: 100%;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-left: 10px;

        .title-name {
          padding-left: 10px;
          border-left: 3px solid var(--el-color-primary);
          font-size: 14px;
          font-weight: 600;
        }

        .title-operate {
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: flex-end;
          padding-right: 10px;

          .icon-style {
            font-size: 16px;
            color: var(--el-color-primary);
            cursor: pointer;
          }
        }
      }

      .bottom-info-content {
        width: 100%;
        height: calc(100% - 40px);
        padding: 0 10px;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .node-img {
          width: 100px;
          height: 100%;
          display: flex;
          justify-content: center;

          img {
            width: 100px;
            height: 100px;
            background-color: #f2f2f2;
            border-radius: 5px;
          }
        }

        .node-content {
          width: calc(100% - 140px);
          height: 100%;

          // .el-form {
          //   width: 100%;
          //   height: 100%;
          //   flex-wrap: wrap;

          //   .el-form-item {
          //     // width: calc(100% / 4);
          //   }
          // }
        }
      }
    }

    .info-box-left,
    .info-box-right {
      width: calc(50% - 5px);
      // width: 100%;
      // height: 500px;
      height: 100%;
      background-color: #fff;
      border-radius: 2px;
      // margin-bottom: 10px;
      // overflow: hidden;

      .bottom-title {
        width: 100%;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-left: 10px;

        .title-name {
          padding-left: 10px;
          border-left: 3px solid var(--el-color-primary);
          font-size: 14px;
          font-weight: 600;
        }

        .title-operate {
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: flex-end;
          padding-right: 10px;

          .icon-style {
            font-size: 16px;
            color: var(--el-color-primary);
            cursor: pointer;
          }
        }
      }

      .bottom-info-content {
        width: 100%;
        height: calc(100% - 40px);
        padding: 0 10px;
        position: relative;

        .operate-box {
          position: absolute;
          top: 0;
          right: 20px;
        }

        .tabs-box {
          // width: calc(100% - 220px);
          height: 40px;
        }

        // .left-tab {
        //   width: calc(100% - 140px);
        // }

        .tabs-info-content {
          width: 100%;
          height: calc(100% - 50px);
          padding: 10px;
          overflow: auto;
        }
      }
    }

    .allpage {
      width: 100%;
      height: 100%;
    }
  }

  .is-all-page {
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 20;
    position: absolute;
  }

  .blue {
    color: var(--el-color-primary);
    margin-right: 5px;
  }
}

.app-status {
  width: 60px;
  display: flex;
  align-items: center;

  .round {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #191919;
    margin-right: 5px;
  }

  .text {
    font-size: 12px;
  }
}

.point {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.status-title {
  padding-left: 8px;
}

.success {
  color: #67c23a;
}

.error {
  color: #f56c6c;
}

.mr5 {
  margin-right: 5px;
}

.info {
  color: grey;
}

.success {
  color: #67c23a;
}

.warn {
  color: #f56c6c;
}

.upload {
  color: #409eff;
}

.mr10 {
  margin-right: 10px;
}

.icon-style {
  font-size: 16px;
  color: var(--el-color-primary);
  cursor: pointer;
}

.mr5 {
  margin-right: 5px;
}

.bottom-info-content-tab {
  width: 100%;
  // height: calc(100% - 40px);
  height: 100%;
  padding: 0 10px;
  padding-right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  // padding: 20px;

  .node-img {
    width: 100px;
    height: 100%;
    display: flex;
    justify-content: center;

    img {
      width: 100px;
      height: 100px;
      background-color: #f2f2f2;
      border-radius: 5px;
    }
  }

  .node-content {
    width: calc(100% - 140px);
    height: 100%;
    padding: 0 20px;
    padding-right: 0;
    padding-bottom: 0;

    .el-form {
      width: 100%;
      // height: 100%;
      height: calc(100% - 50px);
      overflow: auto;
      flex-wrap: wrap;

      .el-form-item {
        // width: calc(100% / 3);
      }
    }

    .button-box {
      width: 100%;
      height: 50px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }
  }
}
</style>
