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.*;
import com.tuoheng.admin.request.accident.AccidentForwardRequest;
import com.tuoheng.admin.service.third.airport.drone.DroneService;
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("originalDroneContinue")
public class OriginalDroneContinue implements AccidentForwardService {

    @Autowired
    private AccidentMapper accidentMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private AccidentInspectionMapper accidentInspectionMapper;

    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    @Autowired
    private DroneService droneService;

    @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、创建应急任务
        Inspection emergencyInspection = CreateEmergencyInspection.create(user, request, InspectionStatusEnum.PREPARING.getCode());
        Integer count = inspectionMapper.insert(emergencyInspection);
        if (count <= 0) {
            log.info("创建应急任务失败");
            throw new ServiceException("创建应急任务失败");
        }

        // 2、新无人机前往
        Tenant tenant = tenantMapper.selectById(user.getTenantId());
        this.callNewDroneForward(tenant, accident, request, emergencyInspection.getId());

        // 3、原无人机继续巡检任务，原无人机没有悬停，一直在执行原任务，因此不需要发送继续巡检指令
//        droneService.continuee(oldInspection.getAirportId(), oldInspection.getId());

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

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

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

        return JsonResult.success();
    }

    /**
     * 调用机场平台，新无人机前往
     *
     * @param tenant
     * @param accident
     * @param request
     * @param inspectionId 应急任务ID
     */
    private void callNewDroneForward(Tenant tenant, Accident accident, AccidentForwardRequest request, String inspectionId) {
        InspectionFile inspectionFile = inspectionFileMapper.selectOne(new LambdaQueryWrapper<InspectionFile>()
                .eq(InspectionFile::getId, accident.getInspectionFileId()));

        String url = CommonConfig.airportURL + SystemConstant.API_AIRPORT_POINT_FLIGH;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("airportId", request.getAirportId());
        jsonObject.put("requestId", inspectionId);
        jsonObject.put("code", SystemConstant.PLATFORM_CODE);
        jsonObject.put("tenantCode", tenant.getCode());
        jsonObject.put("alt", "100");    //高度设置为100
        jsonObject.put("lon", inspectionFile.getLongitude());
        jsonObject.put("lat", 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.NEW_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;
    }


}
