package com.tuoheng.admin.service.inspection.update.status;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.constant.SystemConstant;
import com.tuoheng.admin.entity.domain.Business;
import com.tuoheng.admin.entity.domain.FlightData;
import com.tuoheng.admin.entity.domain.Inspection;
import com.tuoheng.admin.entity.domain.Report;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.code.inspection.EditInspectionStatusCodeEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.service.third.dsp.IDspService;
import com.tuoheng.admin.utils.AirWeatherUtil;
import com.tuoheng.admin.entity.vo.AirWeatherVO;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UpdateWaittStatusService {

    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private FlightDataMapper flightDataMapper;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private IDspService dspService;

    public void updateWaittStatus(Inspection inspection) {
        Inspection inspectionUpdate = new Inspection();
        inspectionUpdate.setId(inspection.getId());
        inspectionUpdate.setStatus(TaskStatusEnum.COMPLETE.getCode());
        inspectionUpdate.setExecutionEndTime(DateUtils.now());

        List<Business> businessList = businessMapper.selectList(new LambdaQueryWrapper<Business>()
                                        .eq(Business::getTypeId, inspection.getId())
                                        .eq(Business::getMark, MarkEnum.VALID.getCode())
                                        .orderByDesc(Business::getCreateTime));

        if (CollectionUtil.isEmpty(businessList)) {
            log.info("业务数据为空");
            inspectionMapper.updateById(inspectionUpdate);
            return;
        }

        // 硬件停止后，停止AI分析
        dspService.stopAI(businessList.get(0).getMsgId(), inspection.getId());

        //获取天气信息
        JsonResult result =  this.getWeather(CommonConfig.airportURL, inspection.getAirportId());
        if (0 != result.getCode()) {
            log.info("修改任务状态业务接口：获取天气信息失败：{}", result.getMsg());
            inspectionUpdate.setWeather("");
            inspectionMapper.updateById(inspectionUpdate);
            return;
        } else {
            log.info("修改任务状态业务接口：获取天气信息：{}", result.getData());
        }
        AirWeatherVO weather = (AirWeatherVO) result.getData();
        String weatherStr = AirWeatherUtil.getWeather(weather);
        log.info("修改任务状态业务接口：获取天气信息：weatherStr={}", weatherStr);
        inspectionUpdate.setWeather(weatherStr);

        Integer flightDataCount = flightDataMapper.selectCount(new LambdaQueryWrapper<FlightData>()
                .eq(FlightData::getInspectionId, inspection.getId())
                .eq(FlightData::getTenantId, inspection.getTenantId())
                .eq(FlightData::getMark, MarkEnum.VALID.getCode()));
        log.info("坐标数据，flightDataCount:{}", flightDataCount);
        if (flightDataCount > 0) {
            int index = (int) Math.ceil((double) flightDataCount / 2);
            FlightData flightData = flightDataMapper.selectOne(new LambdaQueryWrapper<FlightData>()
                    .eq(FlightData::getInspectionId, inspection.getId())
                    .eq(FlightData::getTenantId, inspection.getTenantId())
                    .eq(FlightData::getMark, MarkEnum.VALID.getCode())
                    .orderByDesc(FlightData::getTimestamp)
                    .last("limit " + index + ",1"));
            if (ObjectUtil.isNotNull(flightData)) {
                inspectionUpdate.setFlyHeight(flightData.getUltrasonic());
            }
        }

        inspectionMapper.updateById(inspectionUpdate);

        this.updateReport(inspection);
    }

    public JsonResult getWeather(String airportUrl, Integer airportId) {
        String url = airportUrl + SystemConstant.API_AIRPORT_GET_WEATHER;
        String param = "airportId=" + airportId;
        String weatherStr = HttpUtils.sendGet(url, param);
        JsonResult jsonResult;
        try {
            jsonResult = JacksonUtil.json2pojo(weatherStr, JsonResult.class);
            if (ObjectUtil.isEmpty(jsonResult) || Objects.requireNonNull(jsonResult).getCode() != 0) {
                log.info("获取天气信息失败，url={}", url);
                log.info("获取天气信息失败，param={}", param);
                log.info("获取天气信息失败，返回为空或code为0，请重试!");
                return JsonResult.error(EditInspectionStatusCodeEnum.GET_WEATHER_FAILED.getCode(), EditInspectionStatusCodeEnum.GET_WEATHER_FAILED.getMsg());
            }
            if (ObjectUtil.isEmpty(jsonResult.getData())) {
                return JsonResult.success(new AirWeatherVO());
            }
            AirWeatherVO airWeatherVO = JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData()), AirWeatherVO.class);
            return JsonResult.success(airWeatherVO);
        } catch (Exception e) {
            log.info("获取天气信息失败，url={}", url);
            log.info("获取天气信息失败，param={}", param);
            log.info("获取天气信息失败，异常!");
            return JsonResult.error(EditInspectionStatusCodeEnum.GET_WEATHER_FAILED.getCode(), EditInspectionStatusCodeEnum.GET_WEATHER_FAILED.getMsg());
        }
    }

    private void updateReport(Inspection inspection) {
        Report report = reportMapper.selectOne(Wrappers.<Report>lambdaQuery()
                .eq(Report::getInspectionId, inspection.getId())
                .eq(Report::getMark, MarkEnum.VALID.getCode()));
        if (ObjectUtil.isNull(report)) {
            log.info("该任务还没有生成报告，不需要修改报告的完成时间和状态");
            return;
        }
        report.setStatus(inspection.getStatus());
        report.setExecutionEndTime(inspection.getExecutionEndTime());
        reportMapper.updateById(report);
    }

}
