package com.base.biz.remote;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.base.biz.model.entity.InstanceInfo;
import com.base.orbit.utils.IdGenerator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * 通过第三方接口来获取瞬根
 */
@Component
public class GetAndHandlerInstance {
    /**
     * getTwoLineUrl：推导两行根数的url地址
     */
    @Value("${infer.instanceToTwoLine}")
    private String getTwoLineUrl;

    /**
     * getInstanceUrl：将两行根数转化为六根数的地址
     */
    @Value("${infer.twoLineToInstance}")
    private String getInstanceUrl;

    /**
     * 通过给定六根数推算指定数量的轨道六根数
     *
     * @param bodyObj：输入的轨道数据
     * @return instanceInfos：满足入库的六根数数据集合
     */
    public List<InstanceInfo> getInstanceData(JSONObject bodyObj) {
        //1.将接收到的六根数数据转成所需要的格式
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> twoLineDataExchange = getTwoLineDataResponseEntity(bodyObj, restTemplate);
        //2.将推导出来的两行根数取出，作为下一个接口的入参
        JSONObject twoLineData = JSONObject.parseObject(twoLineDataExchange.getBody());
        JSONArray twoLineJsonArrayData = twoLineData.getJSONArray("data");
        //3.将接收到的两行根数数据转化为六根数数据
        ResponseEntity<Map> twoLineTransferInstanceExchange = getInstanceDataResponseEntity(restTemplate, twoLineJsonArrayData);
        //4.将数据处理为入库的类型
        List<InstanceInfo> instanceInfos = handleInstanceData(twoLineTransferInstanceExchange, bodyObj);
        return instanceInfos;
    }

    /**
     * 将推导出来的六根数数据处理成入库所需的结构
     *
     * @param twoLineTransferInstanceExchange：推导出来的六根数数据
     * @return instanceInfos：满足入库的六根数数据集合
     */
    private List<InstanceInfo> handleInstanceData(ResponseEntity<Map> twoLineTransferInstanceExchange, JSONObject bodyObj) {
        Map twoLineTransferInstanceExchangeBody = twoLineTransferInstanceExchange.getBody();
        List<LinkedHashMap> twoLineTransferInstanceExchangeList = (List<LinkedHashMap>) twoLineTransferInstanceExchangeBody.get("data");
        List<InstanceInfo> instanceInfos = new ArrayList<>();
        for (int i = 0; i < twoLineTransferInstanceExchangeList.size(); i++) {
            String instanceId = IdGenerator.getStrId();
            InstanceInfo instanceInfo = new InstanceInfo();
            LinkedHashMap twoLineTransferInstanceMap = twoLineTransferInstanceExchangeList.get(i);
            String twoLineTransferInstanceStr = JSON.toJSONString(twoLineTransferInstanceMap);
            JSONObject twoLineTransferInstanceJsonObject = JSONObject.parseObject(twoLineTransferInstanceStr);
            instanceInfo.setId(instanceId);
            Date lysk = twoLineTransferInstanceJsonObject.getDate("epochTime");
            Date startTime = bodyObj.getDate("startTime");
            //这里校验历元时刻
            long diff = startTime.getTime() - lysk.getTime();
            if (diff <= 0) {
                instanceInfo.setEpochTime(startTime);
            } else {
                long diffDay = diff / (24 * 60 * 60 * 1000);
                if (diffDay > 3) {
                    instanceInfo.setEpochTime(startTime);
                } else {
                    instanceInfo.setEpochTime(lysk);
                }
            }
            instanceInfo.setRaan(twoLineTransferInstanceJsonObject.getString("lan"));
            instanceInfo.setInclination(twoLineTransferInstanceJsonObject.getString("inclination"));
            instanceInfo.setEccentricity(twoLineTransferInstanceJsonObject.getString("eccentricity"));
            instanceInfo.setSemiMajorAxis(twoLineTransferInstanceJsonObject.getString("orbitalA"));
            instanceInfo.setMeanAnoMaly(twoLineTransferInstanceJsonObject.getString("meanAnomaly"));
            instanceInfo.setArgumentOfPerigee(twoLineTransferInstanceJsonObject.getString("argumentPerigee"));
            instanceInfo.setOrbitNum("13045");
            instanceInfos.add(instanceInfo);
        }
        return instanceInfos;
    }

