<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>
            {{ checkResultView }}
            <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 checkStore.chnNumList"
                                :key="`${item.deviceId}${chnItem}`"
                                :label="'通道' + chnItem.label"
                                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>

        <CompareDataCheckSingleChannelSingleTestPopup ref="dataCheckSingleChannelSingleTestPopupRef" />
    </div>
</template>
<script lang="tsx" setup name="test">
import { InfoFilled, Loading } from '@element-plus/icons-vue'
import CompareDataCheckSingleChannelSingleTestPopup from './compareDataCheckSingleChannelSingleTestPopup.vue'
import { computed, ComputedRef, onBeforeMount, reactive, ref, toRef, watch, onMounted } 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'
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store

import { useDictStore } from '@/stores/modules/dict'

const checkStore = useCheckStore()
const modeStore = useModeStore()
const dictStore = useDictStore()
// 最大通道数
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 scrollContainerRef = ref()
const dataCheckSingleChannelSingleTestPopupRef =
    ref<InstanceType<typeof CompareDataCheckSingleChannelSingleTestPopup>>()

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

// 用来展示的检测结果
const checkResultView: ComputedRef<CheckData.ScriptChnViewItem[]> = computed(() => {
    console.log('🚀 ~ tem.devices:', checkResult)

    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) {
    console.log('🚀 ~ newValue:', newValue)
    if (newValue == 'start' || newValue == 'waiting') {
        if (!checkStore.selectTestItems.preTest && !checkStore.selectTestItems.channelsTest) {
            ElMessage.success('初始化开始!')
            emit('update:testStatus', 'test_init')
            if (checkStore.selectTestItems.test && checkStore.selectTestItems.preTest) {
                testLogList.push({ type: 'info', log: `${new Date().toLocaleString()}：初始化开始！` })
            }
        } else {
            emit('update:testStatus', 'process')
        }
        // 开始计时
        startTimeCount()
        showTestLog()
        //startTimer() // todo 可移除
        startData.value = new Date()
        timeDifference.value = 0
    } else if (newValue == 'error') {
        stopTimeCount()
    }
})

// 次数
let count = 0

watch(
    webMsgSend,
    function (newValue, oldValue) {
        if (testStatus.value == 'test_init') {
            // 正式检测
        } else {
            // 预监测 正式检测
            if (newValue.requestId == 'formal_real') {
                switch (newValue.code) {
                    case 25001:
                        let result: CheckData.ScriptChnItem[] = []
                        scriptData.forEach(item => {
                            // 处理当前节点的数据
                            let temp: CheckData.ScriptChnItem = {
                                scriptType: item.id,
                                scriptName: item.scriptName,
                                devices: []
                            }
                           let message=JSON.parse(newValue.data)

                            for (let i = 0; i < message?.length; i++) {
                          
                                temp.devices.push({
                                    deviceId: message[i].deviceId,
                                    deviceName: message[i].deviceName,
                                    chnResult: message[i].chnResult
                                })
                            }
                            result.push(temp)
                        })
                        console.log("🚀 ~ result:", result)

                        Object.assign(checkResult, result)

                        stopTimeCount()
                        break
                    default:
                        if (newValue.code != 10201) {
                            testLogList.push({
                                type: newValue.code == 10200 ? 'info' : 'error',
                                log: `${new Date().toLocaleString()}：` + newValue.data
                            })
                            if (newValue.code == 25003) {
                                stopTimeCount()
                            }
                            updatePercentage()
                        }

                        break
                }
            }
        }
    },
    { deep: true }
)

// 更新进度条
const updatePercentage = async () => {
    if (testLogList.length - 1 < checkStore.chnNumList.length) {
        percentage.value = Math.trunc(((testLogList.length - 1) / checkStore.chnNumList.length) * 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 + ''
            // })
        }
        stopTimeCount()
        ElMessageBox.alert(
            '检测全部结束,你可以停留在此页面查看检测结果，或返回首页进行复检、报告生成和归档等操作',
            '检测完成',
            {
                confirmButtonText: '确定'
            }
        )
        // 关闭WebSocket连接
        emit('closeWebSocket')
        //clear();
    }
}
// ========== 时间计数器管理函数 ==========
// 开始计时
const startTimeCount = () => {
    if (!timer) {
        timer = setInterval(() => {
            timeCount.value = timeCount.value + 1
            timeView.value = secondToTime(timeCount.value)
        }, 1000)
    }
}

// 停止计时
const stopTimeCount = () => {
    if (timer) {
        clearInterval(timer)
        timer = null
    }
}

// 将秒数转换为 HH:MM:SS 格式
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
}

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

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

// 初始化检测脚本数据
const initScriptData = async () => {
    const pattern = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
    let response: any = await getBigTestItem({
        reCheckType: checkStore.reCheckType,
        planId: checkStore.plan.id,
        devIds: checkStore.devices.map(item => item.deviceId),
        patternId: pattern
    })

    // 格式化脚本数据
    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 < checkStore.chnNumList.length; 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) => {
    console.log('🚀 ~ updateCheckResult ~ data:', data)
    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
    }
}

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

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 })
}

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
}

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)
    console.log('handleTest', item.deviceId, chnNum, scriptType)
    dataCheckSingleChannelSingleTestPopupRef.value?.open(item.deviceId, chnNum + '', scriptType)
    //}
}

const handlePause = () => {
    //emit('sendPause')
    testLogList.push({
        type: 'error',
        log: `${new Date().toLocaleString()}：当前测试小项正在执行中，将在该小项执行结束后暂停...`
    })
}
const initializeParameters = () => {
    percentage.value = 0
    testLogList.splice(0, testLogList.length, { type: 'info', log: '暂无数据，等待检测开始' })
}

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()}：暂停检测`
    })

    console.log('暂停中')
}

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

defineExpose({
    initializeParameters,
    handlePause,
    showTestLog,
    startTimeCount
})
</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>
