<template>
    <div class="monitor-container">
        <div class="left-container">
            <div class="robot-container">
                <div class="title">选择机器人</div>
                <div class="robot-box">
                    <div v-for="item, index in robotList" class="robot" :class="{ active: activeBot === index }"
                        @click="changeBot(index)">
                        <div>
                            <SvgIcon name="bot" :color="colorList[index]" />
                        </div>
                        <div>
                            <div class="bot-name">{{ item.robotName }}</div>
                            <div class="bot-local">{{ robotStatus[item.status] }}</div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="split-line"></div>
            <div class="mode-container">
                <div class="title">控制模式</div>
                <div class="mode-box">
                    <div class="mode-item" :class="{ activeMode: activeMode === 'auto' }" @click="changeMode('auto')">
                        <SvgIcon name="cpu" :color="activeMode === 'auto' ? '#00FF88' : '#fff'" :size="16" />
                        <span class="label">自动巡检</span>
                    </div>
                    <div class="mode-item" :class="{ activeMode: activeMode === 'artificial' }"
                        @click="changeMode('artificial')">
                        <SvgIcon name="gamepad" :color="activeMode === 'artificial' ? '#00FF88' : '#fff'" :size="16" />
                        <span class="label">人工接管</span>
                    </div>
                </div>
            </div>
            <div v-if="activeMode === 'artificial'" class="artificial-panel">
                <el-radio-group v-model="activeController" size="small" @change="handlerController">
                    <el-radio :value="1">底盘</el-radio>
                    <el-radio :value="2">机械臂</el-radio>
                    <el-radio :value="3">相机</el-radio>
                </el-radio-group>
                <div class="controller-panel">人工控制面板</div>
                <DirectionControl v-if="activeController === 1" :robot="activeBotData" />
                <div v-if="activeController === 2" class="robotic-arm-controller-container">
                    <el-radio-group v-model="activeRoboticArm" size="small">
                        <el-radio :value="1">末端控制</el-radio>
                        <el-radio :value="2">关节控制</el-radio>
                        <el-radio :value="3">姿态控制</el-radio>
                    </el-radio-group>

                    <RoboticArm :type="activeRoboticArm === 1 ? 'end' : 'posture'" :robot="activeBotData"
                        v-if="[1, 3].includes(activeRoboticArm)" />

                    <div class="control-panel" v-if="activeRoboticArm === 2">
                        <div class="joint-list">
                            <div v-for="joint in jointControls" :key="joint.name" class="joint-item">
                                <label :for="joint.name">{{ joint.name }}</label>
                                <el-input
                                    v-model="joint.value"
                                    readonly
                                >
                                    <template #prepend>
                                        <el-button
                                            @mousedown="updateJoint(joint.name, '-')"
                                            @mouseup="stop"
                                            @touchstart.prevent="updateJoint(joint.name, '-')"
                                            @touchend.prevent="stop"
                                        >
                                                -
                                        </el-button>
                                    </template>
                                    <template #append>
                                        <el-button
                                            @mousedown="updateJoint(joint.name, '+')"
                                            @mouseup="stop"
                                            @touchstart.prevent="updateJoint(joint.name, '+')"
                                            @touchend.prevent="stop"
                                        >
                                            +
                                        </el-button>
                                    </template>
                                </el-input>
                            </div>
                        </div>
                        <div class="speed-container">
                            <div class="label">速度：</div>
                            <el-slider v-model="jointSpeed" :min="0.01" :step="0.01" :max="1" />
                            <div class="proportion">{{( jointSpeed / 1 * 100).toFixed(0) }} %</div>
                        </div>
                    </div>
                </div>
            </div>

        </div>
        <div class="video-container">
            <div v-if="activeMode === 'auto' || activeController === 1" class="map-container">
                <MapCanvas :robotList="robotList" ref="mapCanvasRef" />
            </div>
            <div v-if="activeMode === 'artificial' && activeController === 2" class="model-container">
                <UrdfViewer ref="urdfViewerRef" base-path="/inspection/elfin10/" />
            </div>
            <div v-if="activeMode === 'artificial' && activeController === 3" class="monitor-container">监控</div>
        </div>
        <div class="right-container">
            <div class="container-title">车载监控</div>
            <div class="monitor-container">
                <IPlayer :isLive="true" :videoUrl="videoUrl" />
            </div>
            <div class="split-line"></div>
            <div class="container-title">语音对话</div>
            <div class="voice-container">
                <VoiceConversation />
            </div>
        </div>
    </div>
