<template>
    <div class="containner">

        <div class="title">
            <LeftOutlined @click="backPage" />
            <div>面状航线</div>
            <SaveOutlined/>

            <div style="flex:1;">
                <a-input v-model:value="submitForm.airLineName"  size="small" placeholder="航线名称" />
            </div>
        </div>

        <div class="area-info">
            <div class="item">
                <div>测区面积</div>
                <div>{{props.airInfo.area}} m²</div>
            </div>
            <div class="bar"></div>
            <div class="item">
                <div>航线长度</div>
                <div>{{props.airInfo.length}} km</div>
            </div>
            <div class="bar"></div>
            <div class="item">
                <div>预计用时</div>
                <div>{{props.airInfo.time}} mins</div>
            </div>
            <div class="bar"></div>
            <div class="item">
                <div>照片数量</div>
                <div>{{props.airInfo.picture}} </div>
            </div>
            
        </div>

        <div class="area-options" >

            <div class="item">
                <div class="label">参考起飞点</div>
                <div class="content">
                    <a-button type="link" style="color:#408eff" @click="setFlyPoint()">
                        <img src="./start-fly.png" style="width:24px;height:24px;position:relative;left:-2px;top:-2px;" alt="">
                        设置起飞点
                    </a-button>
                </div>
            </div>

          
            <div class="item">
                <div class="label">GSD(地面采样距离)</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="calculatParam.gsd" @change="onGsdChange"></a-input>
                </div>
                <div class="unit"> cm/pixel</div>
            </div>

            <div class="item">
                <div class="label">航线高度</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="calculatParam.height" @change="onHeightChange"></a-input>
                </div>
                <div class="unit"> m</div>
            </div>

            <div class="item">
                <div class="label">航向重叠率</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="calculatParam.overlapX"></a-input>
                </div>
                <div class="unit"> % </div>
            </div>

            <div class="item">
                <div class="label">旁向重叠率</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="calculatParam.overlapY" @change="onOverlayYChange"></a-input>
                </div>
                <div class="unit"> %</div>
            </div>

            <div class="item">
                <div class="label">主航线角度</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="calculatParam.overlapAngle"></a-input>
                </div>
                <div class="unit"> °</div>
            </div>


            <div class="item flex-column">
                <div class="label">飞向首航点模式</div>
                <div class="content">
                    <div class="radio-box">
                        <div v-for="(item,index) in missionConfigOptions.flyToWaylineMode" :key="index"
                            :class=" missionConfig.flyToWaylineMode == item.value ? 'radio-item-active':'radio-item'" 
                            @click="missionConfig.flyToWaylineMode = item.value"
                            >
                            {{item.label}}
                        </div>
                    </div>
                </div>
                <div class="description">
                    <img src="/map/flyToWaylineMode.png" alt="">
                </div>
            </div>

            <div class="item">
                <div class="label">安全起飞高度</div>
                <div class="content">
                    <a-input style="width:100px;"  placeholder="" v-model:value="missionConfig.takeOffSecurityHeight"></a-input>
                </div>
                <div class="unit"> m</div>
            </div>

            <div class="item">
                <div class="label">全局航线过渡速度</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="missionConfig.globalTransitionalSpeed"></a-input>
                </div>
                <div class="unit"> m/s</div>
            </div>

            <div class="item">
                <div class="label">全局返航高度</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="missionConfig.droneInfo.droneEnumValue"></a-input>
                </div>
                <div class="unit"> m</div>
            </div>

            <div class="item flex-column">
                <div class="label">航线结束动作</div>
                <div class="content">
                    <div class="radio-box">
                        <div v-for="(item,index) in missionConfigOptions.finishAction" :key="index"
                            :class=" missionConfig.finishAction == item.value ? 'radio-item-active':'radio-item'" 
                            @click="missionConfig.finishAction = item.value"
                            >
                            {{item.label}}
                        </div>
                    </div>
                </div>
            </div>

            <div class="item flex-column">
                <div class="label">失控是否继续执行航线</div>
                <div class="content">
                    <div class="radio-box">
                        <div v-for="(item,index) in missionConfigOptions.exitOnRCLost" :key="index"
                            :class=" missionConfig.exitOnRCLost == item.value ? 'radio-item-active':'radio-item'" 
                            @click="missionConfig.exitOnRCLost = item.value"
                            >
                            {{item.label}}
                        </div>
                    </div>
                </div>
            </div>

            <div class="item flex-column" v-if="missionConfig.exitOnRCLost == 'executeLostAction'">
                <div class="label">失控动作类型</div>
                <div class="content">
                    <div class="radio-box">
                        <div v-for="(item,index) in missionConfigOptions.executeRCLostAction" :key="index"
                            :class=" missionConfig.executeRCLostAction == item.value ? 'radio-item-active':'radio-item'" 
                            @click="missionConfig.executeRCLostAction = item.value"
                            >
                            {{item.label}}
                        </div>
                    </div>
                </div>
            </div>

            <div class="item flex-column">
                <div class="label">高度模式</div>
                <div class="content">
                    <div class="radio-box">
                        <div v-for="(item,index) in folderConfigOptions.executeHeightMode" :key="index"
                            :class=" folder.executeHeightMode == item.value ? 'radio-item-active':'radio-item'" 
                            @click="folder.executeHeightMode = item.value"
                            >
                            {{item.label}}
                        </div>
                    </div>
                </div>
                <div class="description">
                    <img src="/map/executeHeightMode.png" alt="">
                </div>
            </div>
        

            <div class="item">
                <div class="label">全局航线飞行速度</div>
                <div class="content">
                    <a-input style="width:100px;" placeholder="" v-model:value="folder.autoFlightSpeed"></a-input>
                </div>
                <div class="unit"> m/s</div>
            </div>
           
        </div>
    </div>
