<template>
  <div class="app-container simulation-add-task">
    <el-card class="card-step">
      <el-steps style="width: 900px;max-width: 900px;" :space="200" :active="active" finish-status="success">
        <el-step title="Step1" :class="active == 0 ? 'active' : ''" description="评估基本信息填写" />
        <el-step title="Step2" :class="active == 1 ? 'active' : ''" description="选择模型" />
        <el-step title="Step3" :class="active == 2 ? 'active' : ''" description="选择设备" />
        <el-step title="Step4" :class="active == 3 ? 'active' : ''" description="评估数据集选择" />
      </el-steps>
    </el-card>
    <div style="margin-bottom:100px;" class="card-content">
      <addStep1 ref="step1" v-if="active == 1" />
      <addStep2 ref="step2" v-if="active == 2" />
      <addStep3 ref="step3" v-if="active == 3" :modelInfo="modelInfo" />
      <addStep4 ref="step4" v-if="active == 4" />
    </div>
    <el-card class="card-footer">
      <el-button type="primary" v-if="active == 3 && state == 0" @click="doCompile">编译部署</el-button>
      <el-button type="primary" v-if="active == 3 && state == 1" loading disabled>编译中...</el-button>
      <el-button type="primary" v-if="active == 3 && state == 2" loading disabled>部署中...</el-button>
      <el-button type="primary" v-if="active == 4" @click="doStart" :loading="state > 0" :disabled="state > 0">{{ state
        ==
        0 ? "开始推理" : "推理中..." }}</el-button>
      <el-button type="primary" v-if="active > 0 && active < 3 && active != 3" @click="doPrev">上一步</el-button>
      <template v-if="(active == 3 && (state == 0 || state == 3)) || (active == 4 && state == 0)">
        <el-button type="primary" @click="doPrev">上一步</el-button>
      </template>
      <template v-if="active == 3 && state == 3">
        <el-button @click="doNext">下一步</el-button>
      </template>
      <el-button @click="doNext" v-if="active < 3">下一步</el-button>
    </el-card>
  </div>
</template>

<script setup>
import inferenceApi from '@/api/inference'
import logsApi from '@/api/log'
import taskApi from '@/api/task'
import request from 'axios'
import addStep1 from './addStep1.vue'
import addStep2 from './addStep2.vue'
import addStep3 from './addStep3.vue'
import addStep4 from './addStep4.vue'
const router = useRouter();
const active = ref(1)
const step1 = ref()
const step2 = ref()
const step3 = ref()
const step4 = ref()
let modelInfo = reactive({});
let state = ref(0);

let info = reactive({
  devices: [],
  taskInfo: null,
  optIds: [],
  logs: [],
  datas: null,
  taskId: 0,
  inferenceId: 0,
})
//开始推理
const doStart = () => {
  let tmp = step4.value.checkForm();
  if (tmp) {
    info.datas = tmp;
    state.value = 1;
    //startInference();
    doAddTask();
  } else {
    ElMessage.error("请选择数据集!");
  }
}
const doAddTask = () => {
  let postData = {
    task_name: info.taskInfo.taskName,
    task_desc: info.taskInfo.taskDesc,
    infr_task_type: info.taskInfo.taskType,
    model_id: modelInfo.model_id,
    connection_id: modelInfo.connection_id,
    data_set_id: info.datas.dataset_id,
    task_params: {},
    device_list: info.devices.map(it => {
      return {
        device_id: it.device_id,
        tool_params_id: it.tool_params_id,
        tool_id: it.tool_id
      }
    })
  }
  taskApi.addTask(postData).then(d => {
    info.taskId = d.data?.data?.task_id || 0;
    startInference()
  });
};
//开始推理
const startInference = () => {
  //创建推理任务
  let postData = {}
  inferenceApi.startInference(postData).then(d => {
    info.inferenceId = d.data?.data?.operation_id || 0;
    if (info.inferenceId > 0) {
      ElMessage.success("创建推理任务成功!");
      setTimeout(() => {
        router.push({ path: "/simulationEvaluation/execution" });
      }, 1000);
    }
  });

}
const doCompile = () => {
  let tmp = step3.value.checkForm();
  if (tmp) {
    info.devices = tmp;
    state.value = 1;
    step3.value.updateState(state.value);
    startComplie();//开始编译
    //ElMessage.success("开始编译部署!");
  } else {
    ElMessage.error("请选择设备!");
  }
}
//开始编译
const startComplie = () => {
  let ajaxs = info.devices.map(d => {
    return inferenceApi.doCompile({
      model_id: modelInfo.model_id,
      modl_net_type: modelInfo.modl_net_type,
      tool_params_id: d.tool_params_id,
      device_id: d.device_id
    });
  })
  addLogs({ msg: "开始编译....", type: "info" })
  request.all(ajaxs).then(d => {
    info.optIds = d.map(it => {
      return {
        id: it.data.data.operation_id, //op_id
        state: 0 //状态 1为完成
      }
    });
    doGetComplieLogs();//获取编译日志
  });

};
const addLogs = msg => {
  info.logs = [msg, ...info.logs];
  step3.value.updateLogs(info.logs);
}
//获取编译日志
const doGetComplieLogs = () => {
  let ajaxs = [];
  info.optIds.filter(d => d.state == 0).forEach(o => {
    ajaxs.push(logsApi.userOperation(o.id));
    ajaxs.push(logsApi.compileDeploy(o.id));
  })

  request.all(ajaxs).then(d => {
    d.forEach((it, idx) => {
      let msg = it.data.data;
      if (msg.operation_result) {
        addLogs({ msg: msg.operation_result });
        info.optIds[idx].state = msg.operation_finished ? 1 : 0;
      }
      if (msg.log_msg) {
        addLogs({ msg: `[${msg.update_time}${msg.logs_level}]${msg.log_msg}` })
      }
    });
    if (info.optIds.filter(d => d.state == 0).length > 0) {
      setTimeout(doGetComplieLogs, 2000);
    } else {
      doDeploy();
    }
  });
}
const doDeploy = () => {
  state.value = 2;
  step3.value.updateState(state.value);
  addLogs({ msg: "开始部署....", type: 'info' })
  let ajaxs = info.devices.map(d => {
    return inferenceApi.doDeploy({
      model_id: modelInfo.model_id,
      modl_net_type: modelInfo.modl_net_type,
      device_id: d.device_id
    });
  });
  request.all(ajaxs).then(d => {
    info.optIds = d.map(it => {
      return {
        id: it.data.data.operation_id, //op_id
        state: 0 //状态 1为完成
      }
    });
    doGetDeployLogs();//获取编译日志
  })
};