</template>
<script setup>
import { onMounted, nextTick } from "vue";
import SvgIcon from "@/components/SvgIcon";
import UrdfViewer from './UrdfView.vue'
import DirectionControl from './DirectionControl.vue'
import RoboticArm from "./RoboticArm.vue";
import { getRobotList } from '@/api/inspection/robot'
import { getJointStateApi, moveJApi, torqueOnApi, speedJApi, stopMotionApi, clearFault } from '@/api/inspection/cockpit'
import { Remove, CirclePlus } from '@element-plus/icons-vue'
import VoiceConversation from "./VoiceConversation.vue";
import IPlayer from "@/components/IPlayer/index.vue";

const robotList = ref([])

const fetchRobotList = async () => {
    try {
        const res = await getRobotList({
            robotType: 2,
        })
        if (res.code === 200) {
            robotList.value = res.rows
            activeBotData.value = robotList.value[0] || {}
        } else {
            console.error('获取机器人列表失败:', res.message)
        }
    } catch (error) {
        console.error('获取机器人列表失败:', error)
    }
}

const robotStatus = {
    0: '在线',
    1: '离线',
    2: '充电中',
    3: '巡检中'
}

const activeBot = ref(0)
const activeBotData = ref({})
const changeBot = (index) => {
    activeBot.value = index
    activeBotData.value = robotList.value[activeBot.value] || {}
}

const colorList = ['#00D4FF', '#FFB300', '#00FF88', '#fff']

const activeMode = ref('auto')
const changeMode = (mode) => {
    activeMode.value = mode
}

const activeController = ref(1)

const speed = ref(0.8)

const activeRoboticArm = ref(1)

const urdfViewerRef = ref()
const jointControls = ref()

const animationId = ref(null)

const handlerController = (value) => {
    if (value === 2) {
        // 开启机械臂使能
        torqueOnApi({
            deviceId: import.meta.env.VITE_INSPECTION_ARM_DEVICE_ID,
            terminalId: activeBotData.value.terminalId
        }).catch(error => {
            console.error('开启机械臂使能失败:', error)
            clearFault({
                deviceId: import.meta.env.VITE_INSPECTION_ARM_DEVICE_ID,
                terminalId: activeBotData.value.terminalId
            })
        })
        jointControls.value = urdfViewerRef.value.jointControls
        if (animationId.value) {
            clearInterval(animationId.value)
        }
        animationId.value = setInterval(() => {
            getJointState(activeBotData.value)
        }, 100)
    } else {
        if (animationId.value) {
            clearInterval(animationId.value)
        }
    }
}

const jointNamsMap = {
    'joint_1' :'elfin_joint1',
    'joint_2': 'elfin_joint2',
    'joint_3': 'elfin_joint3',
    'joint_4': 'elfin_joint4',
    'joint_5': 'elfin_joint5',
    'joint_6': 'elfin_joint6',
}

const errCount = ref(0)

/**
 * 获取关节状态
 * @param robot 
 */
const getJointState = async (robot) => {
    try {
        const res = await getJointStateApi({
            deviceId: import.meta.env.VITE_INSPECTION_ARM_DEVICE_ID,
            terminalId: robot.terminalId
        })
        if (res.code === 200) {
            setTimeout(() => {
                const names = res.data.name
                const positions = res.data.position
                names.forEach((name, index) => {
                    urdfViewerRef.value.updateJoint(jointNamsMap[name] || name, positions[index].toFixed(3))
                })
            }, 500)
        } else {
            errCount.value += 1
            if (errCount.value > 2) {
                clearInterval(animationId.value)
                errCount.value = 0
            }
            console.error('获取关节状态失败:', res.message)
        }
    } catch (error) {
        errCount.value += 1
        if (errCount.value > 2) {
            clearInterval(animationId.value)
            errCount.value = 0
        }
        console.error('获取关节状态失败:', error)
    }
}

const jointSpeed = ref(0.8)
const updateJoint = async (jointName, _dir) => {
    const velocities = jointControls.value.map(joint => {
        return 0
    })
    const index = jointControls.value.findIndex(joint => joint.name === jointName)
    velocities[index] = jointSpeed.value * (_dir === '+' ? 1 : -1)
    const res = await speedJApi({
        deviceId: import.meta.env.VITE_INSPECTION_ARM_DEVICE_ID,
        terminalId: activeBotData.value.terminalId,
        acceleration: jointSpeed.value + 0.1,
        duration: 60,
        velocities: velocities
    })
}

/**
 * 停止机械臂移动
 */
const stop = async () => {
    await stopMotionApi({
        deviceId: import.meta.env.VITE_INSPECTION_ARM_DEVICE_ID,
        terminalId: activeBotData.value.terminalId
    })
}

