package com.tuoheng.admin.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.common.ServiceExceptionEnum;
import com.tuoheng.admin.config.SystemConstant;
import com.tuoheng.admin.entity.domain.Tenant;
import com.tuoheng.admin.entity.domain.ThInspection;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.domain.WarningRecord;
import com.tuoheng.admin.entity.request.InspectionRequest;
import com.tuoheng.admin.entity.request.PushAndPullURLRequest;
import com.tuoheng.admin.entity.vo.AirLineVO;
import com.tuoheng.admin.entity.vo.AirPortVO;
import com.tuoheng.admin.entity.vo.AirWeatherVO;
import com.tuoheng.admin.entity.vo.InspectionVO;
import com.tuoheng.admin.enums.AccidentTaskEnum;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.UpdateOrCreateEnum;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.mapper.ThInspectionMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.mapper.WarningRecordMapper;
import com.tuoheng.admin.service.IMissionService;
import com.tuoheng.admin.service.IThInspectionService;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.config.CommonConfig;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.*;
import com.tuoheng.system.entity.User;
import com.tuoheng.system.mapper.UserMapper;
import com.tuoheng.system.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @User qiujinyang
 * @Description
 * @Date Created by 2022/7/28 9:39
 */
@Service
@Slf4j
public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper, ThInspection> implements IThInspectionService {


    @Autowired
    private ThInspectionMapper inspectionMapper;

    @Autowired
    private ThMissionMapper missionMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IMissionService missionService;

    @Autowired
    private WarningRecordMapper warningRecordMapper;

    @Override
    public List<InspectionVO> track(Integer id) {
        ThMission mission = missionMapper.selectOne(new LambdaQueryWrapper<ThMission>()
                .eq(ThMission::getId, id)
                .eq(ThMission::getMark, MarkTypeEnum.VALID.getCode()));
        if (ObjectUtil.isNull(mission)) {
            throw new ServiceException("没有该任务记录");
        }
        if (2 == mission.getType() && mission.getEmergencyDataMissionId() != 0) {
            id = mission.getEmergencyDataMissionId();
        }
        LambdaQueryWrapper<ThInspection> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(ThInspection::getMissionId, id)
                .orderByAsc(ThInspection::getCreateTime);
        List<InspectionVO> result = new ArrayList<>();
        List<ThInspection> thInspections = inspectionMapper.selectList(lambdaQueryWrapper);

        for (ThInspection thInspection : thInspections) {
            InspectionVO inspectionVO = new InspectionVO();
            BeanUtils.copyProperties(thInspection, inspectionVO);
            result.add(inspectionVO);
        }
        return result;
    }

    @Override
    public Integer track(InspectionRequest inspectionRequest) throws ServiceException {
        ThInspection inspection = new ThInspection(UpdateOrCreateEnum.CREATE.getCode());
        BeanUtils.copyProperties(inspectionRequest, inspection);
        //获取当前巡检正在执行的任务
        List<ThMission> thMissions = missionMapper.selectList(new LambdaQueryWrapper<ThMission>()
                .eq(ThMission::getId, inspectionRequest.getRequestId())
                .eq(ThMission::getMark, MarkTypeEnum.VALID.getCode())
                .orderByAsc(ThMission::getExecutionStartTime));
        if (ObjectUtil.isEmpty(thMissions) || thMissions.size() == 0) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "没有该任务！");
        }
        ThMission mission = thMissions.get(0);
        inspection.setSpeed(inspectionRequest.getHspeed());
        inspection.setYsingal(inspectionRequest.getYsingal());
        inspection.setMode(inspectionRequest.getMode());
        inspection.setMissionId(mission.getId());
        inspection.setTenantId(mission.getTenantId());
        inspectionMapper.insert(inspection);
        return inspection.getId();
    }

    @Override
    public List<AirPortVO> airport() throws ServiceException, UnsupportedEncodingException {
        Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
        String url = CommonConfig.airportURL + "/api/airportInterface/airportList";
        String param = "page=1&limit=1000&tenantCode=" + tenant.getCode();
        log.info("****** airportList param tenantCode:{}", tenant.getCode());
        String airPortStr = HttpUtils.sendGet(url, param);
        JsonResult jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
        if (ObjectUtil.isEmpty(jsonResult) || (!ObjectUtil.isEmpty(jsonResult.getData()) && jsonResult.getCode() != 0)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取机场信息失败，请重试");
        }
        return JSONObject.parseArray(JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData())).get("records").toString(), AirPortVO.class);
    }

    @Override
    public List<AirLineVO> airLine(Integer droneId) throws ServiceException {
        String url = CommonConfig.airportURL + "/api/airportInterface/taskByDroneId";
        String param = "page=1&limit=100&droneId=" + droneId;
        String airPortStr = HttpUtils.sendGet(url, param);
        JsonResult<AirLineVO> jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
        if (ObjectUtil.isEmpty(jsonResult) || (!ObjectUtil.isEmpty(Objects.requireNonNull(jsonResult).getData()) && jsonResult.getCode() != 0)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取航线信息失败，请重试");
        }
        return JSONObject.parseArray(JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData())).get("records").toString(), AirLineVO.class);
    }

    @Override
    public JsonResult executeTask(String missionId, PushAndPullURLRequest pushAndPull) throws ServiceException {
        log.info("executeTask准备就绪");

        ThMission thMission = missionMapper.selectById(Integer.parseInt(missionId));
        if (ObjectUtil.isNull(thMission)) {
            log.error("该任务不存在，missionId={}", missionId);
            return JsonResult.error("该任务不存在");
        }
        if (2 == thMission.getExecutionStatus()) {
            log.error("该任务已经被执行，missionId={}", missionId);
            return JsonResult.error("该任务已经被执行");
        }
        log.info("mission查询完成");
        User user = userMapper.selectById(thMission.getCreateUser());
        log.info("user查询完成");
        Tenant tenant = tenantMapper.selectById(user.getTenantId());
        log.info("tenant查询完成");

        log.info("executeTask准备入参");
        String url = CommonConfig.airportURL + "/api/airportInterface/executeTaskAnsy";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", SystemConstant.PLATFORM_CODE);
        jsonObject.put("tenantCode", tenant.getCode());
        jsonObject.put("taskId", thMission.getInspectionLine());
        jsonObject.put("requestId", missionId);
        log.info("***** executeTask url:{};param:{}", url, jsonObject.toJSONString());
        String airPortStr = null;
        try {
            airPortStr = HttpUtils.doSend(url, jsonObject, null, "POST");
        } catch (Exception e) {
            log.error("调用机场executeTask接口异常：", e);
            return JsonResult.error("调用机场executeTask接口异常");
        }
        if (StringUtils.isEmpty(airPortStr)) {
            return JsonResult.error("机场接口返回数据为空");
        }
        JsonResult jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
        if (jsonResult.getCode() != 0) {
            return JsonResult.error(jsonResult.getMsg());
        }

        //将任务执行状态修改为已执行
        ThMission thMissionUpdate = new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
        thMissionUpdate.setId(thMission.getId());
        thMissionUpdate.setExecutionStatus(2);
        missionMapper.updateById(thMissionUpdate);

        return JsonResult.success();
    }

    @Override
    public AirWeatherVO getWeather(Integer airportId) throws ServiceException {
        String url = CommonConfig.airportURL + "/api/airportInterface/getWeather";
        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("获取天气信息失败，返回为空或code不为0");
                log.info("获取天气信息失败，url={}", url);
                log.info("获取天气信息失败，param={}", param);
                throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取天气信息失败，请重试");
            }
            if (ObjectUtil.isEmpty(jsonResult.getData())) {
                log.info("获取天气信息，返回数据为空");
                return new AirWeatherVO();
            }
            return JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData()), AirWeatherVO.class);
        } catch (Exception e) {
            log.info("获取天气信息异常，url={}", url);
            log.info("获取天气信息异常，param={}", param);
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取天气信息异常，请重试");
        }
    }

    @Override
    public JsonResult lineTrack(Integer missionId) {
        ThMission thMission = missionMapper.selectById(missionId);
        Assert.notNull(thMission, "任务不能为空！");
        Integer taskId = thMission.getInspectionLine();
        //解析标准srt文件里面的坐标，调用硬件接口，返回数据
        String url = CommonConfig.airportURL + "/api/airportInterface/getLocationById";
        String param = "id=" + taskId;
        String airportLine = HttpUtils.sendGet(url, param);
        JsonResult jsonResult = JacksonUtil.json2pojo(airportLine, JsonResult.class);
        if (ObjectUtil.isEmpty(jsonResult) || Objects.requireNonNull(jsonResult).getCode() != 0) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取标准航线信息失败，请重试");
        }

        JSONArray resultData = JSONArray.parseArray(JSONObject.toJSONString(jsonResult.getData()));
        for (Object o : resultData) {
            JSONObject jsonObject = (JSONObject) o;
            jsonObject.put("lng", jsonObject.getString("lon"));
            jsonObject.remove("lon");
        }
        jsonResult.setData(resultData);

        System.out.println(jsonResult.getData().toString());
        return jsonResult;
    }

    @Override
    public JsonResult fightData(Integer id) {
        //校验
        if (null == id) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //根据任务id查询对应的遥测数据
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("tenantId", ShiroUtils.getTenantId());
        List<ThInspection> listData = inspectionMapper.selectListByMissionId(map);
        return JsonResult.success(listData);
    }

}
