<template>
  <div>
    <div class="dialog" v-bind="dialogBig">
      <div class="dialog-title">
        <div class="timeView">
          <el-icon style="margin: 0px 5px;">
            <Clock/>
          </el-icon>
          <span>检测用时：{{ timeView }}</span>
        </div>
        <el-progress
            style="width: 82%; margin-right: 3%;"
            :percentage="percentage"
            :color="customColors"/>
        <el-button style="width: 10%" type="text" :icon="InfoFilled" @click="showTestLog">检测项进度</el-button>
      </div>

      <div class="dialog-content">
        <el-table :data="checkResultView" row-key="scriptType" height="450px"
                  :header-cell-style="{ background: 'var(--el-color-primary)', color: '#eee', textAlign: 'center' } " style="width: 100%"
                  border>
          <el-table-column fixed prop="scriptName" label="检测项目" width="150px" align="center">
          </el-table-column>

          <template v-if="chnSum<=MAX_CHN_SUM">
            <el-table-column v-for="(item,index1) in deviceList" :key="item.deviceId" :label="item.deviceName"
                             :min-width="110" align="center">
              <el-table-column v-for="(chnItem,index2) in item.chnNum" :key="`${item.deviceId}${chnItem}`"
                               :label="'通道'+chnItem" align="center">
                <template #default="{row}">
                  <el-tooltip
                      :content="row.devices[index1].chnResult[index2].icon==='More' ? '暂无数据'
                      : row.devices[index1].chnResult[index2].icon==='CircleCheckFilled' ? '符合'
                      : row.devices[index1].chnResult[index2].icon==='Close' ? '不符合'
                      : row.devices[index1].chnResult[index2].icon==='WarnTriangleFilled' ? '数据异常'
                      : row.devices[index1].chnResult[index2].icon==='Loading'? '检测中':'连接中断'"
                      placement="right">
                    <el-button
                        :disabled="row.devices[index1].chnResult[index2].color===CheckData.ButtonColorEnum.INFO || row.devices[index1].chnResult[index2].color===CheckData.ButtonColorEnum.LOADING"
                        :color="row.devices[index1].chnResult[index2].color"
                        size="small"
                        @click="handleClick(item,chnItem,row.scriptType)"
                        style="align-self: center;"
                    >
                      <el-icon v-if="row.devices[index1].chnResult[index2].icon==='Loading'" class="loading-box"
                               style="color: #fff">
                        <component :is="Loading"/>
                      </el-icon>
                      <el-icon v-else style="color: #fff">
                        <component :is="row.devices[index1].chnResult[index2].icon"/>
                      </el-icon>
                    </el-button>

                  </el-tooltip>
                </template>
              </el-table-column>
            </el-table-column>
          </template>
        </el-table>
      </div>
 
    </div>
    <div class="drawer-container">
      <el-drawer v-model="drawer" title="检测项进度" direction="btt" :size="'38%'">
        <div ref="scrollContainerRef" style="height: 100%; overflow-y: auto;">
          <p v-for="(item, index) in testLogList"
             :key="index"
             :style="{color:item.type==='error'?'#F56C6C': item.type==='warning'?'#e6a23c':'var(--el-text-color-regular)'}">
            {{ item.log }}<br/>
          </p>
        </div>
      </el-drawer>
    </div>

    <dataCheckSingleChannelSingleTestPopup ref="dataCheckSingleChannelSingleTestPopupRef"/>
  </div>
</template>
<script lang="tsx" setup name="test">
import {InfoFilled, Loading} from '@element-plus/icons-vue'
import dataCheckSingleChannelSingleTestPopup from './dataCheckSingleChannelSingleTestPopup.vue'
import {computed, reactive, ref, toRef, watch} from "vue";
import {dialogBig} from "@/utils/elementBind";
import {CheckData} from "@/api/check/interface"
import {useCheckStore} from "@/stores/modules/check";
import {ElMessage, ElMessageBox} from "element-plus";
import {getBigTestItem} from "@/api/check/test";
import {getAutoGenerate} from "@/api/user/login";
import {generateDevReport} from "@/api/plan/plan";


const checkStore = useCheckStore()

// 最大通道数
const MAX_CHN_SUM = 12

// 总测试项数
let checkTotal = 0

