package com.multictrl.modules.business.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.constant.DockMode;
import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.influxdb.UavReport;
import com.multictrl.modules.business.service.DockService;
import com.multictrl.modules.business.service.FlightTaskService;
import com.multictrl.modules.business.service.InfluxService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * osd设备属性定频上报0.5HZ
 *
 * @author Sdy
 * @since 1.0.0 2026/4/24
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OsdHandler implements MessageHandler {
    private static final String GPS_ZERO = "0.000000";
    private final InfluxService influxService;
    private final FlightTaskService flightTaskService;
    private final DockService dockService;

    @Override
    public void handleMessage(String topic, String payload, String gateway) {
        JSONObject message = JsonUtils.parseObject(payload, JSONObject.class);
        if (message != null) {
            String dockSn = message.getStr(BusinessConstant.GATEWAY);
            JSONObject data = message.getJSONObject(BusinessConstant.DATA);
            if (gateway.equals(dockSn)) {
//                log.debug("dock osd --> topic: {}, payload: {}", topic, payload);
                if (data.containsKey("network_state")) {//网络状态，机库osd分3次上报信息，只有网络状态对程序有用，其他前端展示即可
                    CacheUtils.set(BusinessConstant.DOCK_OSD + dockSn, data, 1000 * 5);
                    //判断飞行结束，从“任务中”切到“空闲“
                    if (data.containsKey("mode_code")) {
                        int modeCode = data.getInt("mode_code", -1);
                        //任务中
                        if (modeCode == DockMode.WORKING.getCode()) {
                            if (CacheUtils.get(BusinessConstant.DOCK_IN_WORK + dockSn) == null) {
                                flightTaskService.updateTaskStart(dockSn);
                                log.debug("{}机库架次开始，更新架次表", dockSn);
                                //更新机库经纬度
                                dockService.updateDockLocation(dockSn, data);
                            }
                            CacheUtils.set(BusinessConstant.DOCK_IN_WORK + dockSn, true);
                        }
                        //刚从“任务中”切到“空闲“，说明架次结束入库了
                        if (modeCode == DockMode.IDLE.getCode() && CacheUtils.get(BusinessConstant.DOCK_IN_WORK + dockSn) != null) {
                            CacheUtils.delete(BusinessConstant.DOCK_IN_WORK + dockSn);
                            log.debug("{}机库架次飞行完成，取消DRC心跳", dockSn);
                            List<String> list = Optional.ofNullable(CacheUtils.get(BusinessConstant.DRC_HEART_BEAT_SN))
                                    .filter(obj -> obj instanceof List)
                                    .map(obj -> (List<String>) obj)
                                    .orElse(Collections.emptyList());
                            if (CollUtil.isNotEmpty(list)) {
                                list.remove(dockSn);
                            }
                            //更新架次表
                            flightTaskService.updateTaskComplete(dockSn);
                            log.debug("{}机库架次结束，更新架次表", dockSn);
                        }
                    }
                }
            } else {
//                log.debug("uav osd --> topic: {}, payload: {}", topic, payload);
                CacheUtils.set(BusinessConstant.UAV_OSD + dockSn, data);
                //保存无人机状态 {"0":"待机","1":"起飞准备","2":"起飞准备完毕","3":"手动飞行","4":"自动起飞","5":"航线飞行","6":"全景拍照","7":"智能跟随","8":"ADS-B 躲避","9":"自动返航","10":"自动降落","11":"强制降落","12":"三桨叶降落","13":"升级中","14":"未连接","15":"APAS","16":"虚拟摇杆状态","17":"指令飞行","18":"空中 RTK 收敛模式","19":"机场选址中","20":"POI环绕","21":"进离场航线飞行过程中"}
                Integer mode = data.getInt("mode_code");
                if (mode != null) {
                    CacheUtils.set(BusinessConstant.UAV_MODE_CODE + dockSn, mode, 1000 * 5);
                }
                //保存osd到influxdb
                String latitude = data.getStr("latitude");
                String longitude = data.getStr("longitude");
                if (latitude != null && longitude != null && !GPS_ZERO.equals(latitude) && !GPS_ZERO.equals(longitude)) {
                    String payload_index = data.getJSONArray("cameras") != null ?
                            data.getJSONArray("cameras").getJSONObject(0).getStr("payload_index") : null;
                    //获取电池电量，如果单电池则把 a赋值给b
                    int capacity_percent_a;
                    int capacity_percent_b;
                    JSONArray batteries = data.getJSONObject("battery").getJSONArray("batteries");
                    capacity_percent_a = batteries.getJSONObject(0).getInt("capacity_percent");
                    if (batteries.size() > 1) {
                        capacity_percent_b = batteries.getJSONObject(1).getInt("capacity_percent");
                    } else {
                        capacity_percent_b = capacity_percent_a;
                    }

                    UavReport uavReport = UavReport.builder()
                            .dockSn(dockSn)
                            .obstacle_avoidance_horizon(data.getJSONObject("obstacle_avoidance").getInt("horizon"))
                            .obstacle_avoidance_upside(data.getJSONObject("obstacle_avoidance").getInt("upside"))
                            .obstacle_avoidance_downside(data.getJSONObject("obstacle_avoidance").getInt("downside"))
                            .is_near_area_limit(data.getInt("is_near_area_limit"))
                            .is_near_height_limit(data.getInt("is_near_height_limit"))
                            .payload_index(payload_index)
                            .gimbal_pitch(payload_index != null ? data.getJSONObject(payload_index).getDouble("gimbal_pitch") : null)
                            .gimbal_roll(payload_index != null ? data.getJSONObject(payload_index).getDouble("gimbal_roll") : null)
                            .gimbal_yaw(payload_index != null ? data.getJSONObject(payload_index).getDouble("gimbal_yaw") : null)
                            .zoom_factor(payload_index != null ? data.getJSONObject(payload_index).getDouble("zoom_factor") : null)
                            .track_id(data.getStr("track_id"))
                            .position_state_is_fixed(data.getJSONObject("position_state").getInt("is_fixed"))
                            .position_state_is_quality(data.getJSONObject("position_state").getInt("quality"))
                            .position_state_is_gps_number(data.getJSONObject("position_state").getInt("gps_number"))
                            .position_state_is_rtk_number(data.getJSONObject("position_state").getInt("rtk_number"))
                            .battery_capacity_percent(data.getJSONObject("battery").getInt("capacity_percent"))
                            .battery_remain_flight_time(data.getJSONObject("battery").getInt("remain_flight_time"))
                            .battery_return_home_power(data.getJSONObject("battery").getInt("return_home_power"))
                            .battery_landing_power(data.getJSONObject("battery").getInt("landing_power"))
                            .battery_capacity_percent_a(capacity_percent_a)
                            .battery_capacity_percent_b(capacity_percent_b)
                            .wind_direction(data.getInt("wind_direction"))
                            .wind_speed(data.getDouble("wind_speed"))
                            .home_distance(data.getDouble("home_distance"))
                            //state上报
//                                .home_latitude(data.getDouble("home_latitude"))
//                                .home_longitude(data.getDouble("home_longitude"))
                            .attitude_head(data.getInt("attitude_head"))
                            .attitude_roll(data.getDouble("attitude_roll"))
                            .attitude_pitch(data.getDouble("attitude_pitch"))
                            .elevation(data.getDouble("elevation"))
                            .height(data.getDouble("height"))
                            .latitude(data.getDouble("latitude"))
                            .longitude(data.getDouble("longitude"))
                            .vertical_speed(data.getDouble("vertical_speed"))
                            .horizontal_speed(data.getDouble("horizontal_speed"))
                            .build();
                    influxService.addRecord(uavReport);
                }
            }
        } else {
            log.debug("osd --> payload解析失败，解析后为null");
        }
    }
}
