<template>
  <!-- 飞行控制主容器 -->
  <div class="flight-control">
    <!-- 顶部状态栏 -->
    <div class="flight-control-top">
      <!-- 机场选择组件 -->
      <SelectComponent @selectChange="changeSelect" />
      <!-- 机场名称 -->
      <div class="airport-name">
        <img src="@/assets/images/flightcontrol/logo.png" alt="机场logo" />
        {{ airportName }}
      </div>
      <!-- 机场状态 -->
      <span class="airport-status" v-if="airporOsdVal.flighttask_step_code">
        <template v-if="airporOsdVal.flighttask_step_code == 0">作业准备中</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 1">飞行作业中</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 2">作业后状态恢复</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 3">自定义飞行区更新中</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 4">地形障碍物更新中</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 5">任务空闲</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 255">飞行器异常</template>
        <template v-else-if="airporOsdVal.flighttask_step_code == 256">未知状态</template>
      </span>
      <!-- 机场直播按钮 -->
      <span class="airport-live" @click="getRtmpList">机场直播</span>
      <!-- 机场环境信息 -->
      <div class="airport-info">
        <img src="@/assets/images/flightcontrol/temperature.png" alt="温度图标" />
        <span class="airport-info-title">舱外温度</span>
        <span>{{ airporOsdVal.temperature }}℃</span>
      </div>
      <div class="airport-info">
        <img src="@/assets/images/flightcontrol/rainfall.png" alt="雨量图标" />
        <span class="airport-info-title">雨量</span>
        <span>
          <template v-if="airporOsdVal.rainfall == 0">无雨</template>
          <template v-else-if="airporOsdVal.rainfall == 1">小雨</template>
          <template v-else-if="airporOsdVal.rainfall == 2">中雨</template>
          <template v-else-if="airporOsdVal.rainfall == 3">大雨</template>
        </span>
      </div>
      <div class="airport-info">
        <img src="@/assets/images/flightcontrol/wind_speed.png" alt="风速图标" />
        <span class="airport-info-title">风速</span>
        <span>{{ airporOsdVal.wind_speed }}m/s</span>
      </div>
      <div class="airport-info">
        <img src="@/assets/images/flightcontrol/rate.png" alt="网络图标" />
        <span class="airport-info-title">网络</span>
        <span>{{ airporOsdVal.rate }}KB/s</span>
      </div>
    </div>
    <!-- 主内容区域 -->
    <div class="flight-contain">
      <!-- 飞行器控制盒打开按钮 -->
      <div class="uavbox-open" @click="openUavBox" v-if="!uavBoxVisible">
        <img src="@/assets/images/flightcontrol/uavbox-open.png" alt="打开飞行器控制盒" />
      </div>
      <!-- 地图容器 -->
      <div class="map-container" :style="uavBoxVisible
        ? 'width:38vw;height:' + mapHeight + 'px'
        : 'width:90vw;height:' + mapHeight + 'px'
        ">
        <div class="map-container-content">
          <!-- 地图组件 -->
          <Map @flyToThere="flyToThere" :airPort="airPort" :uavTrack="uavTrack" :allAreaDataList="allAreaDataList"
            @takeOff="takeOff" />
        </div>
      </div>
      <!-- 飞行器控制盒 -->
      <div class="uav-box" ref="uavBox" v-if="uavBoxVisible">
        <UavBox @closeUavBox="uavBoxVisible = false" @flyLog="logVisible = true" @flyTo="flyTobtn" @patrol="patrolbtn"
          @taskSubmitted="handleTaskSubmitted" />
      </div>
      <!-- 飞行日志面板 -->
      <div class="fly-log" v-if="logVisible">
        <div class="fly-log-title">
          <span>飞行日志</span>
          <span @click="logVisible = false">
            <CloseCircleOutlined />
          </span>
        </div>
        <div class="fly-log-content">
          <div>检查项</div>
          <div class="fly-status">所有检查项均通过，飞行器将立即执行飞行任务。</div>
          <div class="log-opstions" ref="myDiv">
            <template v-for="(item, index) in flyOptions" :key="index">
              <div class="log-item MinusCircleFilled" v-if="item.type == 'info'">
                <MinusCircleFilled />
                <span class="item-desc">{{ item.title }}：{{ item.content }}</span>
              </div>
              <div class="log-item CheckCircleFilled" v-else-if="item.type == 'success'">
                <CheckCircleFilled />
                <span class="item-desc">{{ item.title }}：{{ item.content }}</span>
              </div>
              <div class="log-item CloseCircleFilled" v-else-if="item.type == 'error'">
                <CloseCircleFilled />
                <span class="item-desc">{{ item.title }}：{{ item.content }}</span>
              </div>
            </template>
          </div>
        </div>
      </div>
      <!-- 指点飞行面板 -->
      <div class="fly-to-form" v-if="flyToVisible">
        <div class="fly-to-title">
          <span class="title-name">指点飞行</span>
          <span class="title-icon" @click="flyToVisible = false">
            <CloseOutlined />
          </span>
        </div>
        <span class="form-desc">点击地图选择目标点，点击开始执行，飞行器将飞到指定地点。绘制路线仅供参考。</span>
        <div class="form-content">
          <div class="form-item">
            <span>经度</span>
            <div>
              <a-input v-model:value="flyToData.points[0].longitude" />
            </div>
          </div>
          <div class="form-item">
            <span>纬度</span>
            <div>
              <a-input v-model:value="flyToData.points[0].latitude" />
            </div>
          </div>
          <div class="form-item">
            <span>高度</span>
            <div>
              <a-input v-model:value="flyToData.points[0].height" />
              m
            </div>
          </div>
        </div>
        <div class="fly-to-button">
          <span @click="stop">结束执行</span>
          <span @click="execute">开始执行</span>
        </div>
      </div>
      <!-- 机场直播面板 -->
      <div class="airport-live-contain" v-show="liveVisible">
        <div class="live-title">
          <span title="刷新">
            <img src="@/assets/images/flightcontrol/refresh.png" alt="刷新" @click="reloadLive" />
          </span>
          <span class="关闭">
            <img src="@/assets/images/flightcontrol/close.png" alt="关闭" @click="closeLive" />
          </span>
        </div>
        <div class="player">
          <video id="player-container-id" :width="width" :height="height" preload="auto" playsinline webkit-playsinline>
          </video>
        </div>
      </div>
      <!-- 智能巡检面板 -->
      <div class="patrol-btn" v-if="patrolVisible">
        <Patrol @changePatrol="changePatrol" />
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
// 导入Vue核心模块
import { ref, computed, onMounted, watch, reactive, nextTick, onUnmounted } from 'vue';
// 导入自定义组件
import { SelectComponent, UavBox, Map, Patrol } from './index';
// 导入状态管理
import { airPortStore } from '@/store/modules/airport';
import { useUserStore } from '@/store/modules/user';
// 导入MQTT工具
import { getClient, createConnection, clientSubscribe, destroyConnection } from '@/utils/mqtt';
// 导入事件总线
import { EventBus } from '@/utils/eventBus';
// 导入API接口
import { GetWorkAreaList } from '@/api/demo/mediaLibrary';
import {
  getDronePortInfoFromRedis,
  saveHandFlyTask,
  getLastHandFlyTask,
} from '@/api/workmanagement/droneDock';
import { getOperationLogList, isCanFly } from '@/api/workmanagement/airportMaintenance';
// 导入工具函数
import { WktToGeojson } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import { buildGUID, uuid } from '@/utils/uuid';
import {
  servicesTopic,
  services_replyTopic,
  errorName,
  unServices_replyTopic,
} from '@/utils/debugging/remote';
import { servicesTopicReize } from '@/utils/debugging/events';
// 导入UI组件
import {
  CloseCircleOutlined,
  MinusCircleFilled,
  CheckCircleFilled,
  CloseCircleFilled,
  CloseOutlined,
} from '@ant-design/icons-vue';
import { useMessage } from '@/hooks/web/useMessage';
// 导入第三方库
import axios from 'axios';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //引入插件和样式文件
import { io, Socket } from 'socket.io-client';
import { getAppEnvConfig } from '@/utils/env';
const { VITE_GLOB_PY_WS_URL } = getAppEnvConfig();
// 消息提示实例
const { createConfirm, createMessage } = useMessage();
// 飞行器控制盒引用
const uavBox = ref();

