package com.quantgroup.asset.distribution.service.niwodai.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.quantgroup.asset.distribution.constant.RedisKeyConstants;
import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.service.alarm.IAlarmService;
import com.quantgroup.asset.distribution.service.httpclient.IHttpService;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiService;
import com.quantgroup.asset.distribution.service.niwodai.vo.*;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Base64;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class NiwodaiServiceImpl implements INiwodaiService {
    @Value("${niwodai.url.authDomain}")
    private String domain;
    @Value("${niwodai.url.dataDomain}")
    private String domain2;
    @Value("${niwodai.url.dataCheck}")
    private String dataImportCheckUrl;
    @Value("${niwodai.url.auth}")
    private String authUrl;
    @Value("${niwodai.url.incoming}")
    private String incomingUrl;
    private static String getIncomingResult = "/std/v1/apply-result";
    @Value("${niwodai.client.id}")
    private String clientId;
    @Value("${niwodai.client.secret}")
    private String clientSecret;

    @Autowired
    private IAlarmService alarmService;
    @Autowired
    IRedisService<String> iRedisService;
    @Autowired
    IHttpService iHttpService;

    @Override
    public NiwodaiDataImportCheckResponseVO dataImportCheck(NiwodaiDataImportCheckRequestVO requestVO, String uuid) {
        String token = getToken();
        if (StringUtils.isEmpty(token)) {
            log.error("你我贷准入检查时获取token失败, uuid : {}", uuid);
            throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
        }
        String result = iHttpService.postNiwodaiJson(domain2 + dataImportCheckUrl, commonHeader(token), JSON.toJSONString(requestVO), true);
        log.info("你我贷准入检查接口调用结束, uuid : {}, requestVo : {}, response : {}", uuid, JSON.toJSONString(requestVO), result);
        if (StringUtils.isNotEmpty(result)) {
            NiwodaiDataImportCheckResponseVO vo =  JSON.parseObject(result, NiwodaiDataImportCheckResponseVO.class);
            if (vo != null && vo.getPass() != null) {
                return JSON.parseObject(result, NiwodaiDataImportCheckResponseVO.class);
            }
        } else {
            // 先临时这么处理, 最后一个抛异常也先不删除了, 你我贷需要修复这个问题
            log.info("你我贷准入接口返回结果出现错误, 按拒绝处理, uuid : {}, response : {}", uuid, result);
            alarmService.dingtalkAlarm("Warn", "你我贷准入返回结果出现错误", "uuid : " + uuid
                    + " , 错误信息 : 3012->你我贷准入接口返回结果异常, response : " + result);
            return NiwodaiDataImportCheckResponseVO.createPassFalse();
        }
        throw new QGException(QGExceptionType.NIWODAI_PRE_AUDIT_RESULAT_ERROR, result);
    }

    @Override
    public NiwodaiIncomingResponseVO incoming(NiwodaiIncomingRequestVO requestVO, String uuid) {
        String token = getToken();
        if (StringUtils.isEmpty(token)) {
            log.error("你我贷进件时获取token失败, uuid : {}, bizNo : {}", uuid, requestVO.getOrderId());
            throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
        }
        String result = iHttpService.postNiwodaiJson(domain2 + incomingUrl, commonHeader(token), JSON.toJSONString(requestVO),false);
        log.info("你我贷进件接口审核接口结束, uuid : {}, bizNo : {}, response : {}", uuid, requestVO.getOrderId(), result);
        if (StringUtils.isNotEmpty(result)) {
            NiwodaiIncomingResponseVO vo = JSON.parseObject(result, NiwodaiIncomingResponseVO.class);
            if (vo != null && vo.getCode() != null) {
                return vo;
            }
        } else {
            // 下面抛异常的先不删了, 你我贷会修复这个问题
            log.info("你我贷进件审核接口返回结果出现错误, 按拒绝处理, uuid : {}, bizNo : {}, result : {}", uuid, requestVO.getOrderId(), result);
            alarmService.dingtalkAlarm("Warn", "你我贷进件返回结果出现错误", "bizNo : " + requestVO.getOrderId()
                    + " , uuid : " + uuid + " , 错误信息 : 3013->你我贷进件返回结果异常, response : " + result);
            return NiwodaiIncomingResponseVO.createRejectVo();
        }
        throw new QGException(QGExceptionType.NIWODAI_INCOMING_RESULT_ERROR, result);
    }

    @Override
    public NiwodaiIncomingResultResponseVO incoingResult(NiwodaiIncomingResultRequestVO requestVO){
        String token = getToken();
        if (StringUtils.isEmpty(token)) {
            log.error("你我贷获取进件结果时获取token失败, requestVO : {}", JSON.toJSONString(requestVO));
            throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
        }
        String result = iHttpService.postNiwodaiJson(domain2 + getIncomingResult, commonHeader(token), JSON.toJSONString(requestVO),true);
        if (StringUtils.isNotEmpty(result)){
            NiwodaiIncomingResultResponseVO vo = JSON.parseObject(result, NiwodaiIncomingResultResponseVO.class);
            if (vo != null && vo.getCode() != null) {
                return vo;
            }
        }
        throw new QGException(QGExceptionType.NIWODAI_INCOMING_AUDIT_RESULT_ERROR);
    }

    public String getToken() {
        String token = iRedisService.getString(RedisKeyConstants.NI_WO_DAI_TOKEN_KEY);
        if (StringUtils.isBlank(token)) {
            NiwodaiAccessTokenResponseVO vo = acquireAccessToken();
            if (vo != null){
                token = vo.getAccessToken();
                iRedisService.setStringEx(RedisKeyConstants.NI_WO_DAI_TOKEN_KEY,token,8, TimeUnit.MINUTES);
            }else {
                return null;
            }
        }
        return token;
    }

    public NiwodaiAccessTokenResponseVO acquireAccessToken() {
        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        header.put("Authorization", "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()));
        Map<String, String> parameters = Maps.newHashMap();
        parameters.put("grant_type", "client_credentials");
        String result = null;
        try {
            result = iHttpService.postNiwodai(domain + authUrl, header, parameters, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (StringUtils.isNotEmpty(result)) {
            return JSON.parseObject(result, NiwodaiAccessTokenResponseVO.class);
        }
        return null;
    }

    private static Map<String, String> commonHeader(String token) {
        Map<String, String> header = Maps.newHashMap();
        header.put("Authorization", " bearer " + token);
        header.put("Content-Type", "application/json");
        return header;
    }

}
