<template>
    <div class="page-container">
        <div class="left">
            <div class="header">
                <div>任务队列</div>
                <el-button type="primary" @click="addTask">添加任务</el-button>
            </div>
            <div class="taskList-container">
                <div class="task-item" v-for="task in runTaskList">
                    <div class="task-content">
                        <div class="task-title">{{ task.taskName }}</div>
                        <div class="task-actions">
                            <SvgIcon class="icon" v-if="task.status == '1'" name="pause" :size="24" color="#FFB300"
                                @click="pauseTask(task)" />
                            <SvgIcon class="icon" v-if="task.status == '3' || task.status == '5'" name="start"
                                :size="24" color="#00FF88" @click="startTask(task)" />
                            <SvgIcon class="icon" v-if="task.status != '5'" name="stop" :size="24" color="#d81e06"
                                @click="stopTask(task)" />
                            <SvgIcon class="icon" v-if="task.status == '5'" name="remove" :size="24" color="#FFB300"
                                @click="removeTask(task)" />
                        </div>
                    </div>
                    <div class="robot">手机：{{ task.phoneName }}</div>
                    <div class="robot">车辆：{{ task.vehicleName }}</div>
                    <el-progress :color="customColorMethod"
                        :percentage="parseFloat(taskRunningInfo[task.id]?.progress?.toFixed(2)) || 0" />
                </div>
            </div>
        </div>
        <div class="right" ref="topContainerRef">
            <div class="header">
                <div class="label" :class="{ active: activePanel === 'current' }" @click="activePanel = 'current'">当前任务
                </div>
                <div class="label" :class="{ active: activePanel === 'history' }" @click="activePanel = 'history'">历史记录
                </div>
            </div>
            <div class="context-container">
                <div v-if="activePanel === 'current'">
                    <!-- 当前任务内容 -->
                    <div class="task" v-for="runTask in runingTaskList">
                        <div class="task-header">
                            <div class="header-container">
                                <div class="task-info">
                                    <div class="title">{{ runTask.taskName }}</div>
                                    <div class="id">ID: {{ runTask.taskId }}</div>
                                </div>
                                <div class="robot">
                                    <div>手机：{{ runTask.phoneName }}</div>
                                    <div>车辆：{{ runTask.vehicleName }}</div>
                                    <div>开始时间: {{ formatDate(runTask.startTime) }}</div>
                                </div>
                            </div>
                            <div>
                                <el-tag :type="runTask.status === '3' ? 'primary' : 'warning'">
                                    {{ taskStatusMap[runTask.status] || '未知状态' }}
                                </el-tag>
                            </div>
                        </div>

                        <div class="progress-label">执行进度</div>
                        <el-progress :color="customColorMethod"
                            :percentage="parseFloat(taskRunningInfo[runTask.id]?.progress?.toFixed(2)) || 0" />
                        <taskSteps :list="pointList_runningTask[runTask.taskId]"
                            :activeStep="taskRunningInfo[runTask.id]?.activeStep || 0" />
                        <div class="run-log-container">
                            <div>执行日志</div>
                            <taskLog :list="taskLogList[runTask.id]" />
                        </div>
                    </div>
                </div>
                <div v-else-if="activePanel === 'history'">
                    <div :style="containerHeight">
                        <el-table v-loading="loading" height="100%" :data="tableDataList">
                            <el-table-column align="center" label="任务名称" prop="taskName" show-overflow-tooltip />
                            <el-table-column align="center" label="任务状态" prop="status">
                                <template #default="scope">
                                    <el-tag :type="scope.row.status === '0' ? 'success' : 'danger'">
                                        {{ taskStatusMap[scope.row.status] || '未知状态' }}
                                    </el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column align="center" label="任务类型" prop="taskType">
                                <template #default="scope">
                                    <el-tag :type="scope.row.taskType === '1' ? 'primary' : 'success'">
                                        {{ scope.row.taskType === '1' ? '巡检任务' : '讲解任务' }}
                                    </el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column align="center" label="机器人" prop="robotName" show-overflow-tooltip />
                            <el-table-column align="center" label="开始时间" prop="startTime">
                                <template #default="scope">
                                    {{ formatDate(scope.row.startTime) }}
                                </template>
                            </el-table-column>
                            <el-table-column align="center" label="结束时间" prop="endTime">
                                <template #default="scope">
                                    {{ formatDate(scope.row.endTime) }}
                                </template>
                            </el-table-column>
                            <el-table-column align="center" class-name="small-padding fixed-width" label="操作"
                                width="260">
                                <template #default="scope">
                                    <el-button icon="Edit" link type="primary" @click="handleOpenLog(scope.row)">
                                        日志
                                    </el-button>
                                </template>
                            </el-table-column>
                        </el-table>

                        <pagination v-show="total > 0" v-model:limit="queryParams.pageSize"
                            v-model:page="queryParams.pageNum" :total="total" @pagination="getHistoryList" />
                    </div>
                </div>
            </div>
        </div>


        <!-- 添加任务弹窗 -->
        <el-dialog title="添加任务" v-model="open" width="500px" append-to-body>
            <el-form ref="runTaskRef" :model="form" :rules="rules" label-width="100px">
                <el-form-item label="选择任务" prop="taskId">
                    <el-select v-model="form.taskId" placeholder="请选择任务" clearable style="width: 100%">
                        <el-option v-for="task in taskList" :key="task.id" :label="task.taskName" :value="task.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="选择手机" prop="phoneId">
                    <el-select v-model="form.phoneId" placeholder="请选择手机" clearable style="width: 100%">
                        <el-option v-for="phone in phoneList" :key="phone.id" :label="phone.phoneName"
                            :value="phone.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="选择车辆" prop="vehicleId">
                    <el-select v-model="form.vehicleId" placeholder="请选择车辆" clearable style="width: 100%">
                        <el-option v-for="vehicle in carList" :key="vehicle.id" :label="vehicle.vehicleName"
                            :value="vehicle.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input type="textarea" v-model="form.remark" />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="confirmTaskDialog">确 定</el-button>
                    <el-button @click="cancelTaskDialog">取 消</el-button>
                </div>
            </template>
        </el-dialog>

        <el-dialog title="任务执行日志" v-model="logDialogVisible" width="500px" append-to-body>
            <taskLog :list="logDialogData" :height="300" />
        </el-dialog>
    </div>