const videoUrl = ref('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8')

onMounted(() => {
    fetchRobotList()
})

onUnmounted(() => {
    if (animationId.value) {
        clearInterval(animationId.value)
    }
})

</script>

<style lang="scss" scoped>
.monitor-container {
    width: 100%;
    height: 100%;
    display: flex;

    .left-container {
        width: 360px;
        height: 100%;
        padding: 16px;

        .robot-container {

            .title {
                color: #8899BB;
                font-size: 14px;
                margin-bottom: 16px;
            }

            .robot-box {
                display: flex;
                flex-wrap: wrap;
                gap: 10px;
                align-items: center;
                justify-content: space-between;

                .robot {
                    flex: 0 0 calc(50% - 10px);
                    background: #0F1E38;
                    height: 56px;
                    border-radius: 8px;
                    padding: 16px;
                    display: flex;
                    align-items: center;
                    gap: 20px;
                    margin-bottom: 16px;
                    cursor: pointer;
                    border: 1px solid transparent;

                    .bot-name {
                        color: #fff;
                        font-size: 12px;
                    }

                    .bot-local {
                        color: #00d4ff;
                        font-size: 11px;
                        margin-top: 4px;
                    }
                }

                .active {
                    border-color: #00c2ff;
                    color: #fff;
                    box-shadow: 0 0 10px rgba(0, 194, 255, 0.5);
                }
            }
        }

        .split-line {
            width: 100%;
            height: 1px;
            margin: 16px 0;
            background: #1E3A5F;
        }

        .mode-container {
            .title {
                color: #8899BB;
                font-size: 14px;
                margin-bottom: 16px;
            }

            .mode-box {
                display: flex;
                flex-wrap: wrap;
                gap: 10px;
                align-items: center;
                justify-content: space-between;

                .mode-item {
                    height: 36px;
                    flex: 0 0 calc(50% - 10px);
                    background: #0F1E38;
                    border: 1px solid transparent;
                    border-radius: 8px;
                    padding: 16px;
                    margin-bottom: 12px;
                    display: flex;
                    align-items: center;
                    gap: 16px;
                    cursor: pointer;

                    .label {
                        color: #8899BB;
                        font-size: 13px;
                    }
                }

                .activeMode {
                    border-color: #00FF88;

                    .label {
                        color: #00FF88;
                    }
                }

            }
        }

        .controller-panel {
            padding: 16px;
            color: #fff;
            font-size: 16px;
        }


        .robotic-arm-controller-container {
            :deep(.el-radio-group) {
                display: flex;
                align-items: center;
                justify-content: space-between;
            }
        }
    }

    .video-container {
        flex: 1;
        border: 1px solid #1E3A5F;
        border-top: 0;

        .map-container {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #00c2ff;
            font-size: 20px;
        }

        .model-container {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #00c2ff;
            font-size: 20px;
        }

        .monitor-container {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #00c2ff;
            font-size: 20px;
        }
    }

    .right-container {
        width: 360px;
        height: 100%;
        padding: 16px;

        .container-title {
            color: #fff;
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 16px;
        }

        .split-line {
            width: 100%;
            height: 1px;
            margin: 16px 0;
            background: #1E3A5F;
        }

        .monitor-container {
            width: 100%;
            height: 360px;
        }

        .voice-container {
            width: 100%;
            height: 400px;
        }
    }
}

.control-panel {
    margin-top: 12px;
    background: #0F1E38;
    padding: 15px;
    border-radius: 8px;
    color: #ccc;
    max-height: 80%;
    overflow-y: auto;

    .joint-item {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 10px;
        padding: 10px;
        border: 1px solid rgba(0, 195, 255, 0.08);
        border-radius: 5px;
        background: #0b182c;

        &:hover {
            border-color: #2a3f7a;
            background: rgba(59, 130, 246, 0.031372549);
        }

        label {
            width: 120px;
            font-size: 16px;
            font-weight: bold;
        }

        input[type=range] {
            flex: 1;
        }

        .angle {
            width: 50px;
            text-align: right;
        }

        :deep(.el-input-group__prepend) {
            background: #080b10;
            border-right: 0px;
            box-shadow: 0 0 0 1px #272727 inset;
        }

        :deep(.el-input-group__append) {
            background: #080b10;
            border-left: 0px;
            box-shadow: 0 0 0 1px #272727 inset;
        }

        :deep(.el-input__wrapper) {
            background-color: #0e0e0e;
            box-shadow: 0 0 0 1px #272727 inset;
        }
    }

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

        .label,
        .proportion {
          width: 100px;
          text-align: center;
          color: #fff;
        }
    }
}
</style>