const props = defineProps({
  testStatus: {
    type: String,
    default: 'waiting'
  },
  stepsActive: {
    type: Number,
  },
  webMsgSend: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:testStatus', 'update:webMsgSend', 'sendPause', 'sendResume', 'sendReCheck', 'closeWebSocket']);

// 用来保存测试项进度抽屉是否打开
const drawer = ref(false)
// 进度条颜色
const customColors = [{color: "#91cc75", percentage: 100}]
// 检测脚本数据
let scriptData: CheckData.ScriptItem[] = []
// 用来保存被检设备
const deviceList = reactive<CheckData.Device[]>([])
// 当前进行的测试项索引
let activeIndex = 0
// 百分比
const percentage = ref(0);
// 时间计数器
let timer: any = null
const timeCount = ref(0)
const timeView = ref('00:00:00')
//测试项开始检测时间（或继续检测时间）
const startData = ref(new Date())
//测试项检测结束时间（或暂停时的时间）
const endData = ref(new Date())
const timeDifference = ref(0)
// 真正的检测结果（详细到通道）
const checkResult = reactive<CheckData.ScriptChnItem[]>([])
// 用来存放检测出现失败的测试项id。只要有一个通道检测不合格，则该检测项的id会被加入该数组。
let errorCheckItem: Array<{ scriptType: string, type: CheckData.ChnCheckResultEnum }> = []
// 用来存放检测日志
const testLogList = reactive<CheckData.LogItem[]>([{type: 'info', log: '暂无数据，等待检测开始'}])

const testStatus = toRef(props, 'testStatus')
const webMsgSend = toRef(props, 'webMsgSend')

// const resultDialogVisible = ref(false)
const scrollContainerRef = ref();
const dataCheckSingleChannelSingleTestPopupRef = ref<InstanceType<typeof dataCheckSingleChannelSingleTestPopup>>()

// 总通道数
const chnSum = computed(() => {
  let sum = 0
  deviceList.forEach((item) => {
    sum += item.chnNum
  })
  return sum
})

// 用来展示的检测结果
const checkResultView: ComputedRef<CheckData.ScriptChnViewItem[]> = computed(() => {

  let result: CheckData.ScriptChnViewItem[] = checkResult.map(item => {
    let temp: CheckData.ScriptChnViewItem = {
      scriptType: item.scriptType,
      scriptName: item.scriptName,
      devices: []
    }

    item.devices.forEach(device => {
      let tempChnBtnResult: CheckData.ButtonResult[] = []

      if (chnSum.value <= MAX_CHN_SUM) {
        for (let j = 0; j < device.chnResult.length; j++) {
          switch (device.chnResult[j]) {
            case CheckData.ChnCheckResultEnum.UNKNOWN:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.INFO, icon: 'More'})
              break;
            case CheckData.ChnCheckResultEnum.LOADING:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.LOADING, icon: 'Loading'})
              break;
            case CheckData.ChnCheckResultEnum.SUCCESS:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.SUCCESS, icon: 'CircleCheckFilled'})
              break;
            case CheckData.ChnCheckResultEnum.FAIL:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.DANGER, icon: 'Close'})
              break;
            case CheckData.ChnCheckResultEnum.TIMEOUT:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.WARNING, icon: 'Link'})
              break;
            case CheckData.ChnCheckResultEnum.ERRORDATA:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.WARNING, icon: 'WarnTriangleFilled'})
              break;
            case CheckData.ChnCheckResultEnum.NOT_PART_IN_ERROR:
              tempChnBtnResult.push({color: CheckData.ButtonColorEnum.INFO, icon: 'Minus'})
              break;
            default:
              break;
          }
        }
      }
      temp.devices.push({
        deviceId: device.deviceId,
        deviceName: device.deviceName,
        chnResult: tempChnBtnResult
      })
    })
    return temp
  })

  return result
})