</template>
<script setup>
import SvgIcon from "@/components/SvgIcon";
import taskSteps from "./task-steps.vue";
import taskLog from "./task-log.vue";
import { useContainerHeight } from "@/hooks/tableHeight";
import { getTaskList, getTestCaseByTaskId } from "@/api/intelligenceTest/taskManage";
import { getPhoneList } from "@/api/intelligenceTest/mobilePhone";
import { getVehicleList } from "@/api/intelligenceTest/car";
import { onMounted, onUnmounted } from "vue";
import { 
    addTaskinstance,
    getTaskinstanceList,
    startTaskinstance,
    pauseTaskinstance,
    stopTaskinstance,
    resumeTaskinstance,
    deleteTaskinstance,
    getTaskLogListApi
} from "@/api/intelligenceTest/runningTask";
import { ElMessage, ElMessageBox } from "element-plus";
import { formatDate } from "@/utils/index";
import { debounce } from 'lodash'; // 引入 lodash 的防抖函数

const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const socket = inject('ws');

const taskStatusMap = {
    '0': '已完成',
    '1': '执行中',
    '2': '失败',
    '3': '已暂停',
    '4': '已终止',
    '5': '未执行',
}

const form = reactive({
    taskId: null,
});

const rules = reactive({
    taskId: [{ required: true, message: '请选择任务', trigger: 'change' }],
    phoneId: [{ required: true, message: '请选择手机', trigger: 'change' }],
    vehicleId: [{ required: true, message: '请选择车辆', trigger: 'change' }],
});

const taskList = ref([]);
const phoneList = ref([]);

const runTaskList = ref([]);

const getTaskData = () => {
    getTaskList({
        pageNum: 1,
        pageSize: 10000,
    }).then((res) => {
        taskList.value = res.rows;
    })
}

const getPhoneData = (mapId = null) => {
    getPhoneList({
        pageNum: 1,
        pageSize: 10000
    }).then((res) => {
        phoneList.value = res.rows;
    })
}

const carList = ref([])

const getCarData = (mapId = null) => {
    getVehicleList({
        pageNum: 1,
        pageSize: 10000
    }).then((res) => {
        carList.value = res.rows;
    })
}

const open = ref(false);

const addTask = () => {
    open.value = true;
}

