package com.multictrl.modules.business.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.service.impl.CrudServiceImpl;
import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.ConvertUtils;
import com.multictrl.common.utils.JsonUtils;
import com.multictrl.common.utils.weather.*;
import com.multictrl.modules.business.dao.WeatherNoflyDao;
import com.multictrl.modules.business.dto.LatLonDTO;
import com.multictrl.modules.business.dto.WeatherNoflyDTO;
import com.multictrl.modules.business.entity.WeatherNoflyEntity;
import com.multictrl.modules.business.service.DJIBaseService;
import com.multictrl.modules.business.service.WeatherNoflyService;
import cn.hutool.core.util.StrUtil;
import com.multictrl.modules.business.service.WeatherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 天气阻飞
 *
 * @author Sdy
 * @since 1.0.0 2026-06-15
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WeatherNoflyServiceImpl extends CrudServiceImpl<WeatherNoflyDao, WeatherNoflyEntity, WeatherNoflyDTO> implements WeatherNoflyService {
    private final DJIBaseService djiBaseService;
    private final WeatherService weatherService;

    @Override
    public QueryWrapper<WeatherNoflyEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<WeatherNoflyEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);

        return wrapper;
    }

    @Override
    public WeatherNoflyDTO getInfoByDockSn(String dockSn) {
        WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>().eq("dock_sn", dockSn));
        return ConvertUtils.sourceToTarget(entity, WeatherNoflyDTO.class);
    }

    @Override
    public void addWeatherNofly(WeatherNoflyDTO dto) {
        WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>().eq("dock_sn", dto.getDockSn()));
        if (entity != null) {
            deleteById(entity.getId());
        }
        save(dto);
    }

    @Override
    public JSONObject allowFlight(String dockSn, boolean isJobTask) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("isAllow", true);
        //查询机库是否有阻飞信息
        WeatherNoflyEntity entity = baseDao.selectOne(new QueryWrapper<WeatherNoflyEntity>()
                .eq("dock_sn", dockSn).eq("is_open", true));
        if (entity != null) {//存在阻飞设置
            Boolean isAllPrevent = entity.getIsAllPrevent();
            if (isAllPrevent || isJobTask) {
                Boolean isOpenWeather = entity.getIsOpenWeather();//判断天气阻飞
                if (isOpenWeather) {
                    LatLonDTO dockLocation = djiBaseService.getDockLocation(dockSn);
                    String weatherString = weatherService.getWeatherByLonLat(dockLocation.getLongitude(), dockLocation.getLatitude());
                    JSONObject weatherObject = JsonUtils.parseObject(weatherString, JSONObject.class);
                    if (weatherObject != null) {
                        //风速判断
                        String windpower = weatherObject.getStr("windpower");//风力级别
                        double maxWindSpeed = WindSpeedConverter.getMaxWindSpeed(windpower);
                        if (maxWindSpeed >= entity.getWindSpeedWeather()) {
                            log.info("风力过大，级别：{}，最大风速：{}，阀值：{}", windpower, maxWindSpeed, entity.getWindSpeedWeather());
                            jsonObject.set("isAllow", false);
                            jsonObject.set("reason", "风力过大，阀值：{" + entity.getWindSpeedWeather() + "}，起飞时风速：{" + maxWindSpeed + "}");
                        }

                        //温度判断
                        double temperature = Double.parseDouble(weatherObject.getStr("temperature"));//温度
                        if (temperature < entity.getTemperatureMin()) {
                            log.info("气温过低，当前温度：{}，设置温度下限：{}", temperature, entity.getTemperatureMin());
                            jsonObject.set("isAllow", false);
                            jsonObject.set("reason", "气温过低，阀值：{" + entity.getTemperatureMin() + "}，起飞时温度：{" + temperature + "}");
                        }
                        if (temperature > entity.getTemperatureMax()) {
                            log.info("气温过高，当前温度：{}，设置温度上限：{}", temperature, entity.getTemperatureMax());
                            jsonObject.set("isAllow", false);
                            jsonObject.set("reason", "气温过高，阀值：{" + entity.getTemperatureMax() + "}，起飞时温度：{" + temperature + "}");
                        }

                        String weather = weatherObject.getStr("weather");//天气现象
                        //雨量判断
                        Integer rainfallWeather = entity.getRainfallWeather();
                        if (rainfallWeather > 0) {
                            if (rainfallWeather == 1) {
                                if (RainfallUtils.isMinRain(weather) || RainfallUtils.isModerateRain(weather) || RainfallUtils.isMaxRain(weather)) {
                                    log.info("已达雨量上限，设置：小雨，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雨量{小雨}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (rainfallWeather == 2) {
                                if (RainfallUtils.isModerateRain(weather) || RainfallUtils.isMaxRain(weather)) {
                                    log.info("已达雨量上限，设置：中雨，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雨量{中雨}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (rainfallWeather == 3) {
                                if (RainfallUtils.isMaxRain(weather)) {
                                    log.info("已达雨量上限，设置：大雨，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雨量{大雨}阻飞，起飞时天气：{" + weather + "}");
                                }
                            }
                        }

                        //雪量判断
                        Integer snowWeather = entity.getSnowWeather();
                        if (snowWeather > 0) {
                            if (snowWeather == 1) {
                                if (SnowUtils.isMinSnow(weather) || SnowUtils.isModerateSnow(weather) || SnowUtils.isMaxSnow(weather)) {
                                    log.info("已达雪量上限，设置：小雪，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雪量{小雪}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (snowWeather == 2) {
                                if (SnowUtils.isModerateSnow(weather) || SnowUtils.isMaxSnow(weather)) {
                                    log.info("已达雪量上限，设置：中雪，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雪量{中雪}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (snowWeather == 3) {
                                if (SnowUtils.isMaxSnow(weather)) {
                                    log.info("已达雪量上限，设置：大雪，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雪量{大雪}阻飞，起飞时天气：{" + weather + "}");
                                }
                            }
                        }

                        //雾量判断
                        Integer fogWeather = entity.getFogWeather();
                        if (fogWeather > 0) {
                            if (fogWeather == 1) {
                                if (FogUtils.isMinFog(weather) || FogUtils.isModerateFog(weather) || FogUtils.isMaxFog(weather)) {
                                    log.info("已达雾量上限，设置：轻雾，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雾量{轻雾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (fogWeather == 2) {
                                if (FogUtils.isModerateFog(weather) || FogUtils.isMaxFog(weather)) {
                                    log.info("已达雾量上限，设置：中雾，当前：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雾量{中雾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (fogWeather == 3) {
                                if (FogUtils.isMaxFog(weather)) {
                                    log.info("已达雾量上限，设置：大雾，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发雾量{大雾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            }
                        }

                        //霾量判断
                        Integer hazeWeather = entity.getHazeWeather();
                        if (hazeWeather > 0) {
                            if (hazeWeather == 1) {
                                if (HazeUtils.isMinHaze(weather) || HazeUtils.isModerateHaze(weather) || HazeUtils.isMaxHaze(weather)) {
                                    log.info("已达霾量上限，设置：轻度霾，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发霾量{轻度霾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (hazeWeather == 2) {
                                if (HazeUtils.isModerateHaze(weather) || HazeUtils.isMaxHaze(weather)) {
                                    log.info("已达霾量上限，设置：中度霾，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发霾量{中度霾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            } else if (hazeWeather == 3) {
                                if (HazeUtils.isMaxHaze(weather)) {
                                    log.info("已达霾量上限，设置：重度霾，实际：{}", weather);
                                    jsonObject.set("isAllow", false);
                                    jsonObject.set("reason", "触发霾量{重度霾}阻飞，起飞时天气：{" + weather + "}");
                                }
                            }
                        }

                        //冰雹判断
                        Boolean isHailWeather = entity.getIsHailWeather();
                        if (isHailWeather) {
                            if ("雷阵雨并伴有冰雹".equals(weather)) {
                                log.info("已达冰雹阻飞，设置：开启冰雹阻飞，实际：{}", weather);
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发冰雹阻飞，起飞时天气：{" + weather + "}");
                            }
                        }

                        //沙尘暴判断
                        Boolean isSandstormWeather = entity.getIsSandstormWeather();
                        if (isSandstormWeather) {
                            if ("沙尘暴".equals(weather) || "强沙尘暴".equals(weather)) {
                                log.info("已达沙尘暴阻飞，设置：开启沙尘暴阻飞，实际：{}", weather);
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发沙尘暴阻飞，起飞时天气：{" + weather + "}");
                            }
                        }

                        //龙卷风判断
                        Boolean isTornadoWeather = entity.getIsTornadoWeather();
                        if (isTornadoWeather) {
                            if ("龙卷风".equals(weather)) {
                                log.info("已达龙卷风阻飞，设置：开启龙卷风阻飞，实际：{}", weather);
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发龙卷风阻飞，起飞时天气：{" + weather + "}");
                            }
                        }
                    }
                }

                //云端阻飞
                Integer rainfall = entity.getRainfall();
                Double windSpeed = entity.getWindSpeed();
                JSONObject data = (JSONObject) CacheUtils.get(BusinessConstant.DOCK_OSD + dockSn);
                if (data != null) {
                    if (rainfall == 1 || rainfall == 2 || rainfall == 3) {
                        //0无雨 1小雨 2中雨 3大雨
                        int value = data.getInt("rainfall");
                        if (rainfall == 1) {
                            if (value >= 1) {
                                String message = value == 1 ? "小雨" : value == 2 ? "中雨" : "大雨";
                                log.info("已达下雨阻飞，设置：小雨阻飞,实际：{}", message);
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发下雨阻飞，起飞时天气：{" + message + "}");
                            }
                        }
                        if (rainfall == 2) {
                            if (value >= 2) {
                                String message = value == 2 ? "中雨" : "大雨";
                                log.info("已达下雨阻飞，设置：中雨阻飞,实际：{}", message);
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发下雨阻飞，起飞时天气：{" + message + "}");
                            }
                        }
                        if (rainfall == 3) {
                            if (value >= 3) {
                                log.info("已达下雨阻飞，设置：大雨阻飞,实际：{大雨}");
                                jsonObject.set("isAllow", false);
                                jsonObject.set("reason", "触发下雨阻飞，起飞时天气：{大雨}");
                            }
                        }
                    }
                    //风速
                    Float value = data.getFloat("wind_speed");
                    if (value >= windSpeed) {
                        log.info("风力过大，设置:风速阻飞：{}，实际风速：{}", windSpeed, value);
                        jsonObject.set("isAllow", false);
                        jsonObject.set("reason", "风力过大，阀值：{" + windSpeed + "}，起飞时风速：{" + value + "}");
                    }
                }
            }
        }

        return jsonObject;
    }
}