package com.tuoheng.admin.service.third.airport;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.config.SystemConstant;
import com.tuoheng.admin.entity.domain.Tenant;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.domain.Warning;
import com.tuoheng.admin.entity.domain.WarningRecord;
import com.tuoheng.admin.entity.request.airport.PointFlightRequest;
import com.tuoheng.admin.enums.AirportFlyTypeEnum;
import com.tuoheng.admin.enums.InspectionTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.UpdateOrCreateEnum;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.mapper.WarningMapper;
import com.tuoheng.admin.mapper.WarningRecordMapper;
import com.tuoheng.admin.utils.CodeUtil;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.DateUtils;
import com.tuoheng.common.utils.HttpUtils;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.entity.User;
import com.tuoheng.system.utils.ShiroUtils;
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
public class PointFlightService {

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private WarningMapper warningMapper;

    @Autowired
    private ThMissionMapper missionMapper;

    @Autowired
    private WarningRecordMapper warningRecordMapper;

    @Transactional
    public JsonResult executePointFligh(PointFlightRequest request) {
        log.info("进入调用机场平台，执行定点飞行");
        JsonResult result = this.check(request);
        User user = ShiroUtils.getUserInfo();
        Integer tenantId = user.getTenantId();

        // 获取租户信息
        Tenant tenant = this.getTenant(tenantId);

        // 创建应急任务
        ThMission mission = this.createMission(user, request);

        // 调用机场平台
        ThMission oldMission = (ThMission) result.getData();
        if (oldMission.getAirportId().equals(request.getAirportId())) {
            log.info("原机场执行定点飞行");
//            this.callOldAirpor(tenant, request);
        } else {
            log.info("新机场执行定点飞行");
//            this.callNewAirpor(tenant, request, mission.getId());
        }

        // 创建预警记录
        this.createWarningRecord(user.getId(), tenantId, request, mission.getId());

        log.info("调用机场平台方法: 执行定点飞行结束");
        return JsonResult.success();
    }

    /**
     * 检查参数
     *
     * @param request
     */
    private JsonResult check(PointFlightRequest request) {
        if (ObjectUtil.isNull(request.getWarningId())) {
            throw new ServiceException("预警ID为空");
        }
        if (ObjectUtil.isNull(request.getMissionId())) {
            throw new ServiceException("原巡检任务ID为空");
        }
        if (ObjectUtil.isNull(request.getAirportId())) {
            throw new ServiceException("机场ID为空");
        }
        if (ObjectUtil.isNull(request.getAirportName())) {
            throw new ServiceException("机场名称为空");
        }
        if (ObjectUtil.isNull(request.getAlt())) {
            throw new ServiceException("指点高度为空");
        }
        if (ObjectUtil.isNull(request.getLon())) {
            throw new ServiceException("经度为空");
        }
        if (ObjectUtil.isNull(request.getLat())) {
            throw new ServiceException("纬度为空");
        }
        Warning warning = warningMapper.selectOne(new LambdaQueryWrapper<Warning>()
                        .eq(Warning::getId, request.getWarningId())
                        .eq(Warning::getMark, 1));
        if (ObjectUtil.isNull(warning)) {
            throw new ServiceException("该预警信息不存在");
        }
        ThMission mission = missionMapper.selectOne(new LambdaQueryWrapper<ThMission>()
                .eq(ThMission::getId, request.getMissionId())
                .eq(ThMission::getMark, 1));
        if (ObjectUtil.isNull(mission)) {
            throw new ServiceException("原巡检任务不存在");
        }
        return JsonResult.success(mission);
    }

    /**
     * 获取租户信息
     *
     * @param tenantId
     * @return
     */
    private Tenant getTenant(Integer tenantId) {
        Tenant tenant = tenantMapper.selectById(tenantId);
        if (ObjectUtil.isEmpty(tenant)) {
            log.info("调用机场平台，执行定点飞行: 租户不存在");
            throw new ServiceException("租户不存在");
        }
        // 读取不同租户的机场平台url
        if (StringUtils.isEmpty(tenant.getAirportUrl())) {
            log.info("调用机场平台，执行定点飞行: 机场平台URL为空");
            throw new ServiceException("机场平台URL为空");
        }
        return tenant;
    }

    /**
     * 调用老机场平台
     *
     * @param tenant
     * @param request
     */
    private void callOldAirpor(Tenant tenant, PointFlightRequest request) {
        String url = tenant.getAirportUrl() + SystemConstant.API_AIRPORT_DRONE_CONTROL;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("taskId", request.getMissionId());
        jsonObject.put("airportId", request.getAirportId());
        jsonObject.put("zalt", request.getAlt());
        jsonObject.put("zlon", request.getLon());
        jsonObject.put("zlat", request.getLat());

        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("机场接口返回数据为空，飞行失败");
        }
    }

    /**
     * 调用新机场平台
     *
     * @param tenant
     * @param request
     */
    private void callNewAirpor(Tenant tenant, PointFlightRequest request, Integer emergencyMissionId) {
        String url = tenant.getAirportUrl() + SystemConstant.API_AIRPORT_POINT_FLIGH;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("airportId", request.getAirportId());
        jsonObject.put("requestId", emergencyMissionId);
        jsonObject.put("code", SystemConstant.PLATFORM_CODE); // 与机场平台约定好的
        jsonObject.put("tenantCode", tenant.getCode());
        jsonObject.put("alt", request.getAlt());
        jsonObject.put("lon", request.getLon());
        jsonObject.put("lat", request.getLat());

        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("机场接口返回数据为空，飞行失败");
        }
    }

    /**
     * 创建应急任务
     *
     * @param user
     * @param request
     * @return
     */
    private ThMission createMission(User user, PointFlightRequest request) {
        ThMission mission = new ThMission(UpdateOrCreateEnum.CREATE.getCode());
        String code = "XJRW" + CodeUtil.createCodeNo();
        mission.setCode(code);
        mission.setName("应急任务" + code);
        mission.setTenantId(user.getTenantId());
        mission.setInspectionType(InspectionTypeEnum.AIRPORT.getCode());
        mission.setAirportId(request.getAirportId());
        mission.setAirportName(request.getAirportName());
        mission.setInspectionLine(0);
        mission.setInspectionLineName("");
        mission.setExecutionStartTime(DateUtils.now());
        mission.setAirportFlyType(AirportFlyTypeEnum.POINTING_FLIGHT.getCode());
        mission.setCreateUser(user.getId());
        mission.setCreateTime(DateUtils.now());
        Integer count = missionMapper.insert(mission);
        if (count <= 0) {
            log.info("创建应急任务失败");
            throw new ServiceException("创建应急任务失败");
        }
        return mission;
    }

    /**
     * 创建预警记录
     *
     * @param userId
     * @param tenantId
     * @param request
     * @param emergencyMissionId
     */
    private void createWarningRecord(Integer userId, Integer tenantId, PointFlightRequest request, Integer emergencyMissionId) {
        WarningRecord warningRecord = new WarningRecord();
        warningRecord.setTenantId(tenantId);
        warningRecord.setWarningId(request.getWarningId());
        warningRecord.setMissionId(request.getMissionId());
        warningRecord.setEmergencyMissionId(emergencyMissionId);
        warningRecord.setName(request.getAirportName() + "执行任务");
        warningRecord.setCreateUser(userId);
        warningRecord.setCreateTime(DateUtils.now());
        Integer count = warningRecordMapper.insert(warningRecord);
        if (count <= 0) {
            log.info("创建预计记录失败");
            throw new ServiceException("创建预计记录失败");
        }
    }

}