watch(testStatus, function (newValue, oldValue) {
  if (newValue == 'start') {
    if (!checkStore.selectTestItems.preTest && !checkStore.selectTestItems.channelsTest) {
      ElMessage.success('初始化开始!')
      emit('update:testStatus', 'test_init')
      testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：初始化开始！`})
    } else {
      emit('update:testStatus', 'process')
    }
    startTimeCount()

    showTestLog()
    //startTimer() // todo 可移除
    startData.value = new Date();
    timeDifference.value = 0;
  }

  if (newValue == 'recheck' || newValue == 'error' || newValue == 'test_init_fail' || newValue == 'connect_timeout' || newValue == 'pause_timeout' || oldValue == 'error_flow_end') {
    stopTimeCount()
  }
})

// 次数
let count = 0

watch(webMsgSend, function (newValue, oldValue) {
  if (testStatus.value !== 'waiting') {
    if (props.stepsActive === 4) {
      if (newValue.code == 10520) {
        ElMessageBox.alert('报文解析异常！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：报文解析异常！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10521) {
        ElMessageBox.alert('程控源參数有误！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：程控源參数有误！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10522) {
        ElMessageBox.alert('测试项解析有误！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：测试项解析有误！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10523) {
        if (count === 0) {
          ElMessageBox.alert('源连接失败！', '初始化失败', {
            confirmButtonText: '确定',
            type: 'error',
          })
          testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：源连接失败！`})
          emit('update:testStatus', 'test_init_fail')
          count++
        }
      } else if (newValue.code == 10524) {
        ElMessageBox.alert('获取源控制权失败！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：获取源控制权失败！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10525) {
        ElMessageBox.alert('重置源失败！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：重置源失败！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10527) {
        ElMessageBox.alert('源未进行初始化！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：源未进行初始化！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10528) {
        ElMessageBox.alert('目标源有误(该用户已控制其他源，在关闭前无法操作新的源)！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：目标源有误(该用户已控制其他源，在关闭前无法操作新的源)！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10529) {
        ElMessageBox.alert('源状态有误，无法响应报文(例如源处于输出状态，无法响应初始化报文)！', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：源状态有误，无法响应报文(例如源处于输出状态，无法响应初始化报文)！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10550) {
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：${newValue.data}设备连接异常！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10551) {
        ElMessageBox.alert(`${newValue.data}设备触发报告异常！`, '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：${newValue.data}设备触发报告异常！`})
        emit('update:testStatus', 'test_init_fail')
      } else if (newValue.code == 10552) { //todo 10552之后还会发送消息吗？
        ElMessageBox.alert('存在已经初始化步骤,执行自动关闭,请重新发起检测', '初始化失败', {
          confirmButtonText: '确定',
          type: 'error',
        })
        testLogList.push({
          type: 'error',
          log: `${new Date().toLocaleString()}：存在已经初始化步骤,执行自动关闭,请重新发起检测！`
        })
        // emit('update:testStatus', 'recheck')
        emit('update:testStatus', 'test_init_fail')
      } else {
        switch (newValue.requestId) {
          case 'server_error':
            if (newValue.operateCode === 'server_error' && count === 0) {
              ElMessageBox.alert('服务端主动关闭连接!', '初始化失败', {
                confirmButtonText: '确定',
                type: 'error',
              })
              testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：服务端主动关闭连接！`})
              emit('update:testStatus', 'test_init_fail')
              count++
            }
            break;
          case 'device_error':
            if (newValue.operateCode === 'device_error' && count === 0) {
              ElMessageBox.alert('设备端主动关闭连接!', '初始化失败', {
                confirmButtonText: '确定',
                type: 'error',
              })
              testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：设备端主动关闭连接！`})
              emit('update:testStatus', 'test_init_fail')
              count++
            }
            break;
          case 'formal_real': // 正式测试
            switch (newValue.operateCode) {
              case "stop_timeout":
                ElMessageBox.alert(`暂停时间已过10分钟，本次检测已失效，请重新发起检测！`, '暂停时间过长', {
                  confirmButtonText: '确定',
                  type: 'error',
                })
                emit('update:testStatus', 'pause_timeout')
                break;
            }
            break;
          case 'error_flow_end':
            ElMessageBox.alert(`设备连接异常，请检查设备连接情况！`, '初始化失败', {
              confirmButtonText: '确定',
              type: 'error',
            })
            emit('update:testStatus', 'test_init_fail')
            break
          case 'socket_timeout':
            switch (newValue.operateCode) {
              case "VOLTAGE":
                // todo 超时处理 页面按钮更新
                ElMessageBox.alert('连接超时！', '连接超时', {
                  confirmButtonText: '确定',
                  type: 'error',
                })
                emit('update:testStatus', 'connect_timeout')
                break;
            }
            break;
          case 'connect':
            switch (newValue.operateCode) {
              case "Source":
                ElMessageBox.alert('源通讯失败，请检查源连接情况！', '初始化失败', {
                  confirmButtonText: '确定',
                  type: 'error',
                })
                testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：源通讯失败！`})
                break;
              case "Dev":
                ElMessageBox.alert('设备通讯失败，请检查设备连接情况！', '初始化失败', {
                  confirmButtonText: '确定',
                  type: 'error',
                })
                testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：设备通讯失败！`})
                break;
            }
            emit('update:testStatus', 'test_init_fail')
            break;
          case 'yjc_ytxjy':
            switch (newValue.operateCode) {
              case 'INIT_GATHER':
                if (newValue.code == 10200) {
                  testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：源初始化成功！`})
                  percentage.value = 1
                }
                if (newValue.code == -1) {
                  ElMessageBox.alert('源未知异常！', '初始化失败', {
                    confirmButtonText: '确定',
                    type: 'error',
                  })
                  testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：源未知异常！`})
                  emit('update:testStatus', 'test_init_fail')
                }
                break;
            }
            break;
          case 'yjc_sbtxjy':
            switch (newValue.operateCode) {
              case 'INIT_GATHER$01':
                if (newValue.code == 25001) {
                  testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：设备通讯校验成功！`})
                  percentage.value = 2
                }
                break
            }
            break;
          case 'yjc_xyjy':
            switch (newValue.operateCode) {
              case 'VERIFY_MAPPING$01':
                if (newValue.code == 25001) {
                  ElMessage.success('初始化成功!')
                  testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：协议校验成功！`})
                  timeDifference.value = +new Date().getTime() - startData.value.getTime();
                  testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：初始化成功！`})
                  percentage.value = 3

                  activeIndex = getNextActiveIndex() + 2
                  //startTimer()

                  emit('update:testStatus', 'process')
                } else if (newValue.code == 10200) {
                  let data = JSON.parse(newValue.data)
                  ElMessageBox.alert(`脚本与icd校验失败！icd名称：${data['icdType']} -> 校验项：${data['dataType']}`, '初始化失败', {
                    confirmButtonText: '确定',
                    type: 'error',
                  })
                  testLogList.push({
                    type: 'error',
                    log: `${new Date().toLocaleString()}：脚本与icd校验失败！icd名称：${data['icdType']} -> 校验项：${data['dataType']}`
                  })
                  emit('update:testStatus', 'test_init_fail')
                } else if (newValue.code == 10500) {
                  ElMessageBox.alert(`装置中未找到该icd！`, '初始化失败', {
                    confirmButtonText: '确定',
                    type: 'error',
                  })
                  testLogList.push({
                    type: 'error',
                    log: `${new Date().toLocaleString()}：装置中未找到该icd！`
                  })
                  emit('update:testStatus', 'test_init_fail')
                }
                break;
            }
            break;
          case 'preStopTest':
            if (newValue.operateCode == 'stop') {
              ElMessage.success('暂停成功')
              emit('update:testStatus', 'paused')
              pauseSuccessCallback()
            }
            break;
            // case 'Pause_Fail':
            //   ElMessage.error('暂停失败')
            //   break;
          case 'Resume_Success':
            ElMessage.success('开始继续检测')
            emit('update:testStatus', 'process')
            handleResumeTest()
            break;
            // case 'Resume_Fail':
            //   ElMessage.error('无法继续检测')
            //   break;
          case 'FREQ_Start':
            handleStartItem('FREQ', newValue.desc)
            break;
          case 'FREQ_End':
            handleEndItem('FREQ', newValue.desc, newValue.data)
            break;
          case 'V_Start':
            handleStartItem('V', newValue.desc)
            break;
          case 'V_End':
            handleEndItem('V', newValue.desc, newValue.data)
            break;
          case 'HV_Start':
            handleStartItem('HV', newValue.desc)
            break;
          case 'HV_End':
            handleEndItem('HV', newValue.desc, newValue.data)
            break;
          case 'HI_Start':
            handleStartItem('HI', newValue.desc)
            break;
          case 'HI_End':
            handleEndItem('HI', newValue.desc, newValue.data)
            break;
          case 'HP_Start':
            handleStartItem('HP', newValue.desc)
            break;
          case 'HP_End':
            handleEndItem('HP', newValue.desc, newValue.data)
            break;
          case 'HSV_Start':
            handleStartItem('HSV', newValue.desc)
            break;
          case 'HSV_End':
            handleEndItem('HSV', newValue.desc, newValue.data)
            break;
          case 'HSI_Start':
            handleStartItem('HSI', newValue.desc)
            break;
          case 'HSI_End':
            handleEndItem('HSI', newValue.desc, newValue.data)
            break;
          case 'VOLTAGE_Start':
            handleStartItem('VOLTAGE', newValue.desc)
            break;
          case 'VOLTAGE_End':
            handleEndItem('VOLTAGE', newValue.desc, newValue.data)
            break;
          case 'I_Start':
            handleStartItem('I', newValue.desc)
            break;
          case 'I_End':
            handleEndItem('I', newValue.desc, newValue.data)
            break;
          case 'IMBV_Start':
            handleStartItem('IMBV', newValue.desc)
            break;
          case 'IMBV_End':
            handleEndItem('IMBV', newValue.desc, newValue.data)
            break;
          case 'IMBA_Start':
            handleStartItem('IMBA', newValue.desc)
            break;
          case 'IMBA_End':
            handleEndItem('IMBA', newValue.desc, newValue.data)
            break;
          case 'F_Start':
            handleStartItem('F', newValue.desc)
            break;
          case 'F_End':
            handleEndItem('F', newValue.desc, newValue.data)
            break;
          case 'Quit':
            console.log('检测结束')
            break;
        }
      }
    }
  }
}, {deep: true})

const handleStartItem = (code: string, desc: string | undefined) => {
  if (desc === undefined) {
    activeIndex = getActiveIndex(code)
    updateCheckResultView(code, true)
    updateLog(true)
  } else {
    // if (desc.length > 150) {
    //   desc = desc.substring(0, 150) + '...'
    // }
    testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：${desc}准确度检测：开始`})
  }
}