    /**
     * 根据两行数据推导瞬根数据
     *
     * @param restTemplate：调用外部接口客户端
     * @param twoLineJsonArrayData：JSON结构的两行数据
     * @return twoLineTransferInstanceExchange：转换出来的六根数数据
     */
    private ResponseEntity<Map> getInstanceDataResponseEntity(RestTemplate restTemplate, JSONArray twoLineJsonArrayData) {
        HttpHeaders twoLineHttpHeader = new HttpHeaders();
        twoLineHttpHeader.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<JSONArray> twoLineHttpEntity = new HttpEntity<JSONArray>(twoLineJsonArrayData, twoLineHttpHeader);
        ResponseEntity<Map> twoLineTransferInstanceExchange = restTemplate.exchange(getInstanceUrl, HttpMethod.POST, twoLineHttpEntity, Map.class);
        return twoLineTransferInstanceExchange;
    }

    /**
     * 通过输入六根数推导其余轨道六根数
     *
     * @param bodyObj：输入轨道六根数
     * @param restTemplate：调用第三方接口客户端
     * @return twoLineDataExchange：推导出来的两行数据
     */
    private ResponseEntity<String> getTwoLineDataResponseEntity(JSONObject bodyObj, RestTemplate restTemplate) {
        JSONObject wxInstanceBaseMsg = bodyObj.getJSONObject("wxInstanceBaseMsg");
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, Object> instanceTransferTwoLineInputParams = new LinkedMultiValueMap<String, Object>();
        instanceTransferTwoLineInputParams.put("startTime", Collections.singletonList(bodyObj.getString("startTime")));
        instanceTransferTwoLineInputParams.put("endTime", Collections.singletonList(bodyObj.getString("endTime")));
        instanceTransferTwoLineInputParams.put("epochTime", Collections.singletonList(wxInstanceBaseMsg.getString("lysk")));
        Double gdbj = wxInstanceBaseMsg.getDouble("gdbj") * 1000;
        instanceTransferTwoLineInputParams.put("orbitalA", Collections.singletonList(gdbj.toString()));
        instanceTransferTwoLineInputParams.put("eccentricity", Collections.singletonList(wxInstanceBaseMsg.getString("pxl")));
        instanceTransferTwoLineInputParams.put("inclination", Collections.singletonList(wxInstanceBaseMsg.getString("gdqj")));
        instanceTransferTwoLineInputParams.put("lan", Collections.singletonList(wxInstanceBaseMsg.getString("sjdcj")));
        instanceTransferTwoLineInputParams.put("argumentPerigee", Collections.singletonList(wxInstanceBaseMsg.getString("jddfj")));
        instanceTransferTwoLineInputParams.put("meanAnomaly", Collections.singletonList(wxInstanceBaseMsg.getString("pjdj")));
        instanceTransferTwoLineInputParams.put("satelliteTotal", Collections.singletonList(wxInstanceBaseMsg.getString("satelliteNum")));
        instanceTransferTwoLineInputParams.put("orbitalPlane", Collections.singletonList(wxInstanceBaseMsg.getString("trackSurfaces")));

        HttpEntity<MultiValueMap<String, Object>> instanceTransferTwoLineParamsHttpEntity = new HttpEntity<MultiValueMap<String, Object>>(instanceTransferTwoLineInputParams, httpHeaders);
        ResponseEntity<String> twoLineDataExchange = restTemplate.exchange(getTwoLineUrl, HttpMethod.POST, instanceTransferTwoLineParamsHttpEntity, String.class);
        return twoLineDataExchange;
    }

}