// 地图高度
const mapHeight = ref(document.documentElement.clientHeight - 124);
// 机场状态存储
const airPortStoreVal = airPortStore();
const airPortInfo = airPortStoreVal.getAirport;
const live_info = airPortStoreVal.getLiveInfo;
const uavInfo = airPortStoreVal.getUAV;
const typeId = airPortStoreVal.getTypeId;
// 直播相关
const liveCode = ref(airPortInfo.sn);
const airportName = ref(airPortInfo.name);
// 用户信息
const userStore = useUserStore();
const userInfo = userStore.getUserInfo;

// 机场OSD信息
const airporOsdVal = ref({
  flighttask_step_code: 256, // 飞行任务步骤代码
  temperature: 0, // 温度
  rainfall: 0, // 雨量
  wind_speed: 0, // 风速
  rate: 0, // 网络速率
});

// 位置信息
const locationVal: any = ref({});
// 机场位置信息
const airPort = ref({
  latitude: null, // 纬度
  longitude: null, // 经度
  height: null, // 高度
});

// 无人机轨迹
const uavTrack = ref({});
// 工作区域数据
const allAreaDataList: any = ref([]);
// 选择值
const changeSelectValue = ref();
// 飞行器控制盒可见性
const uavBoxVisible = ref(false);
// 飞行日志可见性
const logVisible = ref(false);
// 飞行日志选项
const flyOptions = ref(airPortStoreVal.getflyLog);
// 指点飞行可见性
const flyToVisible = ref(false);