const handleEndItem = (code: string, desc: string | undefined, devices: CheckData.DeviceCheckResult[] = []) => {
  if (desc === undefined) {
    updatePercentage()
    updateCheckResultView(code, false, devices)
    updateLog(false)
    if (testStatus.value != 'paused') {
      activeIndex = getNextActiveIndex(code)
      //startTimer()
    }
  } else {
    let result = getResult(devices)
    // if (desc.length > 150) {
    //   desc = desc.substring(0, 150) + '...'
    // }
    if (result === 1) {
      testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：${desc}检测结束：符合`})
    }
    if (result === 2) {
      testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：${desc}检测结束：不符合`})
    }
    if (result === 4) {
      testLogList.push({type: 'warning', log: `${new Date().toLocaleString()}：${desc}检测结束：数据异常`})
    }
  }
}

// 更新进度条
const updatePercentage = async () => {
  if (activeIndex < checkTotal) {
    percentage.value = Math.trunc(activeIndex / checkTotal * 100);
  } else {
    percentage.value = 100;
    emit('update:testStatus', 'success')

    let {data: autoGenerate} = await getAutoGenerate()
    if (autoGenerate == 1) {
      //调用自动生成报告接口
      let devIdList = checkStore.devices.map(item => {
        return item.deviceId
      })

      await generateDevReport({
        'planId': checkStore.plan.id,
        'devIdList': devIdList,
        'scriptId': checkStore.plan.scriptId,
        'planCode': checkStore.plan.code + ''
      })
    }
    ElMessageBox.alert('检测全部结束,你可以停留在此页面查看检测结果，或返回首页进行复检、报告生成和归档等操作', '检测完成', {
      confirmButtonText: '确定',
    })
    // 关闭WebSocket连接
    emit('closeWebSocket')
    //clear();
  }
}