</template>
<script lang="ts" setup>
import {ref,defineEmits,defineProps,watch} from 'vue'
import { SaveOutlined,LeftOutlined } from '@ant-design/icons-vue';
import {missionConfigOptions,folderConfigOptions}  from '../waylineConfig/index.ts';
import {uploadXmlFile,addAirLine} from '@/api/sys/workplan';
import { message } from 'ant-design-vue';
import { XMLParser, XMLBuilder } from 'fast-xml-parser';

// 航线计算
import {uavModel,calculateHeight,calculateGsd,calculateSpacing} from '../lib/calculateAirLine'




const emits = defineEmits(["setFlyPoint","exitDraw","calculatParamChange"])

const props = defineProps(["airInfo","polygonAirForm","airPoints","airRoute"])

const airInfo = ref({
    area:0.0,
    length:0.0,
    time:'4m 11s',
    picture:23
})

const setFlyPoint = ()=>{
    emits("setFlyPoint");
}

// 航线计算参数
const calculatParam = ref({
    gsd:2,
    overlapY:70,
    overlapX:80,
    overlapAngle:0,
    height:0,
    spacing:0,
})

watch(
    () => calculatParam.value,
    (newVal,oldVal) => {
        emits("calculatParamChange",newVal)
    },
    {deep:true}
)

calculatParam.value.height = calculateHeight(calculatParam.value.gsd,uavModel['m4td']);

calculatParam.value.spacing =  calculateSpacing(calculatParam.value.gsd,calculatParam.value.overlapY/100,uavModel['m4td'])

// gsd改变
const onGsdChange = ()=>{
    calculatParam.value.height = calculateHeight(calculatParam.value.gsd,uavModel['m4td']);
    onOverlayYChange();
}

// 飞行高度改变
const onHeightChange = () => {
    calculatParam.value.gsd = calculateGsd(calculatParam.value.height,uavModel['m4td']);
    onOverlayYChange();
}

// 旁像重叠率
const onOverlayYChange = ()=>{
    calculatParam.value.spacing =  calculateSpacing(calculatParam.value.gsd,calculatParam.value.overlapY/100,uavModel['m4td'])
}

// 航线基本信息
const missionConfig = ref(
    {
        "flyToWaylineMode": "safely",
        "finishAction": "goHome",
        "exitOnRCLost": "executeLostAction",
        "executeRCLostAction": "goBack",
        "takeOffSecurityHeight": 20,
        "globalTransitionalSpeed": 15,
        "globalRTHHeight": 100,
        "droneInfo": {
            "droneEnumValue": 100,
            "droneSubEnumValue": 1
        },
        "autoRerouteInfo": {
            "transitionalAutoRerouteMode": 1,
            "missionAutoRerouteMode": 1
        },
        "waylineAvoidLimitAreaMode": 0,
        "payloadInfo": {
            "payloadEnumValue": 99,
            "payloadSubEnumValue": 2,
            "payloadPositionIndex": 0
        }
    }
)


// 航点基本信息
const folder = ref({
    "templateId": 0,
    "executeHeightMode": "WGS84",
    "waylineId": 0,
    "distance": 410.047576904297,
    "duration": 80.3239784240723,
    "autoFlightSpeed": 10,
    "Placemark":[]
})