// Socket相关
const socket = ref<Socket | null>(null);
const socketConnected = ref(false);
const socketUrl = ref(`${VITE_GLOB_PY_WS_URL}`); // Socket服务器地址

// 连接Socket服务
const connectSocket = () => {
  try {
    if (socket.value) {
      socket.value.disconnect();
    }

    socket.value = io(socketUrl.value, {
      transports: ['websocket'],
      reconnection: true,
      reconnectionAttempts: 5,
      reconnectionDelay: 1000
    });

    socket.value.on('connect', () => {
      console.log('Socket连接成功');
      socketConnected.value = true;
      airPortStoreVal.setflyLog({
        type: 'info',
        title: 'Socket连接',
        content: 'Socket服务连接成功'
      });
    });

    socket.value.on('disconnect', () => {
      console.log('Socket断开连接');
      socketConnected.value = false;
      airPortStoreVal.setflyLog({
        type: 'info',
        title: 'Socket连接',
        content: 'Socket服务断开连接'
      });
    });

    socket.value.on('task_status_update', (data) => {
      console.log('任务状态更新:', data);
      airPortStoreVal.setflyLog({
        type: 'info',
        title: '任务状态更新',
        content: `任务 ${data.task_id} 状态: ${data.status}`
      });
    });

    socket.value.on('inference_result', (data) => {
      console.log('推理结果:', data);
      airPortStoreVal.setflyLog({
        type: 'info',
        title: '推理结果',
        content: `任务 ${data.task_id} 模型 ${data.model_id} 推理完成`
      });
    });

    socket.value.on('system_notification', (data) => {
      console.log('系统通知:', data);
      airPortStoreVal.setflyLog({
        type: data.type === 'error' ? 'error' : 'info',
        title: '系统通知',
        content: data.message
      });
    });

    socket.value.on('connect_error', (error) => {
      console.error('Socket连接错误:', error);
      socketConnected.value = false;
      airPortStoreVal.setflyLog({
        type: 'error',
        title: 'Socket连接',
        content: `Socket服务连接失败: ${error.message}`
      });
    });

  } catch (error) {
    console.error('连接Socket服务失败:', error);
    airPortStoreVal.setflyLog({
      type: 'error',
      title: 'Socket连接',
      content: `连接Socket服务失败: ${error.message}`
    });
  }
};

// 断开Socket连接
const disconnectSocket = () => {
  if (socket.value) {
    socket.value.disconnect();
    socket.value = null;
    socketConnected.value = false;
    console.log('Socket连接已断开');
  }
};

// 订阅任务
const subscribeTask = (taskId: string) => {
  if (socket.value && socketConnected.value) {
    socket.value.emit('subscribe_task', { task_id: taskId }, (response: any) => {
      console.log('订阅任务响应:', response);
      if (response.status === 'subscribed') {
        airPortStoreVal.setflyLog({
          type: 'info',
          title: '任务订阅',
          content: `成功订阅任务 ${taskId}`
        });
      } else {
        airPortStoreVal.setflyLog({
          type: 'error',
          title: '任务订阅',
          content: `订阅任务失败: ${response.message}`
        });
      }
    });
  } else {
    airPortStoreVal.setflyLog({
      type: 'error',
      title: '任务订阅',
      content: 'Socket未连接，无法订阅任务'
    });
  }
};

// 处理任务提交事件
const handleTaskSubmitted = (data: any) => {
  console.log('接收到任务提交事件:', data);
  if (data.success && data.taskId) {
    // 连接Socket服务
    connectSocket();

    // 延迟订阅任务，确保Socket连接成功
    setTimeout(() => {
      subscribeTask(data.taskId);
    }, 1000);

    // 显示飞行日志面板
    logVisible.value = true;

    // 记录任务提交成功日志
    airPortStoreVal.setflyLog({
      type: 'success',
      title: '任务提交',
      content: `智能巡检任务提交成功，已连接Socket服务监听任务状态`
    });
  }
};
// 指点飞行数据
const flyToData = reactive({
  fly_to_id: buildGUID(),
  max_speed: 10,
  points: [{}],
});
// 直播可见性
const liveVisible = ref(false);
// 巡检可见性
const patrolVisible = ref(false);

// 飞行日志滚动容器引用
const myDiv = ref(null);

// 监听飞行日志变化，自动滚动到底部
watch(
  () => flyOptions.value,
  () => {
    nextTick(() => {
      if (myDiv.value) {
        (myDiv.value as HTMLElement).scrollTop = (myDiv.value as HTMLElement).scrollHeight;
      }
    });
  },
  { deep: true }
);

