package cn.quantgroup.customer.service.impl;

import cn.quantgroup.customer.model.order.*;
import cn.quantgroup.customer.rest.param.applyorder.ApplyOrderQuery;
import cn.quantgroup.customer.rest.vo.JsonResult;
import cn.quantgroup.customer.service.IFileService;
import cn.quantgroup.customer.service.IIceService;
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.ArrayUtils;
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 sun.security.pkcs11.wrapper.Constants;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service("iceService")
public class IceServiceImpl implements IIceService {

    @Value("${mo.ice.http}")
    private String iceUrl;

    @Value("${mo-sidecar.http}")
    private String sidecarUrl;

    private final IHttpService httpService;

    @Autowired
    private IFileService fileService;


    @Autowired
    public IceServiceImpl(IHttpService httpService) {
        this.httpService = httpService;
    }

    @Override
    public JsonResult<ApplyOrder> findApplyOrders(ApplyOrderQuery applyOrderQuery) {
        String logPre = "IceService.findApplyOrders";
        log.info("{} 申请订单查询 applyOrderQuery={}", logPre, applyOrderQuery);
        String orderNo = applyOrderQuery.getOrderNo();
        Long loanId = applyOrderQuery.getLoanId();
        Long userId = applyOrderQuery.getUserId();
        String url = iceUrl + "/ex/customer_sys/query/applyOrder";
        Map<String, Object> param = Maps.newHashMap();
        if (StringUtils.isNotEmpty(orderNo)) {
            param.put("orderNo", orderNo);
        }
        if (Objects.nonNull(userId)) {
            param.put("userId", userId.toString());
        }
        if (Objects.nonNull(loanId)) {
            param.put("loanId", loanId.toString());
        }
        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        String result = httpService.post(url, header, param);
        log.info("{} 用户申请订单列表 url={}, header={},param={},result={}", logPre, url, header, param, result);
        if (StringUtils.isBlank(result)) {
            log.error("{} 调用信用钱包失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("申请订单查询失败", null);
        }

        TypeReference<JsonResult<ApplyOrder>> typeToken = new TypeReference<JsonResult<ApplyOrder>>() {
        };
        JsonResult<ApplyOrder> jsonResult = JSONTools.deserialize(result, typeToken);
        return jsonResult;
    }

    @Override
    public JsonResult<LoanOrder> findLoanOrder(Long loanId) {
        String logPre = "IceService.findLoanOrder";
        log.info("{} 提现订单详情 loanId={}", logPre, loanId);
        String url = iceUrl + "/ex/customer_sys/loan/detail";
        if (Objects.isNull(loanId)) {
            log.error("{} 借款订单号为空 orderNo={}", logPre, loanId);
            return JsonResult.buildErrorStateResult("借款订单号为空", null);
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("loanId", loanId.toString());

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        String result = null;
        try {
            result = httpService.post(url, header, param);
            log.info("{} 提现订单详情 loanId={},result:{}", logPre, loanId, result);
        } catch (Exception e) {
            log.error("{} 远程调用异常 url={},param={}", logPre, url, param, e);
            return JsonResult.buildErrorStateResult("网络异常", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 调用信用钱包失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("提现订单详情查询失败", null);
        }
        TypeReference<JsonResult<LoanOrder>> typeToken = new TypeReference<JsonResult<LoanOrder>>() {
        };
        JsonResult<LoanOrder> jsonResult = JSONTools.deserialize(result, typeToken);

        return jsonResult;
    }

    @Override
    public JsonResult<List<FlowNode>> findFlowChart(String orderNo) {
        String logPre = "IceService.findFlowChart";
        log.info("{} 流程日志查询 orderNo={}", logPre, orderNo);
        String url = iceUrl + "/ex/customer_sys/query/flow";
        if (StringUtils.isEmpty(orderNo)) {
            log.error("{} 申请订单号为空 orderNo={}", logPre, orderNo);
            return JsonResult.buildErrorStateResult("申请订单号为空", null);
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("orderNo", orderNo);

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        String result = null;
        try {
            result = httpService.post(url, header, param);
            log.info("{} 流程日志查询 orderNo={},result:{}", logPre, orderNo, result);
        } catch (Exception e) {
            log.error("{} 通讯异常 url={},param={}", logPre, url, param, e);
            return JsonResult.buildErrorStateResult("通讯异常", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 调用信用钱包失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("流程日志查询失败", null);
        }
        TypeReference<JsonResult<List<FlowNode>>> typeToken = new TypeReference<JsonResult<List<FlowNode>>>() {
        };
        JsonResult<List<FlowNode>> jsonResult = JSONTools.deserialize(result, typeToken);
        return jsonResult;

    }

    @Override
    public JsonResult<List<SettleStatus>> findSettleFlag(List<Long> loanIds) {
        String logPre = "IceService.findSettleFlag";
        log.info("{} 结清状态查询 loanIds={}", logPre, loanIds);
        String url = sidecarUrl + "/middle_office/settle_proof/status";
        if (CollectionUtils.isEmpty(loanIds)) {
            log.error("{} 订单号全为空 loanIds={}", logPre, loanIds);
            return JsonResult.buildErrorStateResult("申请订单号为空", null);
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("loanIds", StringUtils.join(loanIds, ","));

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        String result;
        try {
            result = httpService.get(url, header, param);
            log.info("{} 结清状态查询 loanIds={},result:{}", logPre, loanIds, result);
        } catch (Exception e) {
            log.error("{} 通讯异常 url={},param={}", logPre, url, param, e);
            return JsonResult.buildErrorStateResult("通讯异常", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 调用失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("结清状态查询失败", null);
        }
        TypeReference<JsonResult<List<SettleStatus>>> typeToken = new TypeReference<JsonResult<List<SettleStatus>>>() {
        };
        JsonResult<List<SettleStatus>> jsonResult = JSONTools.deserialize(result, typeToken);
        return jsonResult;
    }

    @Override
    public JsonResult applySettle(Long loanId) {
        String logPre = "IceService.applySettle";
        log.info("{} 申请结清下载 loanIds={}", logPre, loanId);
        String url = sidecarUrl + "/middle_office/settle_proof/apply";
        if (loanId == null) {
            log.error("{} 申请订单号loanId为空", logPre);
            return JsonResult.buildErrorStateResult("申请订单号为空", null);
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("loanId", String.valueOf(loanId));

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        String result;
        try {
            result = httpService.post(url, header, param);
            log.info("{} 申请结清下载 loanId={},result:{}", logPre, loanId, result);
        } catch (Exception e) {
            log.error("{} 通讯异常 url={},param={}", logPre, url, param, e);
            return JsonResult.buildErrorStateResult("通讯异常", null);
        }

        if (StringUtils.isBlank(result)) {
            log.error("{} 调用失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("申请结清下载失败", null);
        }
        TypeReference<JsonResult> typeToken = new TypeReference<JsonResult>() {
        };
        return JSONTools.deserialize(result, typeToken);
    }

    @Override
    public JsonResult downloadSettle( HttpServletResponse response, Long loanId) {
        String logPre = "IceService.downloadSettle";
        log.info("{} 结清证明下载 loanIds={}", logPre, loanId);
        String url = sidecarUrl + "/middle_office/settle_proof/download";
        if (loanId == null) {
            log.error("{} 申请订单号loanId为空 loanId", logPre);
            return JsonResult.buildErrorStateResult("申请订单号为空", null);
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("loanId", String.valueOf(loanId));

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/x-www-form-urlencoded");
        byte[] result;
        try {
            result = httpService.getByte(url, header, param);
            log.info("{} 结清证明下载 loanId={},result:{}", logPre, loanId, result);
        } catch (Exception e) {
            log.error("{} 通讯异常 url={},param={}", logPre, url, param, e);
            return JsonResult.buildErrorStateResult("通讯异常", null);
        }

        if (result == null) {
            log.error("{} 调用失败 url={}, header={},param={},result={}", logPre, url, header, param, result);
            return JsonResult.buildErrorStateResult("结清证明下载失败,返回值为空", null);
        }
        return fileService.outputFile(response,  System.currentTimeMillis() + String.valueOf(loanId) +"settle.pdf", result);
    }
}