onBeforeMount(async () => {
  await initScriptData()
  initDeviceList()
  initCheckResult()

})

const showTestLog = () => {
  drawer.value = true
}

// 初始化检测脚本数据
const initScriptData = async () => {

  let response: any = await getBigTestItem({reCheckType: checkStore.reCheckType, planId: checkStore.plan.id, devIds: checkStore.devices.map(item => item.deviceId)})

  let temp = response.data.map((item: any) => {
    return {
      ...item,
      scriptName: item.scriptName
    }
  })

  scriptData.push(...temp)
  checkTotal = scriptData.length
}
// 初始化设备列表
const initDeviceList = () => {
  Object.assign(deviceList, checkStore.devices)
}

// 初始化检测结果 （详细到通道）
const initCheckResult = () => {
  let result: CheckData.ScriptChnItem[] = []
  scriptData.forEach(item => {
    // 处理当前节点的数据
    let temp: CheckData.ScriptChnItem = {
      scriptType: item.id,
      scriptName: item.scriptName,
      devices: []
    }
    for (let i = 0; i < deviceList?.length; i++) {
      let tempChnResult: CheckData.ChnCheckResultEnum[] = []
      for (let j = 0; j < deviceList[i].chnNum; j++) {
        tempChnResult.push(CheckData.ChnCheckResultEnum.UNKNOWN)
      }
      temp.devices.push({
        deviceId: deviceList[i].deviceId,
        deviceName: deviceList[i].deviceName,
        chnResult: tempChnResult
      })
    }
    result.push(temp)
  })
  Object.assign(checkResult, result)
}

// 更新检测结果（详细到通道）
const updateCheckResult = (data: CheckData.ScriptChnItem) => {
  const {scriptType} = {...data}

  checkResult.forEach(item => {
    if (item.scriptType == scriptType) {
      for (let i = 0; i < item.devices.length; i++) {
        let targetDevice = data.devices.find(dev => dev.deviceId === item.devices[i].deviceId)
        if (targetDevice !== undefined) {
          item.devices[i].chnResult = [...targetDevice.chnResult]
        }
      }
    }
  })
}

const scrollToBottom = () => {
  if (scrollContainerRef.value) {
    scrollContainerRef.value.scrollTop = scrollContainerRef.value.scrollHeight + 70;
  }
};

function getRandomInt(max: number): number {
  return Math.floor(Math.random() * max)
}


function getTimeDifference(timeDifference: number): string {
  // 将时间差转换为天、小时、分钟、秒
  const millisecondsPerDay = 1000 * 60 * 60 * 24;
  const millisecondsPerHour = 1000 * 60 * 60;
  const millisecondsPerMinute = 1000 * 60;
  const millisecondsPerSecond = 1000;

  const days = Math.floor(timeDifference / millisecondsPerDay);
  const hours = Math.floor((timeDifference % millisecondsPerDay) / millisecondsPerHour);
  const minutes = Math.floor((timeDifference % millisecondsPerHour) / millisecondsPerMinute);
  const seconds = Math.floor((timeDifference % millisecondsPerMinute) / millisecondsPerSecond);
  if (days > 0) {
    return `: ${days} 天, ${hours} 小时, ${minutes} 分钟, ${seconds} 秒`
  } else if (hours > 0) {
    return `: ${hours} 小时, ${minutes} 分钟, ${seconds} 秒`
  } else {
    return `: ${minutes} 分钟, ${seconds} 秒`
  }
}

watch(testLogList, () => {
  scrollToBottom();
}, {deep: true})