const runTaskRef = ref();
/**
 * 确定添加执行任务
 */
const confirmTaskDialog = () => {
    runTaskRef.value.validate((valid) => {
        if (valid) {
            addTaskinstance(form).then(() => {
                ElMessage.success("任务添加成功");
                getList();
                open.value = false;
                runTaskRef.value.resetFields();
            }).catch(() => {
                ElMessage.error("任务添加失败");
            })
        }
    });
}

const cancelTaskDialog = () => {
    open.value = false;
}


const runingTaskList = ref([])
/**
 * 获取任务队列
 */
const getList = () => {
    getTaskinstanceList({
        statusList: ['1', '3', '5'],
    }).then((res) => {
        if (res.code === 200) {
            runTaskList.value = res.rows;
            runingTaskList.value = res.rows.filter(item => item.status !== '5')
            for (let i = 0; i < runTaskList.value.length; i++) {
                getCaseByTaskId(runTaskList.value[i].taskId)
                getTaskLogList(runTaskList.value[i].id)
            }
        }
    })
}

const pointList_runningTask = ref({})
/**
 * 获取正在执行任务的用例列表
 * @param taskId 
 */
const getCaseByTaskId = async (taskId) => {
    const res = await getTestCaseByTaskId(taskId)
    if (res.code === 200) {
        pointList_runningTask.value[taskId] = res.data
    }
}

const taskLogList = ref({})

/**
 * 获取正在执行任务的执行日志
 * @param taskInstanceId 
 */
const getTaskLogList = async (taskInstanceId) => {
    const res = await getTaskLogListApi({ taskInstanceId })
    if (res.code === 200) {
        taskLogList.value[taskInstanceId] = res.rows
    }
}

/**
 * 自定义进度条值不同区间所显示的颜色
 * @param percentage 
 */
const customColorMethod = (percentage) => {
    if (percentage < 30) {
        return '#6f7ad3'
    }
    if (percentage < 70) {
        return '#1989fa'
    }
    return '#67c23a'
}

const activePanel = ref('current');

const tableDataList = ref([]);
const loading = ref(false);
const total = ref(0);

const queryParams = reactive({
    pageNum: 1,
    pageSize: 10,
});

/**
 * 开始执行任务
 * @param task 
 */
const startTask = async (task) => {
    if (task.status === '3') {
        let res = await resumeTaskinstance(task.id);
        if (res.code === 200) {
            ElMessage.success("任务已恢复");
            getList();
        }
    } else {
        let res = await startTaskinstance(task.id);
        if (res.code === 200) {
            ElMessage.success("任务已开始");
            getList();
        }
    }
}

/**
 * 暂停执行任务
 * @param task 
 */
const pauseTask = async (task) => {
    let res = await pauseTaskinstance(task.id);
    if (res.code === 200) {
        ElMessage.success("任务已暂停");
        getList();
    }
}

/**
 * 停止执行任务
 * @param task 
 */
const stopTask = async (task) => {
    let res = await stopTaskinstance(task.id);
    if (res.code === 200) {
        ElMessage.success("任务已停止");
        getList();
    }
}

/**
 * 删除执行任务
 * @param task 
 */
const removeTask = async (task) => {
    ElMessageBox.confirm('确定要删除该任务吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(async () => {
        let res = await deleteRunTask(task.id);
        if (res.code === 200) {
            ElMessage.success("任务已删除");
            getList();
        }
    }).catch(() => {
        // 取消删除
    });
}

/**
 * 获取历史执行任务
 */
const getHistoryList = () => {
    loading.value = true;
    getTaskinstanceList({
        statusList: ['0', '2', '4'],
        pageNum: queryParams.pageNum,
        pageSize: queryParams.pageSize,
    }).then((res) => {
        if (res.code === 200) {
            tableDataList.value = res.rows;
            total.value = res.total;
        }
        loading.value = false;
    }).catch(() => {
        loading.value = false;
    });
}

const taskRunningInfo = ref({})

const socketChannelCallbacks = ref({})
const channel = 'AimaTaskInstance';

/**
 * 订阅websocket
 */
