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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.friday.custody.service.trustService.anxin.common.AnxinContants;
import com.friday.custody.dto.AnxinAppSecretDTO;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.entity.InvokeRecordEntity;
import com.friday.custody.service.basicService.impl.InvokeRecordServiceImpl;
import com.friday.custody.service.basicService.impl.PullDataFailureLogServiceImpl;
import com.friday.custody.utils.PullDataFailureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class AnXinUtils {

    @Autowired
    private InvokeRecordServiceImpl invokeRecordService;

    @Autowired
    private PullDataFailureLogServiceImpl pullDataFailureLogService;

    @Value("${custody.remote.url.anxin.anxinUrlPrefix}")
    private String anXinUrl;

    private RestTemplate restTemplate = new RestTemplate();

    private ObjectMapper objectMapper = new ObjectMapper();

    public Map<String, Object> sendMessage(TenantEscrowAuthorizationInfoDto tenant, String api, String paramStr, Map<String, Object> paramsMap){
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            log.error("AnXinUtils睡眠被打断了!", e);
            Thread.currentThread().interrupt();
        }
        String tenantAppSecret = tenant.getAppSecret();
        if (ObjectUtil.isEmpty(tenantAppSecret)){
            return new HashMap<>();
        }
        AnxinAppSecretDTO anxinAppSecretDTO = new AnxinAppSecretDTO();
        try {
            anxinAppSecretDTO = objectMapper.readValue(tenantAppSecret, AnxinAppSecretDTO.class);
        } catch (IOException e) {
            log.error("解析安信托管账密失败!", e);
        }
        String appSecret = anxinAppSecretDTO.getAppSecret();
        String appKey = anxinAppSecretDTO.getAppKey();
        //header参数
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //组装
        paramsMap.put("AppSecret", appSecret);
        paramsMap.put("AppKey", appKey);
        JSONObject params = new JSONObject(paramsMap);
        HttpEntity<JSONObject> request = new HttpEntity<>(params, headers);
        String url = anXinUrl + api + "?AppSecret="+ appSecret +"&AppKey="+appKey + paramStr;
        log.info("安信请求路径：{}", url);
        ResponseEntity<String> responseEntity = null;
        String errorMsg = null;
        try {
            responseEntity = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
        }catch (Exception e){
            log.error("安信调用上游接口失败! admin = {}, trustNo = {}, api = {}", tenant.getTenantName(), tenant.getTrustNo(), api, e);
            errorMsg = e.getMessage();
        }
        HashMap result = new HashMap();
        if (!ObjectUtils.isEmpty(responseEntity)) {
            result = JSONObject.parseObject(responseEntity.getBody(), HashMap.class);
            if (AnxinContants.SUCCESS_CODE.equals(result.get("code") == null ? "" : result.get("code").toString())) {
                //保存调用记录
                saveInvokeRecord(tenant, tenant.getTrustNo(), api, headers.toString(), paramsMap, result);
                return result;
            }
        }
        if (StringUtils.isEmpty(errorMsg)){
            errorMsg = JSONObject.toJSONString(result);
        }
        pullDataFailureLogService.saveErrorData(tenant.getTenantName(),
                PullDataFailureUtil.createErrorMap(tenant.getTrustNo(), api, headers, "appKey="+ appKey + "&params=" + paramStr, errorMsg ));
        return result;
    }

    public void saveInvokeRecord(TenantEscrowAuthorizationInfoDto tenant, String trustNo, String invokeType, String headers, Map<String, Object> params, Map<String, Object> invokeResult) {
        Date now = new Date();
        InvokeRecordEntity invokeRecordEntity = InvokeRecordEntity.builder()
                .trustNo(trustNo)
                .admin(tenant.getTenantName())
                .invokeType(invokeType)
                .reqHeader(JSON.toJSONString(headers))
                .reqParam(JSON.toJSONString(params))
                .invokeTime(now)
                .invokeResult(JSON.toJSONString(invokeResult))
                .queryKey(tenant.getTenantName() + "::" + trustNo + "::" + invokeType)
                .createTime(now)
                .updateTime(now)
                .build();
        invokeRecordService.save(invokeRecordEntity);
    }
}