// 更新日志
const updateLog = (isStart: boolean) => {
  const currentTime = ref(new Date().toLocaleString());
  let timeDifferenceItem = 0

  if (activeIndex === 1 && isStart) {
    // timeDifference.value = 0;
    //testLogList.length = 0; // 清空数组
  }
  // debugger
  if (activeIndex <= checkTotal) {
    if (isStart) {
      startData.value = new Date();
      testLogList.push({
        type: 'info',
        log: currentTime.value + ` ：${scriptData[activeIndex - 1].scriptName}准确度检测：开始`,
      })
    } else {
      endData.value = new Date();
      timeDifferenceItem = endData.value.getTime() - startData.value.getTime();
      timeDifference.value += timeDifferenceItem

      let errorItem = getErrorCheckItem(scriptData[activeIndex - 1].id)
      switch (errorItem?.type) {
        case CheckData.ChnCheckResultEnum.SUCCESS:
          testLogList.push({
            type: 'info',
            log: currentTime.value + ` ：${scriptData[activeIndex - 1].scriptName}准确度检测结束：符合，用时` + getTimeDifference(timeDifferenceItem),
          })
          break
        case CheckData.ChnCheckResultEnum.FAIL:
          testLogList.push({
            type: 'error',
            log: currentTime.value + ` ：${scriptData[activeIndex - 1].scriptName}准确度检测结束：不符合，用时` + getTimeDifference(timeDifferenceItem),
          })
          break
        case CheckData.ChnCheckResultEnum.TIMEOUT:
          testLogList.push({
            type: 'warning',
            log: currentTime.value + ` ：${scriptData[activeIndex - 1].scriptName}准确度检测结束：连接超时，用时` + getTimeDifference(timeDifferenceItem),
          })
          break
        case CheckData.ChnCheckResultEnum.ERRORDATA:
          testLogList.push({
            type: 'warning',
            log: currentTime.value + ` ：${scriptData[activeIndex - 1].scriptName}准确度检测结束：数据异常，用时` + getTimeDifference(timeDifferenceItem),
          })
          break
      }

      timeView.value = secondToTime(timeDifference.value / 1000)
      if (activeIndex === checkTotal) {
        testLogList.push({
          type: 'info',
          log: currentTime.value + ' ：检测结束，总用时' + getTimeDifference(timeDifference.value),
        })
        stopTimeCount()
      }
    }
  }
}

const setErrorCheckItem = (scriptType: string, devices: CheckData.DeviceCheckResult[]) => {
  let type = 1
  let tempChnResult: CheckData.ChnCheckResultEnum[] = []
  for (let i = 0; i < devices.length; i++) {
    tempChnResult.push(...devices[i].chnResult)
  }

  if (tempChnResult.some(item => item === CheckData.ChnCheckResultEnum.ERRORDATA)) {
    type = CheckData.ChnCheckResultEnum.ERRORDATA
  }
  if (tempChnResult.some(item => item === CheckData.ChnCheckResultEnum.FAIL)) {
    type = CheckData.ChnCheckResultEnum.FAIL
  }
  if (tempChnResult.some(item => item === CheckData.ChnCheckResultEnum.TIMEOUT)) {
    type = CheckData.ChnCheckResultEnum.TIMEOUT
    for (let i = 0; i < devices.length; i++) {
      if (devices[i].chnResult.some(item => item === CheckData.ChnCheckResultEnum.TIMEOUT)) {
        testLogList.push({
          type: 'warning',
          log: `${new Date().toLocaleString()} ：${devices[i].deviceName}连接超时`,
        })
        ElMessageBox.alert('连接超时！', '连接超时', {
          confirmButtonText: '确定',
          type: 'error',
        })
        emit('update:testStatus', 'connect_timeout')
      }
    }
  }

  errorCheckItem.push({scriptType, type: type})
}

//判断该检测项（例如 频率准确度检测）是否全部合格（所有设备所有通道所有子检测项目全部合格为合格，否则为不合格）
function getErrorCheckItem(scriptType: string) {
  let results = errorCheckItem.filter((item) => item.scriptType === scriptType)
  if (results.length > 0) {
    return results[0]
  } else {
    return null
  }
}

const updateCheckResultView = (scriptCode: string, isStart: boolean, devices: CheckData.DeviceCheckResult[] = []) => {
  let scriptType = scriptData.filter(item => item.code === scriptCode)[0]?.id
  let temp = null
  if (isStart) {
    temp = getLoadingResult(scriptType)
  } else {
    setErrorCheckItem(scriptType, devices)
    temp = {
      scriptType,
      devices
    }
  }
  updateCheckResult(temp)
};

// 获取loading状态的结果
const getLoadingResult = (scriptType: string) => {
  let devices = []

  devices = deviceList.map(item => {

    let tempChnResult: CheckData.ChnCheckResultEnum[] = []
    for (let i = 0; i < item.chnNum; i++) {
      tempChnResult.push(CheckData.ChnCheckResultEnum.LOADING)
    }

    return {
      deviceId: item.deviceId,
      deviceName: item.deviceName,
      chnResult: tempChnResult,
    }
  })

  let tempScriptChnItem: CheckData.ScriptChnItem = {
    scriptType,
    devices,
  }

  return tempScriptChnItem
}