// 航点详细信息
const pointInfo =  {
    "Point": {
        "coordinates": "118.295430406842,35.1352868743403"      // 坐标
    },
    "index": 0,                                                 // 序号
    "executeHeight": 167,                                       // 高度
    "waypointSpeed": 12.7125370218057,                          // 飞行速度
    "waypointHeadingParam": {                                   // 飞行器参数
        "waypointHeadingMode": "followWayline",                 // 偏航角模式  和航线角度一致         
        "waypointHeadingAngle": -96.9990577342362,                 
        "waypointPoiPoint": "0.000000,0.000000,0.000000",
        "waypointHeadingAngleEnable": 1,
        "waypointHeadingPathMode": "followBadArc",
        "waypointHeadingPoiIndex": 0
    },
    "waypointTurnParam": {
        "waypointTurnMode": "toPointAndStopWithDiscontinuityCurvature",
        "waypointTurnDampingDist": 0
    },
    "useStraightLine": 1,
    "actionGroup": [
        {
            "#text": "z",
            "actionGroupId": 0,
            "actionGroupStartIndex": 0,
            "actionGroupEndIndex": 13,
            "actionGroupMode": "sequence",
            "actionTrigger": {
                "actionTriggerType": "betweenAdjacentPoints"
            },
            "action": [
                {
                    "actionId": 0,
                    "actionActuatorFunc": "gimbalAngleLock"
                },
                {
                    "actionId": 1,
                    "actionActuatorFunc": "gimbalRotate",
                    "actionActuatorFuncParam": {
                        "gimbalHeadingYawBase": "aircraft",
                        "gimbalRotateMode": "absoluteAngle",
                        "gimbalPitchRotateEnable": 1,
                        "gimbalPitchRotateAngle": -90,
                        "gimbalRollRotateEnable": 0,
                        "gimbalRollRotateAngle": 0,
                        "gimbalYawRotateEnable": 0,
                        "gimbalYawRotateAngle": 0,
                        "gimbalRotateTimeEnable": 0,
                        "gimbalRotateTime": 10,
                        "payloadPositionIndex": 0
                    }
                },
                {
                    "actionId": 2,
                    "actionActuatorFunc": "startTimeLapse",
                    "actionActuatorFuncParam": {
                        "payloadPositionIndex": 0,
                        "useGlobalPayloadLensIndex": 0,
                        "payloadLensIndex": "visable",
                        "minShootInterval": 1.52472746372223
                    }
                }
            ]
        },
        {
            "actionGroupId": 1,
            "actionGroupStartIndex": 0,
            "actionGroupEndIndex": 13,
            "actionGroupMode": "sequence",
            "actionTrigger": {
                "actionTriggerType": "multipleTiming",
                "actionTriggerParam": 2
            },
            "action": {
                "actionId": 0,
                "actionActuatorFunc": "gimbalRotate",
                "actionActuatorFuncParam": {
                "gimbalHeadingYawBase": "aircraft",
                "gimbalRotateMode": "absoluteAngle",
                "gimbalPitchRotateEnable": 1,
                "gimbalPitchRotateAngle": -90,
                "gimbalRollRotateEnable": 0,
                "gimbalRollRotateAngle": 0,
                "gimbalYawRotateEnable": 0,
                "gimbalYawRotateAngle": 0,
                "gimbalRotateTimeEnable": 0,
                "gimbalRotateTime": 10,
                "payloadPositionIndex": 0
                }
            }
        }
    ],
    "waypointGimbalHeadingParam": {
        "waypointGimbalPitchAngle": 0,
        "waypointGimbalYawAngle": 0
    },
    "isRisky": 0,
    "waypointWorkType": 0
}