// 视频播放器实例
let player;
// 播放器尺寸
const width = ref(300);
const height = ref(200);

// MQTT连接状态
const connected = ref(false);
const connectCallback = () => {
  connected.value = true;
};

// 机场MQTT主题
const topicUrl = computed(() => {
  return 'thing/product/' + airPortInfo.sn + '/osd';
});
// 无人机MQTT主题
const topicUAVUrl = computed(() => {
  return 'thing/product/' + uavInfo.sn + '/osd';
});
// 机场选择变更处理
const changeSelect = async (value?: any) => {
  if (value) {
    changeSelectValue.value = value;
    airportName.value = value.airportName;
  }
  // 订阅机场消息
  const topicUrl = 'thing/product/' + airPortInfo.sn + '/osd';
  clientSubscribe(topicUrl, { qos: 1 });

  // 获取机场信息
  getDronePortInfoFromRedis({ key: value.airport }).then((res) => {
    const rs = JSON.parse(res);
    // 设置机场位置信息
    airPort.value.latitude = rs.lat;
    airPort.value.longitude = rs.lng;
    airPort.value.height = rs.height;

    // 如果设备在线，查询任务信息
    if (rs.device_online_status == 1) {
      getLastHandFlyTask({ sn: airPortInfo.sn }).then((res) => {
        if (res.Status == 1 || res.Status == 6) {
          // 设置任务ID
          airPortStoreVal.setTaskId(res.Id);
          // 获取操作日志
          getOperationLogList({ taskid: res.Id, page: 1, limit: 1000 }).then((res) => {
            const optiosns = [];
            res.items.forEach((element) => {
              optiosns.push(JSON.parse(element.data));
            });
            // 更新飞行日志
            airPortStoreVal.setflyLog(optiosns, 'replace');
            flyOptions.value = optiosns;
          });
        }
      });
    }
  });

  // 订阅飞行器消息
  const topicUAVUrl = 'thing/product/' + uavInfo.sn + '/osd';
  clientSubscribe(topicUAVUrl, { qos: 1 });
};