// 模拟检测 todo 可移除
const getCheckResult = (scriptType: string) => {
  // debugger
  let devices = []

  devices = deviceList.map(item => {
    let tempChnResult: CheckData.ChnCheckResultEnum[] = []
    for (let i = 0; i < item.chnNum; i++) {
      tempChnResult.push(CheckData.ChnCheckResultEnum.SUCCESS)
    }
    let randomNum = getRandomInt(item.chnNum * 2)
    if (randomNum < item.chnNum && activeIndex >= 4 && activeIndex <= 8) {
      tempChnResult[randomNum] = CheckData.ChnCheckResultEnum.FAIL
      errorCheckItem.push({scriptType, type: CheckData.ChnCheckResultEnum.FAIL})
    }
    // }

    return {
      deviceId: item.deviceId,
      deviceName: item.deviceName,
      chnResult: tempChnResult,
    }
  })
  // }

  let tempScriptChnItem: CheckData.ScriptChnItem = {
    scriptType,
    devices,
  }

  return tempScriptChnItem
}

const getResult = (devices: CheckData.DeviceCheckResult[] = []) => {
  let type = 1
  let tempChnResult: CheckData.ChnCheckResultEnum[] = []
  for (let i = 0; i < devices.length; i++) {
    tempChnResult.push(...devices[i].chnResult)
  }

  if (tempChnResult.some(item => item === CheckData.ChnCheckResultEnum.ERRORDATA)) {
    type = CheckData.ChnCheckResultEnum.ERRORDATA
  }
  if (tempChnResult.some(item => item === CheckData.ChnCheckResultEnum.FAIL)) {
    type = CheckData.ChnCheckResultEnum.FAIL
  }
  return type
}


// 点击查看（设备）通道检测详情。参数1：设备信息，参数2：通道号，-1：代表查看全部通道
const handleClick = (item: any, chnNum: number, scriptType: string) => {
  let checkResultItem = checkResult.find(obj => obj.scriptType === scriptType)
  let flag = -1
  if (checkResultItem) {
    let device = checkResultItem.devices.find(obj => obj.deviceId === item.deviceId)
    if (device) {
      let chnResult = device.chnResult
      if (chnNum === -1) {
        if (chnResult.findIndex(obj => obj === CheckData.ChnCheckResultEnum.TIMEOUT) !== -1) {
          flag = 0
        }
        if (chnResult.findIndex(obj => obj === CheckData.ChnCheckResultEnum.ERRORDATA) !== -1) {
          flag = 1
        }
      } else {
        if (chnResult[chnNum - 1] === CheckData.ChnCheckResultEnum.TIMEOUT) {
          flag = 0
        }
        if (chnResult[chnNum - 1] === CheckData.ChnCheckResultEnum.ERRORDATA) {
          flag = 1
        }
      }
    }
  }

  if (flag === 0) {
    ElMessageBox.alert('连接超时，请检查设备通讯是否正常', '连接超时', {
      confirmButtonText: '确定',
      type: 'warning',
    })
  }
  if (flag === -1 || flag === 1) {
    checkStore.setShowDetailType(2)
    dataCheckSingleChannelSingleTestPopupRef.value?.open(item.deviceId, chnNum + '', scriptType);
  }
};

// todo 可移除
const startTimer = () => {
  console.log('开始检测第' + activeIndex + '项')
  switch (activeIndex) {
    case 0:
      setTimeout(() => {
        emit('update:webMsgSend', {
          requestId: 'yjc_ytxjy',
          operateCode: "INIT_GATHER",
          code: 10200
        })
      }, 2000)
      setTimeout(() => {
        emit('update:webMsgSend', {
          requestId: 'yjc_sbtxjy',
          operateCode: "INIT_GATHER$01",
          code: 25001
        })
      }, 4000);
      setTimeout(() => {
        emit('update:webMsgSend', {
          requestId: 'yjc_xyjy',
          operateCode: "INIT_GATHER$03",
          code: 25001
        })
      }, 6000)
      break;
    case 1:
      todoItem('V')
      break;
    case 2:
      todoItem('I')
      break;
    case 3:
      todoItem('IMBV')
      break;
    case 4:
      todoItem('FREQ')
      break;
    case 5:
      todoItem('HV')
      break;
    case 6:
      todoItem('HI')
      break;
    case 7:
      todoItem('HSV')
      break;
    case 8:
      todoItem('HSI')
      break;
    case 9:
      emit('update:webMsgSend', {
        requestId: 'Quit'
      })
      break;
  }
};
const handlePause = () => {
  //emit('sendPause')
  testLogList.push({type: 'error', log: `${new Date().toLocaleString()}：当前测试小项正在执行中，将在该小项执行结束后暂停...`})
}

const pauseSuccessCallback = () => {
  endData.value = new Date();
  let diffTime = endData.value.getTime() - startData.value.getTime();
  timeDifference.value += diffTime

  testLogList.push({
    type: 'info',
    log: `${new Date().toLocaleString()}：暂停检测`,
  })
  stopTimeCount()
  console.log('暂停中')
};