// 处理航点数据
const handlerPointInfo = ()=>{

    if(props.airPoints?.length<=0){
        message.warning("请添加航点！");
        return null;
    }
    props.airPoints?.forEach((item,index)=>{
        let point = {
            "Point": {
                "coordinates": item.lng+","+item.lat    // 坐标
            },
            "index": index,                                                 // 序号
            "executeHeight": 167,                                       // 高度
            "waypointSpeed": 12.7125370218057,                          // 飞行速度
            "waypointHeadingParam": {                                   // 飞行器参数
                "waypointHeadingMode": "followWayline",                 // 偏航角模式  和航线角度一致         
                "waypointHeadingAngle": -96.9990577342362,                 
                "waypointPoiPoint": "0.000000,0.000000,0.000000",
                "waypointHeadingAngleEnable": 1,
                "waypointHeadingPathMode": "followBadArc",
                "waypointHeadingPoiIndex": 0
            },
            "waypointTurnParam": {
                "waypointTurnMode": "toPointAndStopWithDiscontinuityCurvature",
                "waypointTurnDampingDist": 0
            },
            "useStraightLine": 1,
            "actionGroup": [
                {
                    "#text": "z",
                    "actionGroupId": 0,
                    "actionGroupStartIndex": 0,
                    "actionGroupEndIndex": 13,
                    "actionGroupMode": "sequence",
                    "actionTrigger": {
                        "actionTriggerType": "betweenAdjacentPoints"
                    },
                    "action": [
                        {
                            "actionId": 0,
                            "actionActuatorFunc": "gimbalAngleLock"
                        },
                        {
                            "actionId": 1,
                            "actionActuatorFunc": "gimbalRotate",
                            "actionActuatorFuncParam": {
                                "gimbalHeadingYawBase": "aircraft",
                                "gimbalRotateMode": "absoluteAngle",
                                "gimbalPitchRotateEnable": 1,
                                "gimbalPitchRotateAngle": -90,
                                "gimbalRollRotateEnable": 0,
                                "gimbalRollRotateAngle": 0,
                                "gimbalYawRotateEnable": 0,
                                "gimbalYawRotateAngle": 0,
                                "gimbalRotateTimeEnable": 0,
                                "gimbalRotateTime": 10,
                                "payloadPositionIndex": 0
                            }
                        },
                        {
                            "actionId": 2,
                            "actionActuatorFunc": "startTimeLapse",
                            "actionActuatorFuncParam": {
                                "payloadPositionIndex": 0,
                                "useGlobalPayloadLensIndex": 0,
                                "payloadLensIndex": "visable",
                                "minShootInterval": 1.52472746372223
                            }
                        }
                    ]
                },
                {
                    "actionGroupId": 1,
                    "actionGroupStartIndex": 0,
                    "actionGroupEndIndex": 13,
                    "actionGroupMode": "sequence",
                    "actionTrigger": {
                        "actionTriggerType": "multipleTiming",
                        "actionTriggerParam": 2
                    },
                    "action": {
                        "actionId": 0,
                        "actionActuatorFunc": "gimbalRotate",
                        "actionActuatorFuncParam": {
                        "gimbalHeadingYawBase": "aircraft",
                        "gimbalRotateMode": "absoluteAngle",
                        "gimbalPitchRotateEnable": 1,
                        "gimbalPitchRotateAngle": -90,
                        "gimbalRollRotateEnable": 0,
                        "gimbalRollRotateAngle": 0,
                        "gimbalYawRotateEnable": 0,
                        "gimbalYawRotateAngle": 0,
                        "gimbalRotateTimeEnable": 0,
                        "gimbalRotateTime": 10,
                        "payloadPositionIndex": 0
                        }
                    }
                }
            ],
            "waypointGimbalHeadingParam": {
                "waypointGimbalPitchAngle": 0,
                "waypointGimbalYawAngle": 0
            },
            "isRisky": 0,
            "waypointWorkType": 0
        }
       
        folder.value.Placemark?.push(point);
    })

    return true;

}

// waylines.json 数据
const waylinesJson = ref(
    {
    "kml": {
            "Document": {
                "missionConfig":missionConfig.value,
                "Folder":folder.value
            }
        }
    }
)



// 保存航线
const saveAirLine = ()=>{

    let handlerResult =  handlerPointInfo();

    if(handlerResult){
        const builder = new XMLBuilder();

        let lineData = {...waylinesJson.value}

        let obj = handlerPrefixWpml(lineData);

        let xmlString = builder.build(obj);

        let xmlString2 = xmlString.replace(/<\/?\d+>/g, "")

        let xmlString3 = xmlString2.replace("<kml>",`<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.6">`)

        handlerCreateFile(xmlString3);

    }

}

// 处理wmpl:前缀 
const handlerPrefixWpml = (obj) => {
  for (const key in obj) {

    // 如果是对象
    if (typeof obj[key] === 'object' && obj[key] !== null) {

        handlerPrefixWpml(obj[key]); // 递归处理嵌套对象

        const newAttrs = {};
        for (const attrName in obj[key]) {
           
            // 检查属性名是否首字母小写
            if (/^[a-z]/.test(attrName)) {
                newAttrs[`wmpl:${attrName}`] = obj[key][attrName];
            } else {
                newAttrs[attrName] = obj[key][attrName];
            }
        }
        obj[key] = newAttrs;
    }
  }
  return obj;
}


