package com.friday.custody.service.trustService.gtja.utils;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.friday.custody.service.trustService.htsc.utils.HTSCGetDataUtil;
import com.gtja.openapi.request.CommonRequest;
import com.gtja.openapi.request.CommonResult;
import com.gtja.openapi.request.GtjaApiClient;
import com.friday.custody.dto.GtjaAppSecretDTO;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.service.trustService.gtja.dto.BaseResultDto;
import com.friday.custody.utils.PullDataFailureUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Service("gTJAHttpUtil")
public class GTJAHttpUtil {

    //有时因为网络波动无法拿到数据，需要重复发送请求，重复请求最大次数
    public static final int REPEAT_INVOKE_TIMES = 16 ;

    @Autowired
    private HTSCGetDataUtil hTSCGetDataUtil ;
    @Value("${custody.remote.url.gtja.gtjaUrlPrefix}")
    private String url ;

    public static <T> CommonResult<T> callForObj(CommonRequest commReq, Class<T> clazz,int invokeTimes) throws Exception {
        String rep = GtjaApiClient.call(commReq);
        CommonResult commonResult = null;
        try{
            commonResult = JSON.parseObject(rep, new TypeReference<CommonResult<T>>(new Type[]{clazz}) {}, new Feature[0]);
        }catch (Exception e){
            log.info("国泰callForObj入参commReq={},调用GtjaApiClient.call后rep={},当前调用次数为{}",JSON.toJSONString(commReq),rep,invokeTimes);
            if(invokeTimes < GTJAHttpUtil.REPEAT_INVOKE_TIMES){
                invokeTimes = invokeTimes + 1;
                commonResult = GTJAHttpUtil.callForObj(commReq,clazz,invokeTimes);
            }else{
                log.error("重复调用了最大测试：{}次，停止重新调用!");
                throw new Exception(e);
            }
        }
        return commonResult;
    }

    public   Map<String,Object> sendMessage(String paramsJson, String serviceName,TenantEscrowAuthorizationInfoDto tenant) {

        CommonRequest commReq =null;
        GtjaAppSecretDTO appSecretDTO = getAppSecretDTO(tenant);
        String appKey = appSecretDTO.getAppKey();
        String appSecret = appSecretDTO.getAppSecret();
        String managerId = appSecretDTO.getManagerId();
        commReq= new CommonRequest(serviceName,
                paramsJson,
                appKey,
                appSecret,
                managerId,
                url
                );

        String errorMessage = "";
        try {
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();

            CommonResult<String> result = GTJAHttpUtil.callForObj(commReq, String.class,1);
            log.info("CommonResult"+JSON.toJSONString(result));
            if (result.isSuccess() && CommonResult.RET_CODE_SUCCESS.equals(result.getRetCode())) {

                String dataStr = result.getData();
                List<JSONObject> data;
                try{
                    data= JSON.parseArray(dataStr, JSONObject.class);
                }catch (JSONException e){
                    BaseResultDto baseResultDto = JSON.parseObject(dataStr, BaseResultDto.class);
                    String totalCount = baseResultDto.getTotalCount();
                    stringObjectHashMap.put("totalCount",totalCount);
                    data = baseResultDto.getResult();
                }

                if(CollectionUtils.isNotEmpty(data)){
                    stringObjectHashMap.put("data",data);
                }
                stringObjectHashMap.put("result",true);
                System.err.println(JSON.toJSONString(stringObjectHashMap));

                hTSCGetDataUtil.saveInvokeRecord(tenant, tenant.getTrustNo(), serviceName, "", paramsJson, JSON.toJSONString(result));

                return stringObjectHashMap;
            }else{
                errorMessage = result.getRetMsg();
            }
        } catch (Exception e) {
            log.error("GTJAHttpUtil_sendMessage_commReq={}",JSON.toJSONString(commReq));
            log.error("国泰君安验权失败：",e);
            errorMessage = e.getMessage();
        }
        String trustNo = tenant.getTrustNo();
        Map<String,String> headerMap =new HashMap<>();

        headerMap.put("appkey", appKey);
        headerMap.put("appsecret", appSecret);
        headerMap.put("uri", url + serviceName);

        Map<String, Object> errorMap = PullDataFailureUtil.createErrorMap(trustNo, serviceName,JSON.toJSONString(headerMap), "appId=" + appKey + "&params=" + paramsJson, errorMessage);

        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("result",false);
        stringObjectHashMap.put("data",errorMap);
        return stringObjectHashMap;
    }
    private ObjectMapper objectMapper = new ObjectMapper();
    public GtjaAppSecretDTO getAppSecretDTO(TenantEscrowAuthorizationInfoDto tenant){
        String tenantAppSecret = tenant.getAppSecret();
        if (ObjectUtil.isEmpty(tenantAppSecret)){
            return null;
        }
        GtjaAppSecretDTO gtjaAppSecretDTO = new GtjaAppSecretDTO();
        try {
            gtjaAppSecretDTO = objectMapper.readValue(tenantAppSecret, GtjaAppSecretDTO.class);
        } catch (IOException e) {
            log.error("解析账密{}失败!{}", gtjaAppSecretDTO,  e);
        }
        return gtjaAppSecretDTO;
    }

}