// 打开飞行器控制盒
const openUavBox = () => {
  getDronePortInfoFromRedis({ key: airPortInfo.sn }).then((res) => {
    const rs = JSON.parse(res);
    if (rs.device_online_status == 1) {
      // 显示飞行器控制盒
      uavBoxVisible.value = true;
      // 调整地图高度
      nextTick(() => {
        mapHeight.value = uavBox.value.clientHeight;
        console.log(uavBox.value.clientHeight);
      });
    } else {
      // 提示飞行器未开机
      createMessage.warning('飞行器未开机');
    }
  });
};
// 地图点击定位
const flyToThere = (e) => {
  // 存储位置信息
  locationVal.value.lat = e._lat;
  locationVal.value.lng = e._lng;
  locationVal.value.alt = e._alt;
  // 触发位置获取事件
  EventBus.emit('obtainTheLocation', locationVal.value);
};
// 获取几何类型
function getGeomType(area) {
  let geom = area.geom;
  let radiusFlag = area.properties.indexOf('radius') > -1 ? true : false;
  // 点类型
  if (geom.indexOf('POINT') > -1 && !radiusFlag) {
    return 'Point';
  }
  // 线类型
  if (geom.indexOf('LINESTRING') > -1 && !radiusFlag) {
    return 'Polyline';
  }
  // 多边形类型
  if (geom.indexOf('POLYGON') > -1 && !radiusFlag) {
    return 'Polygon';
  }
  // 圆形类型
  if (geom.indexOf('POINT') > -1 && radiusFlag) {
    return 'Circle';
  }
}
// 飞行任务ID
const flight_id = ref(uuid(14, 14));
// 一键起飞
const takeOff = () => {
  createConfirm({
    iconType: 'info',
    title: '一键起飞',
    content: '确定要一键起飞吗？',
    onOk: async () => {
      // 显示飞行日志
      logVisible.value = true;

      // 起飞参数
      const data = {
        flight_id: flight_id.value,
        security_takeoff_height: 100, // 安全起飞高度
        rth_altitude: 115, // 返航高度
        rth_mode: 1, // 返航模式
        max_speed: 10, // 最大速度
        commander_flight_mode: 1, // 指挥官飞行模式
        rc_lost_action: 2, // 遥控器丢失动作
        commander_mode_lost_action: 1, // 指挥官模式丢失动作
        commander_flight_height: 115.0, // 指挥官飞行高度
        flight_safety_advance_check: 1, // 飞行安全预先检查
        target_height: Number(airPort.value.height) + 100, // 目标高度
        target_latitude: Number(airPort.value.latitude), // 目标纬度
        target_longitude: Number(airPort.value.longitude), // 目标经度
      };

      // 适配不同类型的机场
      if (typeId == 'Dock 1') {
        delete data.rth_mode;
        delete data.flight_safety_advance_check;
      }

      // 构建请求参数
      const querys = {
        bid: buildGUID(),
        data: data,
        tid: buildGUID(),
        timestamp: new Date().getTime(),
        method: 'takeoff_to_point',
      };

      console.log(querys);

      // 检查设备状态
      getDronePortInfoFromRedis({ key: airPortInfo.sn }).then((res) => {
        const rs = JSON.parse(res);
        if (rs.device_online_status == 1) {
          // 设备已开机，不能起飞
          airPortStoreVal.setflyLog({
            type: 'info',
            title: '飞行器已开机',
            content: '不能进行起飞操作',
          });
        } else {
          // 检查是否可以飞行
          isCanFly({
            sn: airPortInfo.sn,
            dock: airPortInfo.getTypeId,
            userid: userInfo.id,
          }).then((res) => {
            console.log(res);
            if (res.status) {
              // 发送起飞指令
              servicesTopic(querys);
              services_replyTopic();
            } else {
              // 起飞被阻止
              airPortStoreVal.setflyLog({
                type: 'error',
                title: '一键起飞阻止',
                content: res.msg,
              });
            }
          });
        }
      });
    },
  });
};
// 直播任务ID
const startTid = buildGUID();
// 获取并显示机场直播
const getRtmpList = () => {
  // 显示直播面板
  liveVisible.value = true;
  liveCode.value = airPortInfo.sn;

  // 查询直播流列表
  axios.get(live_info.getUrl + 'api/v1/streams/').then((res) => {
    console.log(res);
    if (res.data.streams.length > 0) {
      console.log(res.data.streams);
      // 查找当前机场的直播流
      const index = res.data.streams.findIndex((item) => item.url === `/live/` + airPortInfo.sn);
      console.log(index);
      if (index == -1) {
        // 未找到直播流，启动直播
        startLiveFun();
      } else {
        // 检查直播流是否活跃
        if (res.data.streams[index].publish.active) {
          // 播放直播
          reloadLive()
          // 记录日志
          airPortStoreVal.setflyLog({
            type: 'success',
            title: airPortInfo.name + '直播',
            content: '已开启',
          });
        } else {
          // 直播流未活跃，启动直播
          startLiveFun();
        }
      }
    } else {
      // 无直播流，启动直播
      startLiveFun();
    }
  });
};
// 启动直播
const startLiveFun = () => {
  // 构建直播启动参数
  const querys = {
    bid: buildGUID(),
    method: 'live_start_push',
    tid: startTid,
    timestamp: new Date().getTime(),
    data: {
      url_type: 1, // 0 = 自适应；如需 RTMP 改为 1；GB28181 为 3；WebRTC 为 4
      url: live_info.rtmp + liveCode.value,
      video_id: airPortInfo.video_id,
      video_quality: 3, // 0=自适应，1=流畅，2=标清，3=高清，4=超清
    },
  };

  console.log(querys);
  // 发送直播启动指令
  servicesTopic(querys);
  services_replyTopic();
};
// 重新加载直播
const reloadLive = () => {
  let liveUrl = `${live_info.url}/${liveCode.value}.flv`
  if(player){
    player.src(liveUrl);
    player.play();
  }else{
    // 初始化视频播放器
    player = TCPlayer('player-container-id', {
      sources: [
        {
          src: liveUrl, // 播放地址
        },
      ],
      autoplay: true, // 是否自动播放
    });
  }
};
// 停止直播任务ID
const stopTid = buildGUID();
// 关闭直播
const closeLive = () => {
  // 隐藏直播面板
  liveVisible.value = false;
};
// 打开指点飞行面板
const flyTobtn = () => {
  flyToVisible.value = true;
  EventBus.emit('flyTobtn', '');
};
// 执行指点飞行
const execute = () => {
  // 检查是否选择了目标点
  if (
    flyToData.points[0].latitude == null ||
    flyToData.points[0].longitude == null ||
    flyToData.points[0].height == null
  ) {
    createMessage.warning('请先选择目标点');
    return;
  }

  // 转换坐标类型为数字
  flyToData.points[0].latitude = Number(flyToData.points[0].latitude);
  flyToData.points[0].longitude = Number(flyToData.points[0].longitude);
  flyToData.points[0].height = Number(flyToData.points[0].height);

  // 构建指点飞行参数
  const querys = {
    bid: buildGUID(),
    data: flyToData,
    tid: buildGUID(),
    timestamp: new Date().getTime(),
    method: 'fly_to_point',
  };

  console.log(querys);
  // 发送指点飞行指令
  servicesTopic(querys);
};
// 停止指点飞行
const stop = () => {
  // 构建停止指令参数
  const querys = {
    bid: buildGUID(),
    data: {},
    tid: buildGUID(),
    timestamp: new Date().getTime(),
    method: 'fly_to_point_stop',
  };

  console.log(querys);
  // 发送停止指令
  servicesTopic(querys);
};
// 打开智能巡检面板
const patrolbtn = () => {
  patrolVisible.value = true;
};
// 关闭智能巡检面板
const changePatrol = () => {
  patrolVisible.value = false;
};
// 监听机场选择变化，加载工作区域数据
watch(
  () => changeSelectValue.value,
  async () => {
    // 获取工作区域列表
    allAreaDataList.value = await GetWorkAreaList({
      workspaceid: changeSelectValue.value.project,
    });
    // 处理工作区域数据
    if (allAreaDataList.value.length > 0) {
      allAreaDataList.value.forEach((area, index) => {
        // 转换WKT为GeoJSON
        let geomjson = WktToGeojson(area.geom);
        // 更新区域数据
        area = {
          ...area,
          properties: JSON.parse(area.properties),
          geomtype: getGeomType(area),
          coordinates: geomjson.coordinates,
        };
        allAreaDataList.value[index] = area;
      });
    }
  },
);