const todoItem = (code: string) => {
  emit('update:webMsgSend', {
    requestId: `${code}_Start`
  })
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_Start`,
        desc: '输入：频率t=42.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° '
      })
    }
  }, 1000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_End`,
        desc: '输入：频率t=42.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° ',
        data: [{
          chnResult: [1, 1, 1, 1],
          deviceId: "e90c09c0905248ad912e19e17a8672aa",
          deviceName: "250226001"
        }]
      })
    }
  }, 2000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_Start`,
        desc: '输入：频率t=45.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° '
      })
    }
  }, 3000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_End`,
        desc: '输入：频率t=45.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° ',
        data: [{
          chnResult: [1, 1, 1, 1],
          deviceId: "e90c09c0905248ad912e19e17a8672aa",
          deviceName: "250226001"
        }]
      })
    }
  }, 5000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_Start`,
        desc: '输入：频率t=50.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° '
      })
    }
  }, 6000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_End`,
        desc: '输入：频率t=50.5Hz Ua=57.74%Un,相角=0.0° Ub=57.74%Un,相角=-120.0° Uc=57.74%Un,相角=120.0° Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0°,Ia=0.0%In,相角=0.0° Ib=0.0%In,相角=0.0° Ic=0.0%In,相角=0.0° ',
        data: [{
          chnResult: [1, 1, 1, 1],
          deviceId: "e90c09c0905248ad912e19e17a8672aa",
          deviceName: "250226001"
        }]
      })
    }
  }, 8000)
  setTimeout(() => {
    if (testStatus.value !== 'paused') {
      emit('update:webMsgSend', {
        requestId: `${code}_End`,
        data: [{
          chnResult: [1, 2, 1, 1],
          deviceId: "e90c09c0905248ad912e19e17a8672aa",
          deviceName: "250226001"
        }]
      })
    }
  }, 9000)
}

const handleResumeTest = () => {
  //activeIndex++
  startData.value = new Date();
  testLogList.push({type: 'info', log: `${new Date().toLocaleString()}：开始重新检测！`})
  //startTimer()
  resumeTimeCount()
  console.log('开始继续检测')
};

// 获取当前执行的大测试项序号
const getActiveIndex = (code: string): number => {
  for (let i = 0; i < scriptData.length; i++) {
    if (scriptData[i].code === code) {
      return i + 1
    }
  }
  return -1
}

// 获取当前执行的大测试项序 的 下一个大测试项序号
const getNextActiveIndex = (code: string = ''): number => {
  if (code === '') {
    return -1
  }
  for (let i = 0; i < scriptData.length; i++) {
    if (scriptData[i].code === code) {
      return i + 2
    }
  }
  return -1
}
const startTimeCount = () => {
  if (!timer) {
    timer = setInterval(() => {
      timeCount.value = timeCount.value + 1
      timeView.value = secondToTime(timeCount.value)
    }, 1000)
  }
}

const stopTimeCount = () => {
  if (timer) {
    clearInterval(timer)
  }
}

const resumeTimeCount = () => {
  timer = setInterval(() => {
    timeCount.value = timeCount.value + 1
    timeView.value = secondToTime(timeCount.value)
  }, 1000)
}


const secondToTime = (second: number) => {
  //将秒数转换成时分秒
  let h: string | number = Math.floor(second / 3600)
  let m: string | number = Math.floor((second - h * 3600) / 60)
  let s: string | number = Math.floor(second % 60);

  h = h < 10 ? '0' + h : h;
  m = m < 10 ? '0' + m : m;
  s = s < 10 ? '0' + s : s;
  return h + ':' + m + ':' + s;
}

onBeforeUnmount(() => {

  if (timer) {
    clearInterval(timer)
  }
})

defineExpose({
  handlePause
})
</script>

<style scoped lang="scss">

:deep(.el-table .header-row) {
  background-color: #f5f7fa;
}

:deep(.el-table .warning-row) {
  color: red;
}



.el-table .success-row {
  --el-table-tr-bg-color: var(--el-color-success-light-9);
}

.dialog {
  display: flex;
  flex-direction: column;
  overflow-y: hidden;
  overflow-x: hidden;
}

.dialog-title {

  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-right: 10px;
  margin-bottom: 10px;

  .timeView {
    display: flex;
    align-items: center;
    color: #91cc75;
    width: 28%;
    margin-right: 0px;
    text-align: left;
    font-size: 26px;
    font-weight: bold;
  }
}

.dialog-content {
  max-height: 450px;
  overflow-y: hidden;
}

:deep(.el-collapse-item__header) {
  height: 30px;
}

.dialog-log {
  height: 50px;
  overflow-y: hidden;

  p {
    margin: 5px 0;
    font-size: 14px;
  }
}

.drawer-container {
  :deep(header.el-drawer__header) {
    color: #fff !important;
    background-color: var(--el-color-primary) !important;

    .el-drawer__close-btn svg:hover {
      color: #ccc !important;
    }

    .el-drawer__title {
      color: #fff !important;
    }
  }
}

.loading-box {
  animation: loading 1.5s linear infinite;
}

@keyframes loading {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

</style>

<style lang="scss" scoped>
:deep(.el-button--small) {
  height: 20px !important;
  width: 20px !important;
}

:deep(.el-table--default  td ) {
  padding: 5px 0 !important;
}


</style>
