package com.tuoheng.admin.service.accident.forward;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.constant.SystemConstant;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.AccidentDroneForwardTypeEnum;
import com.tuoheng.admin.enums.AccidentStatusEnum;
import com.tuoheng.admin.enums.InspectionStatusEnum;
import com.tuoheng.admin.mapper.AccidentInspectionMapper;
import com.tuoheng.admin.mapper.AccidentMapper;
import com.tuoheng.admin.mapper.InspectionFileMapper;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.request.accident.AccidentForwardRequest;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service("originalDroneForward")
public class OriginalDroneForward implements AccidentForwardService {

    @Autowired
    private AccidentMapper accidentMapper;

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private AccidentInspectionMapper accidentInspectionMapper;

    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    @Autowired
    private UpdateAccidentStatusService updateAccidentStatusService;

    @Override
    @Transactional
    public JsonResult forward(User user, Accident accident, AccidentForwardRequest request) {
        Inspection oldInspection = inspectionMapper.selectById(accident.getInspectionId());
        if (ObjectUtil.isNull(oldInspection)) {
            throw new ServiceException("该应急事故对应的巡检任务不存在");
        }

        // 1、原无人机前往
        this.callAirport(accident, oldInspection);

        // 2、创建应急任务
        request.setDspServiceInstId(oldInspection.getDspServiceInstId());
        request.setAirportId(oldInspection.getAirportId());
        request.setAirportName(oldInspection.getAirportName());
        request.setDroneId(oldInspection.getDroneId());
        request.setEmergencyDataInspectionId(oldInspection.getId());
        Inspection emergencyInspection = CreateEmergencyInspection.create(user, request, InspectionStatusEnum.IN_FLIGHT.getCode());
        Integer count = inspectionMapper.insert(emergencyInspection);
        if (count <= 0) {
            log.info("创建应急任务失败");
            throw new ServiceException("创建应急任务失败");
        }

        // 3、关联事故与应急任务表
        this.createInspectionAccident(user, accident, emergencyInspection);

        // 4、修改应急事故状态
        updateAccidentStatusService.update(user, accident);

        // 5、修改原巡检任务状态为已完成
//        oldInspection.setStatus(InspectionStatusEnum.FLIGHT_COMPLETED.getCode());
//        inspectionMapper.updateById(oldInspection);

        return JsonResult.success();
    }

    /**
     * 调用机场平台，执行指点飞行
     *
     * @param accident
     * @param inspection
     */
    private void callAirport(Accident accident, Inspection inspection) {
        InspectionFile inspectionFile = inspectionFileMapper.selectOne(new LambdaQueryWrapper<InspectionFile>()
                .eq(InspectionFile::getId, accident.getInspectionFileId()));
        if (ObjectUtil.isNull(inspectionFile)) {
            log.info("调用机场平台，无人机执行定点飞行：没有对应的任务问题");
            throw new ServiceException("没有对应的任务问题");
        }

        String url = CommonConfig.airportURL + SystemConstant.API_AIRPORT_DRONE_CONTROL;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("taskId", inspection.getId());
        jsonObject.put("airportId", inspection.getAirportId());
        jsonObject.put("zalt", "100");
        jsonObject.put("zlon", inspectionFile.getLongitude());
        jsonObject.put("zlat", inspectionFile.getLatitude());

        log.info("调用机场平台，无人机执行定点飞行: url:{}", url);
        log.info("调用机场平台，无人机执行定点飞行: jsonObject:{}", jsonObject);

        String airPortStr = HttpUtils.doSend(url, jsonObject, null, "POST");
        if (StringUtils.isEmpty(airPortStr)) {
            log.info("调用机场平台，无人机执行定点飞行：返回数据为空，飞行失败，jsonObject：{}", jsonObject);
            throw new ServiceException("机场平台返回数据为空，飞行失败");
        }

        JsonResult jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
        if (0 != jsonResult.getCode()) {
            log.info("调用机场平台，无人机执行定点飞行：飞行失败，jsonResult：{}", jsonResult.getMsg());
            throw new ServiceException("机场平台返回，飞行失败");
        }
    }

    /**
     * 创建任务与事故关联表相关
     *
     * @param user
     * @param accident
     * @param emergencyInspection
     * @return
     */
    private AccidentInspection createInspectionAccident(User user, Accident accident, Inspection emergencyInspection) {
        AccidentInspection accidentInspection = new AccidentInspection();
        accidentInspection.setTenantId(user.getTenantId());
        accidentInspection.setAccidentId(accident.getId());
        accidentInspection.setInspectionId(emergencyInspection.getId());
        accidentInspection.setName(emergencyInspection.getAirportName() + "执行任务");
        accidentInspection.setDroneForwardType(AccidentDroneForwardTypeEnum.ORIGINAL_DRONE_FORWARD.getCode());
        accidentInspection.setCreateUser(user.getId());
        accidentInspection.setCreateTime(DateUtils.now());
        int count = accidentInspectionMapper.insert(accidentInspection);
        if (count <= 0) {
            log.info("创建应急任务关联表失败");
            throw new ServiceException("创建应急事故与应急任务关联表失败");
        }
        return accidentInspection;
    }


}