// 方向控制变化处理
const changeDRC = (val) => {
  console.log(val);
};
// 键盘事件超时器
const timeout = ref();
const timeoutUp = ref();
// 键盘按下事件处理
const handleKeyDown = (event) => {
  clearTimeout(timeout.value);
  timeout.value = setTimeout(() => {
    console.log('handleKeyDown', event.key);
    changeDRC(event.key);
  }, 500);
};
// 键盘释放事件处理
const handleKeyUp = (event) => {
  clearTimeout(timeoutUp.value);
  timeoutUp.value = setTimeout(() => {
    console.log('handleKeyUp', event.key);
    changeDRC('');
  }, 500);
};
// 组件挂载时初始化
onMounted(() => {
  console.log('index--onMounted');
  console.log(getClient());

  // 监听窗口大小变化，调整地图高度
  window.addEventListener('resize', function () {
    const pageHeight = document.documentElement.clientHeight;
    console.log(pageHeight);
    mapHeight.value = document.documentElement.clientHeight - 124;
  });

  // 初始化MQTT连接
  if (!getClient() || !getClient().connected) {
    createConnection(connectCallback);
  }

  // 监听键盘事件
  document.addEventListener('keydown', handleKeyDown);
  document.addEventListener('keyup', handleKeyUp);
  if (liveVisible.value && live_info) {
    // 初始化视频播放器
    player = TCPlayer('player-container-id', {
      sources: [
        {
          src: live_info.url + liveCode.value + '.flv', // 播放地址
        },
      ],
      autoplay: true, // 是否自动播放
    });
  }


  // 监听位置获取事件
  EventBus.on('obtainTheLocation', (val: any) => {
    flyToData.points[0].latitude = val.lat.toFixed(6);
    flyToData.points[0].longitude = val.lng.toFixed(6);
    flyToData.points[0].height = val.alt.toFixed(2);
  });

  // 监听MQTT消息
  setTimeout(() => {
    getClient().on('message', (topic, message) => {
      const rs = JSON.parse(message);
      const rsData = rs.data;

      // 处理机场消息
      if (topic === topicUrl.value) {
        if (rsData.flighttask_step_code) {
          airporOsdVal.value.flighttask_step_code = rsData.flighttask_step_code;
        }
        if (rsData.temperature) {
          airporOsdVal.value.temperature = rsData.temperature;
        }
        if (rsData.rainfall) {
          airporOsdVal.value.rainfall = rsData.rainfall;
        }
        if (rsData.wind_speed) {
          airporOsdVal.value.wind_speed = rsData.wind_speed;
        }
        if (rsData.network_state && rsData.network_state.rate) {
          airporOsdVal.value.rate = rsData.network_state.rate;
        }
      }

      // 处理无人机消息
      if (topic == topicUAVUrl.value) {
        if (rsData.latitude && rsData.longitude) {
          uavTrack.value = rs.data;
        }
      }

      // 处理一键起飞消息
      if (rs.method == 'takeoff_to_point') {
        console.log('一键起飞');
        console.log(rs);
        if (rsData.result == 0) {
          // 保存飞行任务
          saveHandFlyTask({
            flightId: flight_id.value,
            workspaceId: airPortStoreVal.getProject,
            sn: airPortInfo.sn,
          }).then((res) => {
            if (res) {
              airPortStoreVal.setTaskId(res.taskId);
              // 记录起飞成功日志
              airPortStoreVal.setflyLog({
                type: 'success',
                title: '一键起飞',
                content: '成功',
                mark: rs.timestamp
                  ? rs.method + '-' + rs.timestamp
                  : rs.method + '-' + new Date().getTime(),
              });
              // 延迟记录起飞中日志
              setTimeout(() => {
                airPortStoreVal.setflyLog({
                  type: 'success',
                  title: '一键起飞',
                  content: '正在起飞，请稍后',
                });
              }, 500);
            }
          });
        } else {
          // 记录起飞失败日志
          airPortStoreVal.setflyLog({
            type: 'error',
            title: '一键起飞',
            content: '失败，' + errorName(rsData.result),
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        }
      }

      // 处理机场直播消息
      if (rs.method == 'live_start_push' && rs.tid == startTid) {
        if (rsData.result == 0) {
          // 开始直播
          player.src(live_info.url + liveCode.value + '.flv');
          player.play();
          // 记录直播成功日志
          airPortStoreVal.setflyLog({
            type: 'success',
            title: airPortInfo.name + '开始直播',
            content: '成功',
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        } else if (rsData.result == 513003) {
          // 直播已开启
          player.src(live_info.url + liveCode.value + '.flv');
          player.play();
          airPortStoreVal.setflyLog({
            type: 'success',
            title: airPortInfo.name + '直播',
            content: '已开启',
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        } else {
          // 记录直播失败日志
          airPortStoreVal.setflyLog({
            type: 'error',
            title: airPortInfo.name + '开始直播',
            content: '失败，' + errorName(rsData.result),
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        }
      } else if (rs.method == 'live_stop_push' && rs.tid == stopTid) {
        if (rs.data.result == 0) {
          // 记录停止直播成功日志
          airPortStoreVal.setflyLog({
            type: 'success',
            title: airPortInfo.name + '停止直播',
            content: '成功',
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        } else {
          // 记录停止直播失败日志
          airPortStoreVal.setflyLog({
            type: 'error',
            title: airPortInfo.name + '停止直播',
            content: '失败,' + errorName(rs.data.result),
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        }
      }

      // 处理指点飞行消息
      if (rs.method == 'fly_to_point') {
        if (rs.data.result == 0) {
          // 记录指点飞行成功日志
          airPortStoreVal.setflyLog({
            type: 'success',
            title: '指点飞行',
            content: '成功',
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
          EventBus.emit('closeTranslation', null);
          // 修改云台的角度至最下方
          const querys = {
            bid: buildGUID(),
            method: 'camera_screen_drag',
            tid: buildGUID(),
            timestamp: new Date().getTime(),
            data: {
              payload_index: uavInfo.camera_index,
              locked: true,
              pitch_speed: -180,
              yaw_speed: 0,
            },
          };
          servicesTopicReize(querys);
        } else {
          // 记录指点飞行失败日志
          airPortStoreVal.setflyLog({
            type: 'error',
            title: '指点飞行',
            content: '失败,' + errorName(rs.data.result),
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        }
      }

      // 处理结束指点飞行消息
      if (rs.method == 'fly_to_point_stop') {
        if (rs.data.result == 0) {
          // 记录结束指点飞行成功日志
          airPortStoreVal.setflyLog({
            type: 'success',
            title: '结束指点飞行',
            content: '成功',
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        } else {
          // 记录结束指点飞行失败日志
          airPortStoreVal.setflyLog({
            type: 'error',
            title: '结束指点飞行',
            content: '失败,' + errorName(rs.data.result),
            mark: rs.timestamp
              ? rs.method + '-' + rs.timestamp
              : rs.method + '-' + new Date().getTime(),
          });
        }
      }
    });
  }, 1000);
});
// 组件卸载时清理
onUnmounted(() => {
  // 取消服务订阅
  unServices_replyTopic();
  // 清理相机设置
  airPortStoreVal.setCamera('type', null);
  airPortStoreVal.setCamera('name', null);
});
</script>
<style lang="less" scoped>
.flight-control {
  background: #00152a;

  .flight-control-top {
    width: 100%;
    background: #10203a;
    height: 42px;
    display: flex;
    align-items: center;
    font-size: 12px;

    .airport-name {
      color: #fff;
      margin-left: 10px;

      img {
        width: 16px;
      }
    }

    .airport-status {
      margin-left: 10px;
      padding: 4px 6px;
      color: #f2762d;
      border-radius: 20px;
      box-shadow:
        0px 10px 30px 0px rgba(0, 0, 6, 0.15),
        0px 7px 6px 0px rgba(28, 29, 34, 0.06),
        inset 0px 1px 3px 0px rgba(0, 0, 0, 0.5);
      border: 1px solid #f2762d;
    }

    .airport-live {
      margin-left: 10px;
      padding: 4px 6px;
      color: #fff;
      border-radius: 20px;
      background: #0377f6;
      cursor: pointer;
    }

    .airport-info {
      margin-left: 10px;
      color: #fff;

      .airport-info-title {
        display: inline-block;
        margin: 0 6px;
        opacity: 0.6;
      }

      img {
        width: 12px;
      }
    }
  }
}

.flight-contain {
  position: relative;
  margin-top: 2px;
  display: flex;
  overflow: auto;

  .uavbox-open {
    position: absolute;
    right: 0;
    top: 0;
    background: #10203a;
    color: #fff;
    z-index: 2;
    padding: 6px;
    cursor: pointer;

    img {
      width: 20px;
    }
  }

  .map-container {
    // width: calc(100% - 44px);
    // height: 90vh;
  }

  .map-container-content {
    width: 100%;
    height: 100%;
  }

  .uav-box {
    width: 62vw;
  }
}

.fly-log {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 15vw;
  height: 50vh;
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
  border-radius: 6px;
  border: 1px solid #3662a5;
  background: #00152a;

  .fly-log-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 20px;
    color: #fff;
    border-bottom: 1px solid #4e5778;

    span:last-child {
      font-size: 20px;
      cursor: pointer;
    }
  }

  .fly-log-content {
    width: 90%;
    height: 40vh;
    box-shadow:
      0px 10px 30px 0px rgba(0, 0, 6, 0.15),
      0px 10px 30px 0px rgba(0, 0, 6, 0.15);
    border-radius: 6px;
    border: 1px solid #3662a5;
    margin: 20px auto;
    background: #10203a;
    padding: 10px 12px;
    color: #fff;

    .fly-status {
      color: #868e9b;
      font-size: 12px;
      margin: 10px 0 20px 0;
    }

    .log-opstions {
      font-size: 14px;
      height: 29vh;
      overflow: scroll;
    }

    .log-item {
      padding: 5px 0;

      .item-desc {
        font-size: 14px;
        color: #fff;
        margin-left: 10px;
      }
    }

    .MinusCircleFilled {
      color: #737d8c;
      font-size: 16px;

      .item-desc {
        color: #737d8c;
      }
    }

    .CheckCircleFilled {
      font-size: 16px;
      color: #1aa053;
    }

    .CloseCircleFilled {
      font-size: 16px;
      color: #0e5528;
    }
  }
}

.fly-to-form {
  position: absolute;
  left: 16.6vw;
  bottom: 90px;
  width: 17vw;
  height: 34vh;
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
  border-radius: 6px;
  border: 1px solid #3662a5;
  background: #00152a;
  color: #fff;

  .fly-to-title {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title-name {
      margin: 10px 0 0 10px;
    }

    .title-icon {
      border: 1px solid #3662a5;
      border-top: none;
      border-right: none;
      border-radius: 6px;
      width: 26px;
      height: 26px;
      text-align: center;
      line-height: 26px;
      cursor: pointer;
    }
  }

  .form-desc {
    color: #f2762d;
    font-size: 12px;
    padding: 14px;
    display: inline-block;
  }

  .form-content {
    padding: 10px 16px;

    .form-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 16px;

      div {
        background: #263f66;
        width: 60%;
        border-radius: 6px;
        border: 1px solid #3662a5;
        height: 34px;
      }

      input {
        background: #263f66;
        width: 140px;
        text-align: right;
        color: #fff;
        font-size: 12px;
        border: none;
      }

      ::v-deep .ant-input-number,
      .ant-input-number-group-wrapper {
        background: none;
        width: 260px !important;
        text-align: right;
        color: #fff;
        font-size: 12px;
      }

      ::v-deep .ant-input-number-group-wrapper {
        input {
          background: none;
          width: 260px !important;
          text-align: right;
          color: #fff;
          font-size: 12px;
        }
      }
    }
  }

  .fly-to-button {
    display: flex;
    align-items: center;
    justify-content: space-around;

    span {
      width: 40%;
      color: '#fff';
      height: 34px;
      border-radius: 6px;
      text-align: center;
      line-height: 34px;
      cursor: pointer;
    }

    span:first-child {
      background: rgba(207, 39, 48, 0.6);
    }

    span:last-child {
      background: #0377f6;
    }
  }
}

.airport-live-contain {
  position: absolute;
  left: 16.6vw;
  top: 20px;
  width: 17vw;
  height: 26vh;
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
  border-radius: 6px;
  border: 1px solid #3662a5;
  background: #00152a;
  color: #fff;

  .live-title {
    display: flex;
    align-items: center;
    justify-content: flex-end;

    img {
      width: 16px;
      cursor: pointer;
    }

    span {
      width: 30px;
      height: 30px;
      border: 1px solid #3662a5;
      text-align: center;
    }
  }
}

.player {
  display: flex;
  justify-content: center;
  align-items: center;

  #player-container-id-live {
    margin: 0 auto;
  }
}

.patrol-btn {
  position: absolute;
  left: 32vw;
  top: 4px;
  width: 16vw;
  height: 59vh;
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
  border-radius: 6px;
  border: 1px solid #3662a5;
  background: #00152a;
  color: #fff;
}
</style>
<style scoped>
body :global(.ant-message-notice) {
  text-align: right;
}
</style>