const subscribeDebounced = debounce(async (sub) => {
    if (!socket) {
        console.warn(`执行任务订阅失败: socket=${!!socket}`);
        return;
    }

    socket.send({
        type: 'channel_subscription',
        action: sub ? 'subscribe' : 'unsubscribe',
        channel,
    });

    if (sub) {
        await nextTick();
        // 清理旧回调
        if (socketChannelCallbacks.value[channel]) {
            socket.off(channel, socketChannelCallbacks.value[channel]);
            console.log('清理旧回调:', channel);
        }

        const callback = (data) => {
            console.log('data', data)
            if (data !== '500') {
                if (data.status !== 0) {
                    let activeStep = pointList_runningTask.value[data.taskId].findIndex(item => item.detectItemId === data.itemId) || 0
                    if (data.progress == 100) {
                        activeStep += 1
                    }
                    taskRunningInfo.value[data.taskInstanceId] = {
                        ...data,
                        activeStep
                    }
                    if (!taskLogList.value[data.taskInstanceId]) {
                        taskLogList.value[data.taskInstanceId] = []
                    }
                    taskLogList.value[data.taskInstanceId].push({
                        ...data
                    })
                } else {
                    delete taskRunningInfo.value[data.taskInstanceId]
                    delete taskLogList.value[data.taskInstanceId]
                    getList()
                    getHistoryList()
                }
            } else {
                // 错误处理：取消订阅后重新订阅
                subscribeDebounced(false);
                subscribeDebounced(true);
            }
        };
        socket.on(channel, callback);
        socketChannelCallbacks.value[channel] = callback;
    } else {
        if (socketChannelCallbacks.value[channel]) {
            socket.off(channel, socketChannelCallbacks.value[channel]);
            delete socketChannelCallbacks.value[channel];
        }
    }
}, 300);

const logDialogVisible = ref(false)
const logDialogData = ref([])
const handleOpenLog = async (row) => {
    logDialogVisible.value = true
    const res = await getTaskLogListApi({ taskInstanceId: row.id })
    if (res.code === 200) {
        logDialogData.value = res.rows
    }
}
onMounted(() => {
    getTaskData();
    getPhoneData();
    getCarData()
    getList();
    getHistoryList();
    subscribeDebounced(true)
})

onUnmounted(() => {
    subscribeDebounced(false)
})
</script>
<style lang="scss" scoped>
.page-container {
    width: 100%;
    height: 100%;
    display: flex;
    gap: 12px;

    .left {
        width: 25%;
        height: 100%;
        background: #fff;
        padding: 16px;

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding-bottom: 16px;
            border-bottom: 1px solid #eee;
        }

        .taskList-container {
            margin-top: 16px;
            height: calc(100% - 100px);
            overflow-y: auto;

            .task-item {
                padding: 12px;
                background: #fafafa;
                box-shadow: inset 0 0 0 1px #eee;
                border-radius: 8px;
                margin-bottom: 16px;

                .task-content {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;

                    .task-title {
                        font-size: 16px;
                        font-weight: bold;
                    }

                    .task-actions {
                        display: flex;
                        gap: 8px;

                        .icon {
                            cursor: pointer;
                        }
                    }
                }

                .robot {
                    margin-top: 8px;
                    color: #666;
                }
            }
        }
    }

    .right {
        flex: 1;
        padding: 16px;
        background: #fff;
        overflow: hidden;

        .header {
            display: flex;
            margin-bottom: 16px;
            border-bottom: 1px solid #eee;

            .label {
                font-size: 16px;
                font-weight: bold;
                color: #333;
                cursor: pointer;
                box-shadow: inset 0 0 0 1px #eee;
                padding: 10px;
            }

            .active {
                color: #409eff;
                box-shadow: inset 0 0 0 1px #409eff;
            }
        }

        .context-container {
            height: calc(100% - 40px);
            overflow: auto;
        }

        .task {
            padding: 16px;
            background: #fafafa;
            border-radius: 20px;
            margin-bottom: 12px;

            .task-header {
                display: flex;
                justify-content: space-between;
                align-items: center;

                .task-info {
                    display: flex;
                    gap: 40px;

                    .title {
                        font-size: 18px;
                        font-weight: bold;
                    }

                    .id {
                        color: #666;
                        font-size: 14px;
                        margin: 8px 0;
                    }
                }

                .robot {
                    display: flex;
                    align-items: center;
                    gap: 50px;
                    color: #666;
                    font-size: 14px;
                }
            }



            .progress-label {
                margin-top: 12px;
                color: #666;
                font-size: 14px;
                font-weight: bold;
            }
        }
    }
}
</style>