const doGetDeployLogs = () => {
  let ajaxs = [];
  info.optIds.filter(d => d.state == 0).forEach(o => {
    ajaxs.push(logsApi.userOperation(o.id));
    ajaxs.push(logsApi.compileDeploy(o.id));
  })
  request.all(ajaxs).then(d => {
    d.forEach((it, idx) => {
      let msg = it.data.data;
      if (msg.operation_result) {
        addLogs({ msg: msg.operation_result });
        info.optIds[idx].state = msg.operation_finished ? 1 : 0;
      }
      if (msg.log_msg) {
        addLogs({ msg: `[${msg.update_time}${msg.logs_level}]${msg.log_msg}` })
      }
    });
    if (info.optIds.filter(d => d.state == 0).length > 0) {
      setTimeout(doGetDeployLogs, 2000);
    } else {
      addLogs({ msg: "编译部署完成", type: 'success' })
      state.value = 3;
      step3.value.updateState(state.value);
    }
  });
};

const doPrev = () => {
  active.value--;
  if (active.value == 3) {
    state.value = 0;
    info.logs = [];
    info.optIds = [];
  }
}
const doNext = () => {
  if (active.value == 1) {
    step1.value.checkForm().then(d => {
      if (d) {
        info.taskInfo = step1.value.getFormData();
        active.value++;
      }
    });
  } else if (active.value == 2) {
    let tmp = step2.value.checkForm();
    if (tmp) {
      modelInfo = tmp;
      state.value = 0;
      info.logs = [];
      info.optIds = [];
      active.value++;
    } else {
      ElMessage.error("请选择模型!");
    }
  } else if (active.value == 3) {
    active.value++;
    state.value = 0;
  } else if (active.value == 4) {

  } else {
    active.value++;
  }
}
</script>
<style lang='scss'>
.simulation-add-task {
  .card-step {
    .el-card__body {
      padding-left: 100px;
      display: flex;
      justify-content: center;

      .el-steps {
        flex-grow: 1;
        margin-left: 100px;

        .el-step {
          &.active {}

          .el-step__main {
            position: relative;

            .el-step__title {
              display: inline-block;
              width: 150px;
              text-align: center;
              padding: 0px;
              position: relative;
              left: -65px;
            }

            .el-step__description {
              display: inline-block;
              width: 150px;
              text-align: center;
              padding: 0px;
              position: relative;
              left: -65px;
            }
          }
        }
      }
    }
  }

  .card-content {
    position: relative;

    .el-card__header {
      padding: 8px 12px;
      display: flex;
      align-items: center;
      font-weight: bold;
    }
  }

  .card-footer {
    position: fixed;
    width: calc(100% - 215px);
    bottom: 0px;

    :deep(.el-card__body) {
      padding: 10px;

      .el-pagination {
        justify-content: end;
      }
    }
  }
}
</style>