package cn.quantgroup.customer.service.impl;

import cn.quantgroup.customer.enums.ErrorCodeEnum;
import cn.quantgroup.customer.exception.BusinessException;
import cn.quantgroup.customer.model.kaordermapping.ApplyRequestHistory;
import cn.quantgroup.customer.model.kaordermapping.ChannelConfigurationResult;
import cn.quantgroup.customer.model.kaordermapping.LoanOrderMapping;
import cn.quantgroup.customer.model.order.ApplyOrder;
import cn.quantgroup.customer.model.order.CallbackRecordList;
import cn.quantgroup.customer.rest.param.ordermapping.OrderQueryParam;
import cn.quantgroup.customer.rest.vo.JsonResult;
import cn.quantgroup.customer.service.IKaService;
import cn.quantgroup.customer.service.http.IHttpService;
import cn.quantgroup.customer.util.JSONTools;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * @author Wang Xiangwei
 * @version 2020/3/9
 */
@Slf4j
@Service
public class KaServiceImpl implements IKaService {


    @Value("${qapi.http}")
    private String kaSysUrl;

    @Autowired
    private IHttpService httpService;

    @Override
    public JsonResult<LoanOrderMapping> findOrderMapping(OrderQueryParam orderQueryParam) {
        String logPre = "KaServiceImpl.findOrderMapping";
        log.info("{},获得orderMapping orderQueryParam={}", logPre, orderQueryParam);

        if (Objects.isNull(orderQueryParam)) {
            log.error("{} 查询参数为空 orderQueryParam={}", logPre, orderQueryParam);
            return JsonResult.buildErrorStateResult("查询参数为空", null);
        }

        String applyOrderNo = orderQueryParam.getApplyOrderNo();
        String channelOrderNo = orderQueryParam.getChannelOrderNo();
        Long loanId = orderQueryParam.getLoanId();
        Long channelId = orderQueryParam.getChannelId();

        String url = kaSysUrl + "/external/get/orderMapping";
        try {
            Map<String, Object> param = Maps.newHashMap();
            if (Objects.nonNull(applyOrderNo)) {
                param.put("applyOrderNo", applyOrderNo);
            }
            if (StringUtils.isNotBlank(channelOrderNo)) {
                param.put("channelOrderNo", channelOrderNo);
            }
            if (Objects.nonNull(channelId)) {
                param.put("channelId", channelId);
            }
            if (Objects.nonNull(loanId)) {
                param.put("loanId", loanId);
            }

            String result = null;
            try {
                result = httpService.get(url, param);
            } catch (Exception e) {
                log.error(" {}查询orderMapping失败http请求异常 url={},param={}", logPre, url, param, e);
                return JsonResult.buildErrorStateResult("通讯异常", null);
            }
            log.info("{} 请求ka系统返回值:{}", logPre, result);

            if (StringUtils.isBlank(result)) {
                log.error("{} 查询orderMapping失败 jsonResult={}", logPre, result);
                return JsonResult.buildErrorStateResult("查询数据异常", null);
            }
            TypeReference<JsonResult<LoanOrderMapping>> typeToken = new TypeReference<JsonResult<LoanOrderMapping>>() {
            };
            JsonResult<LoanOrderMapping> jsonResult = JSONTools.deserialize(result, typeToken);
            return jsonResult;


        } catch (Exception e) {
            log.error("{} 网络通讯异常,orderQueryParam:{},ex:{}", orderQueryParam, ExceptionUtils.getStackTrace(e));
            throw new BusinessException(ErrorCodeEnum.NET_ERROR);
        }

    }