// 保存表单
const submitForm = ref({
    "id": "",
    "airLineName": props.airRoute.name, 
    "airLineType": "waypoint",
    "uavId": "",
    "flyToFirstPointMode": "", 
    "safeTakeoffAltitude": 0, 
    "safeTakeoffSpeed": 0,  
    "globalRouteSpeed": 0, 
    "taskCompletionAction": "", 
    "outOfControlOption": "",
    "typeOfOutOfControlAction": "",
    "globalWayPointType": "",
    "ptzControlMode": "",
    "aircraftYawAngleMode": "",
    "wpml": ""
})



// 生成xml文件，创建航线
const handlerCreateFile =async (content)=>{
    const blob = new Blob([content], { type: 'wmpl/plain' });
    // 创建FormData对象用于上传
    const formData = new FormData();
    formData.append('xmlFile', blob);
    let res = await uploadXmlFile(formData);
    if(res){
        submitForm.value.wpml = res.path;
        let addAirLineRes =await addAirLine(submitForm.value);
        if(addAirLineRes){
            message.success("操作成功！");
            backPage();
        }else{
            message.error("操作失败！");
        }
    }else{
        message.error("操作失败！");
    }
}

// 退出绘制
const backPage = ()=>{
    emits("exitDraw")
}

</script>
<style scoped>
.container{
    width:100%;
    height:100%;
    color:#fff;
}

.title{
    padding:20px;
    font-size:16px;
    color:#ffffff;
    display:flex;
    gap:12px;
    line-height:24px;
}

.area-info{
    width:100%;
    border-top:1px solid rgba(255,255,255,0.2);
    border-bottom:1px solid rgba(255,255,255,0.2);
    display:flex;
    padding:20px 0px;
}
.area-info .item{
    flex:1;
    color:#fff;
    text-align: center;
    display:flex;
    gap:12px;
    flex-direction: column;
}

.area-options{
    width:100%;
    height: calc( 100vh - 260px);
    padding:10px;
    overflow-y:auto;
    line-height:32px;
}

.area-options .item{
    padding:10px;
    margin:15px 0px;
    background:#232323;
    color:#fff;
    display:flex;
}
.area-options .item .label{
    flex:1;
}
.area-options .item .content{
    cursor:pointer;
}

.flex-column{
    flex-direction: column;
    gap:10px;
}


.radio-box{
    width:100%;
    display: flex;
    overflow: hidden;
    border:0.5px solid #3B4154 ;
    background:#050608;
    font-size:13px;
    border-radius: 19px;
    height:38px;
    line-height:38px;
}


.radio-box .radio-item{
    flex:1;
    color:#8A92A6 ;
    text-align: center;
    cursor:pointer;

}

.radio-box .radio-item-active{
    flex:1;
    color:#fff;
    text-align: center;
    background:#3A57E8 ;
    border-radius: 19px;
    cursor:pointer;
}

.area-options .item .unit{
    min-width: 60px;
    text-align:center;

}


::v-deep .ant-radio-group {
    display: block;
    width: 100%;
}



::v-deep .ant-select-selector{
    border:none!important;
    color:#fff!important;
    background:#3F4150!important ;
    border-radius: 3px!important;
}


::v-deep .ant-select-selection-placeholder {
    color:rgba(255, 255, 255, 0.533)!important;
  }
::v-deep .ant-select-arrow {
    color:rgba(255, 255, 255, 0.533)!important;
  }
::v-deep .ant-select-selection-search-input::placeholder{
    color:rgba(255, 255, 255, 0.933)!important;
}


::v-deep .ant-tree {
    background:none!important;
    color:#fff!important;
}

::v-deep .ant-tree-treenode-selected{
    background:#3a57e877!important;
}

::v-deep .ant-tree-treenode-selected::before{
    background:none!important;
}

::v-deep .ant-tree-treenode-selected::after{
    content:"";
    height:28px;
    width:4px;
    background:#3A57E8;
    position:absolute;
    top:0px;
    left:0px;
}

::v-deep .ant-input{
    background:#3c3c3c!important ;
    border:none!important;
    border-top-left-radius: 3px !important;
    border-bottom-left-radius: 3px !important;
    color:#fff!important;
}

::v-deep .ant-input::placeholder{
    color:rgba(255, 255, 255, 0.533)!important;
}


::v-deep .ant-btn-default{
    background:none!important;
    border:none!important;
    outline:none!important;
    color:#fff!important;
    height:30px !important;
    background:#3F4150!important ;
}
</style>