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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ServiceException;
import com.tuoheng.admin.constant.SystemConstant;
import com.tuoheng.admin.entity.Inspection;
import com.tuoheng.admin.entity.Tenant;
import com.tuoheng.admin.entity.User;
import com.tuoheng.admin.enums.AccidentEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.request.accident.AccidentFlightRequest;
import com.tuoheng.admin.utils.CurrentUserUtil;
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 org.springframework.transaction.annotation.Transactional;

/**
 * @Author ChengWang
 * @Date 2023/3/13
 */
@Service
@Slf4j
public class PointFlightService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Transactional
    public JsonResult pointFlight(AccidentFlightRequest request) {
        log.info("执行应急飞行起飞，request={}", request);
        //先创建应急任务--->执行定点飞行任务
        //校验
        if (StringUtils.isEmpty(request.getLongitude())) {
            log.info("经度，lon={}", request.getLongitude());
            return JsonResult.error(AccidentEnum.LONGITUDE_IS_NULL.getCode(), AccidentEnum.LONGITUDE_IS_NULL.getMsg());
        }
        if (StringUtils.isEmpty(request.getLatitude())) {
            log.info("经度，lat={}", request.getLatitude());
            return JsonResult.error(AccidentEnum.LATITUDE_IS_NULL.getCode(), AccidentEnum.LATITUDE_IS_NULL.getMsg());
        }
        if (null == request.getAirportId()) {
            log.info("机场id,id={}", request.getAirportId());
            return JsonResult.error(AccidentEnum.AIRPORT_ID_IS_NULL.getCode(), AccidentEnum.AIRPORT_ID_IS_NULL.getMsg());
        }
        if (StringUtils.isEmpty(request.getAirportName())) {
            log.info("机场名称，airportName={}", request.getAirportName());
            return JsonResult.error(AccidentEnum.AIRPORT_NAME_IS_NULL.getCode(), AccidentEnum.AIRPORT_NAME_IS_NULL.getMsg());
        }
        //获取当前用户及租户信息
        User user = CurrentUserUtil.getUserInfo();
        String tenantId = CurrentUserUtil.getTenantId();
        //获取租户信息
        Tenant tenant = this.getTenant(tenantId);
        log.info("当前登录用户租户id，tenantId={}", tenant);
        //创建应急任务
        Inspection inspection = this.createInspection(user, request);
        log.info("生成的应急任务，inspection={}", inspection);

        //调用机场平台进行飞行
        //因任务为原来新的应急任务不用关心其他正在巡检飞行的任务
        this.callNewAirport(tenant, request, inspection.getId());
        //log.info("调用机场进行飞行，flag={}",flag);

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

        return JsonResult.success(inspection);
    }

    /**
     * 调用机场平台
     *
     * @param tenant
     * @param request
     * @param inspectionId
     */
    private void callNewAirport(Tenant tenant, AccidentFlightRequest request, String inspectionId) {
        String url = CommonConfig.airportURL + SystemConstant.API_AIRPORT_POINT_FLIGH;
        //高度设置为60
        request.setAlt("100");
        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", request.getAlt());
        jsonObject.put("lon", request.getLongitude());
        jsonObject.put("lat", request.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 com.tuoheng.common.core.exception.ServiceException("机场平台返回，飞行失败");
        }
    }

    /**
     * 创建应急任务
     *
     * @param user
     * @param request
     * @return
     */
    private Inspection createInspection(User user, AccidentFlightRequest request) {
        Inspection inspection = new Inspection();
        inspection.setTenantId(user.getTenantId());
        String code = DateUtils.generateCode("XJRW");
        inspection.setCode(code);
        inspection.setDeptId(user.getDeptId());
        inspection.setName("应急任务" + code);
        inspection.setType(2);
        inspection.setStatus(TaskStatusEnum.INFLIGHT.getCode());// 设置应急任务状态为飞行中
        inspection.setRoadId("");
        inspection.setSectionId("");
        inspection.setInspectionType(2);
        inspection.setAirportId(request.getAirportId());
        inspection.setAirportName(request.getAirportName());
        inspection.setInspectionLine(0);
        inspection.setInspectionLineName("");
        inspection.setExecutionStartTime(DateUtils.now());
        inspection.setCreateUser(user.getId());
        inspection.setCreateTime(DateUtils.now());
        inspection.setIsLive(1);
        inspection.setDroneId(request.getDroneId());
        int result = inspectionMapper.insert(inspection);
        if (result <= 0) {
            log.info("创建应急任务失败");
            throw new ServiceException("创建应急任务失败");
        }
        return inspection;
    }


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