    @Override
    public JsonResult<Map<String, String>> findChannelOrderNosByApplyOrderNos(List<String> applyOrderNos) {
        String logPre = "KaServiceImpl.findOrderMappingByApplyOrderNos";
        log.info("{},获得渠道订单号 applyOrderNos={}", logPre, applyOrderNos);

        if (CollectionUtils.isEmpty(applyOrderNos)) {
            log.error("{} 查询参数为空 applyOrderNos={}", logPre, applyOrderNos);
            return JsonResult.buildErrorStateResult("查询参数为空", null);
        }

        String url = kaSysUrl + "/external/query/channelOrder/applyNos";
        StringJoiner stringJoiner = new StringJoiner(",");
        applyOrderNos.forEach(e -> stringJoiner.add(e));
        Map<String, Object> param = Maps.newHashMap();
        param.put("applyNos", stringJoiner.toString());

        String result;
        try {
            result = httpService.get(url, param);
        } catch (Exception e) {
            log.error("{} 通过申请订单号获取渠道订单号失败", logPre, e);
            return JsonResult.buildErrorStateResult("查询渠道订单号失败", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 获得渠道订单号 jsonResult={}", logPre, result);
            return JsonResult.buildErrorStateResult("获得渠道订单号", null);
        }
        TypeReference<JsonResult<Map<String, String>>> typeToken = new TypeReference<JsonResult<Map<String, String>>>() {
        };
        JsonResult<Map<String, String>> jsonResult = JSONTools.deserialize(result, typeToken);

        return jsonResult;
    }

    @Override
    public JsonResult<List<ChannelConfigurationResult>> getAllChannelConfiguration() {
        String logPre = "KaServiceImpl.getAllChannelConfiguration";
        log.info("{},获得所有渠道", logPre);


        String url = kaSysUrl + "/external/query/all/channelConfiguration";


        String result;
        try {
            result = httpService.get(url);
        } catch (Exception e) {
            log.error("{} 获得所有渠道失败", logPre, e);
            return JsonResult.buildErrorStateResult("获得所有渠道失败", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 获得所有渠道 jsonResult={}", logPre, result);
            return JsonResult.buildErrorStateResult("获得所有渠道失败", null);
        }
        TypeReference<JsonResult<List<ChannelConfigurationResult>>> typeToken = new TypeReference<JsonResult<List<ChannelConfigurationResult>>>() {
        };
        JsonResult<List<ChannelConfigurationResult>> jsonResult = JSONTools.deserialize(result, typeToken);
        return jsonResult;
    }


    @Override
    public JsonResult<CallbackRecordList> querySendRecords(String applyNo, Long channelId) {
        String logPre = "[KaServiceImpl.querySendRecords] 查询发送通知记录";
        log.info("{}, applyNo={},channelId={}", logPre, applyNo, channelId);

        String url = kaSysUrl + "/external/query/orderCallBack";
        try {
            Map<String, Object> param = Maps.newHashMap();
            if (Objects.nonNull(applyNo)) {
                param.put("applyNo", applyNo);
            }

            if (Objects.nonNull(channelId)) {
                param.put("channelId", String.valueOf(channelId));
            }

            String result;
            try {
                result = httpService.get(url, param);
            } catch (Exception e) {
                log.error(" {} http请求异常 url={},param={}", logPre, url, param, e);
                return JsonResult.buildErrorStateResult(ErrorCodeEnum.NET_ERROR.getMessage(), null);
            }
            log.info("{} 请求ka系统返回值:{}", logPre, result);

            if (StringUtils.isBlank(result)) {
                log.error("{} 返回结果为空，查询失败 jsonResult={}", logPre, result);
                return JsonResult.buildErrorStateResult(ErrorCodeEnum.RETURN_ERROR.getMessage(), null);
            }
            TypeReference<JsonResult<CallbackRecordList>> typeToken = new TypeReference<JsonResult<CallbackRecordList>>() {
            };
            return JSONTools.deserialize(result, typeToken);
        } catch (Exception e) {
            log.error("{} 网络通讯异常,applyNo={},channelId={},ex:{}", applyNo, channelId, ExceptionUtils.getStackTrace(e));
            throw new BusinessException(ErrorCodeEnum.NET_ERROR);
        }
    }

    @Override
    public JsonResult<ApplyRequestHistory> queryLatestChannelRequestFlows(String applyNo, Long channelId) {
        String logPre = "[KaServiceImpl.queryLatestChannelRequestFlows] 查询最新渠道进件请求流水";
        log.info("{}, applyNo={},channelId={}", logPre, applyNo, channelId);

        String url = kaSysUrl + "/external/query/applyRequest";
        try {
            Map<String, Object> param = Maps.newHashMap();
            if (Objects.isNull(channelId) || StringUtils.isBlank(applyNo)) {
                log.error("{} 查询渠道进件流水，渠道号和渠道订单号不允许为空 applyNo={},channelId={}", logPre, applyNo, channelId);
                return JsonResult.buildErrorStateResult(ErrorCodeEnum.PARAM_ERROR.getMessage(), ErrorCodeEnum.PARAM_ERROR.getCode());
            }

            param.put("applyNo", applyNo);
            param.put("channelId", String.valueOf(channelId));


            String result;
            try {
                result = httpService.get(url, param);
            } catch (Exception e) {
                log.error(" {} http请求异常 url={},param={}", logPre, url, param, e);
                return JsonResult.buildErrorStateResult(ErrorCodeEnum.NET_ERROR.getMessage(), null);
            }
            log.info("{} 请求ka系统返回值:{}", logPre, result);

            if (StringUtils.isBlank(result)) {
                log.error("{} 返回结果为空，查询失败 jsonResult={}", logPre, result);
                return JsonResult.buildErrorStateResult(ErrorCodeEnum.RETURN_ERROR.getMessage(), null);
            }
            TypeReference<JsonResult<ApplyRequestHistory>> typeToken = new TypeReference<JsonResult<ApplyRequestHistory>>() {
            };
            return JSONTools.deserialize(result, typeToken);
        } catch (Exception e) {
            log.error("{} 网络通讯异常,applyNo={},channelId={},ex:{}", applyNo, channelId, ExceptionUtils.getStackTrace(e));
            throw new BusinessException(ErrorCodeEnum.NET_ERROR);
        }
    }
}
