package com.clx.performance.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.clx.performance.config.MslPaymentConfig;
import com.clx.performance.constant.ActionConstants;
import com.clx.performance.dao.ThirdPartRequestLogDao;
import com.clx.performance.dao.payment.OrderPaymentDao;
import com.clx.performance.encryption.oldmsl.PayEncryptTools;
import com.clx.performance.encryption.oldmsl.PrivateKeyConfig;
import com.clx.performance.encryption.oldmsl.SystemCodeEnum;
import com.clx.performance.enums.*;
import com.clx.performance.enums.payment.PayOperationStatusEnum;
import com.clx.performance.enums.payment.PaymentActionEnum;
import com.clx.performance.enums.payment.PaymentStatusEnum;
import com.clx.performance.model.ThirdPartRequestLog;
import com.clx.performance.model.payment.OrderPayment;
import com.clx.performance.param.pc.payment.*;
import com.clx.performance.service.PaymentService;
import com.clx.performance.service.ThirdPartRequestLogService;
import com.google.gson.Gson;
import com.msl.common.dto.HttpDTO;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.result.Result;
import com.msl.common.utils.EncryptUtil;
import com.msl.common.utils.HttpUtil;
import com.msl.common.utils.LocalDateTimeUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.GeneralSecurityException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.clx.performance.enums.HttpEnum.PERFORMANCE_PAY_CLX_PAYMENT;

@Service
@Slf4j
@AllArgsConstructor
public class PaymentServiceImpl implements PaymentService {

    public static final String TRANSPORT_USER = "13403503399";
    public static final String TRANSPORT_KEY = "9Y1N5AUP8N2TI359";
    /** 转账回调地址 **/
    public static final String NOTIFY_URL = "/clx-performance/payment/notify/userPayNotify";

    /** 违约回调地址 **/
    public static final String NOTIFY_BROKER_URL = "/clx-performance/payment/notify/userPayBrokerContractNotify";

    /** 司机平台押金冻结回调地址 **/
    public static final String NOTIFY_PLATFORM_FEE_URL = "/clx-performance/payment/notify/userPayDriverFreezeNotify";

    /** 司机平台押金冻结调整回调地址 **/
    public static final String NOTIFY_ADJUST_PLATFORM_FEE_URL = "/clx-performance/payment/notify/userPayAdjustDriverFreezeNotify";

    /** 司机平台押金冻结取消回调地址 **/
    public static final String NOTIFY_CANCEL_PLATFORM_FEE_URL = "/clx-performance/payment/notify/userPayCancelDriverFreezeNotify";
    /** 司机平台押金冻结完成回调地址 **/
    public static final String NOTIFY_COMPLETE_PLATFORM_FEE_URL = "/clx-performance/payment/notify/userPayCompleteDriverFreezeNotify";


    @Autowired
    private final MslPaymentConfig mslPaymentConfig;

    @Autowired
    ThirdPartRequestLogDao thirdPartRequestLogDao;

    @Autowired
    ThirdPartRequestLogService thirdPartRequestLogService;

    @Autowired
    OrderPaymentDao orderPaymentDao;

    @Autowired
    UniqueOrderNumService uniqueOrderNumService;

    /**
     * 钱包直接划账给钱包
     *
     * @param payDTO
     * @return
     */
    @Override
    public Result paymentWallet(PayParam payDTO) {
        /** 构建支付单元 **/
        PayUnitDTO payUnitDTO = PayUnitDTO.builder()
                .id(payDTO.getTradeId())
                .from(payDTO.getFrom())
                .to(payDTO.getTo())
                .figure(payDTO.getFigure())
                .type(PayUnitTypeEnum.RESIDUE_PAY.getCode())
                .timestamp(System.currentTimeMillis() / 1000)
                .remark(payDTO.getRemark()).build();
        /** 生成签名**/
        PayEncryptTools.sign(payUnitDTO, PrivateKeyConfig.privateKeyByte);

        /** 构建支付支付 ***/
        PayUserDTO payUserDTO = PayUserDTO.builder()
                .pwd(payDTO.getPwd())
                .system(SystemCodeEnum.PERFORMANCE_SERVICE.getCode())
                .userCode(payDTO.getFrom())
                .orderNo(payDTO.getTradeNo())
                .uuid(UUID.randomUUID().toString().replaceAll("-", ""))
                .notifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_URL)
                .payUnitDTO(payUnitDTO).build();
        log.info("发起支付请求日志 {}", JSON.toJSONString(payUserDTO));
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost()+ PERFORMANCE_PAY_CLX_PAYMENT.getUrl(), JSON.toJSONString(payUserDTO));
        log.info("支付返回日志 {}", notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }
        return notify;
    }



    /**
     * 钱包直接划账给钱包（违约）
     * @param payDTO
     * @return
     */
    @Override
    public Result paymentBreakContractWallet(PayParam payDTO) {
        /** 构建支付单元 **/
        PayUnitDTO payUnitDTO = PayUnitDTO.builder()
                .id(payDTO.getTradeId())
                .from(payDTO.getFrom())
                .to(payDTO.getTo())
                .figure(payDTO.getFigure())
                .type(PayUnitTypeEnum.RESIDUE_PAY.getCode())
                .timestamp(System.currentTimeMillis() / 1000)
                .remark(payDTO.getRemark()).build();
        /** 生成签名**/
        PayEncryptTools.sign(payUnitDTO, PrivateKeyConfig.privateKeyByte);

        /** 构建支付支付 ***/
        PayUserDTO payUserDTO = PayUserDTO.builder()
                .pwd(payDTO.getPwd())
                .system(SystemCodeEnum.PERFORMANCE_SERVICE.getCode())
                .userCode(payDTO.getFrom())
                .orderNo(payDTO.getTradeNo())
                .uuid(UUID.randomUUID().toString().replaceAll("-", ""))
                .notifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_BROKER_URL)
                .payUnitDTO(payUnitDTO).build();
        log.info("发起支付请求日志 {}", payUserDTO);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost()+ PERFORMANCE_PAY_CLX_PAYMENT.getUrl(), JSON.toJSONString(payUserDTO));
        log.info("支付返回日志 {}", notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }
        return notify;
    }

    /**
     * 创建支付流水记录
     * @param orderPayment
     */
    public void saveOrderPayment( OrderPayment orderPayment){
        orderPaymentDao.saveEntity(orderPayment);
    }


    /**
     * 冻结司机平台押金
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result paymentPlatformFee(PayPlatformFeeParam payDTO) {
        /** 创建记录 默认冻结 **/
        OrderPayment orderPayment = new OrderPayment()
                .setAmount(payDTO.getFigure())
                .setOrderNo(payDTO.getTradeNo())
                .setRelationNo(payDTO.getTradeNo())
                .setPaymentItem(PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "")
                .setStatus(PaymentStatusEnum.CREATE.getValue())
                .setOperation(PayOperationStatusEnum.FREEZE.getValue());
        saveOrderPayment(orderPayment);

        /** 构建司机冻结单元  **/
        PayUserDTO payUserDTO = buildDriverFreezeBatchDTO(payDTO, orderPayment);

        log.info("发起司机押金冻结支付请求日志 {}", payUserDTO);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost()
                + HttpEnum.PERFORMANCE_PAY_CLX_DRIVER_FREEZE.getUrl(), JSON.toJSONString(payUserDTO));
        log.info("支付司机押金冻结支付请求 返回日志 {}", notify);

        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }
        return notify;
    }

    /**
     * 调整司机平台押金
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result paymentChangePlatformFee(PayPlatformFeeParam param) {
         //查询冻结记录
        OrderPayment orderPaymentOptional =
                orderPaymentDao.selectByOrderNoAndItemIdAndOperation(param.getTradeNo(),
                PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "",
                        PayOperationStatusEnum.FREEZE.getValue()).orNull();
        if (null == orderPaymentOptional){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        /** 创建记录 新的调整记录 **/
        OrderPayment orderPayment = new OrderPayment()
                .setAmount(param.getFigure())
                .setOrderNo(param.getTradeNo())
                .setRelationNo(payOrderNoGenerate())
                .setSerialNo(orderPaymentOptional.getSerialNo())
                .setPaymentItem(PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "")
                .setStatus(PaymentStatusEnum.CREATE.getValue())
                .setOperation(PayOperationStatusEnum.ADJUSTMENT.getValue());
        saveOrderPayment(orderPayment);

        /**  调整冻结记录  **/
        FreezeBatchDTO freezeBatchDTO = buildChangeFreezeBatchDTO(orderPaymentOptional,orderPayment.getId() ,param.getFigure());

        log.info("发起支付请求日志 {}", freezeBatchDTO);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost() +
                HttpEnum.PERFORMANCE_PAY_CLX_ADJUST_DRIVER_FREEZE.getUrl(), JSON.toJSONString(freezeBatchDTO));
        log.info("支付返回日志 {}", notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            if(Objects.equals(notify.getCode(),1005)){
                throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR,
                        "预估接单保证金"+new BigDecimal(param.getFigureNew()).movePointLeft(2)+"元，车主钱包余额不足，请先充值");
            }else if(Objects.equals(notify.getCode(),6104)){
                throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR,
                        "预估接单保证金"+new BigDecimal(param.getFigureNew()).movePointLeft(2)+"元，车主钱包余额不足，请先充值");
            }
            else{
                throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
            }
        }
        return notify;
    }

    @Override
    public Result paymentCompletePlatformFee(PayPlatformFeeParam param) {
        List<OrderPayment> orderPaymentList = checkOrderPaymentExit(param);
        //如果没有冻结记录
        List<OrderPayment> orderPaymentFreezeList = orderPaymentList.stream()
                .filter(i -> i.getOperation().equals(PayOperationStatusEnum.FREEZE.getValue()))
                .filter(i -> i.getStatus().equals(PaymentStatusEnum.SUCCESS.getValue()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(orderPaymentFreezeList)){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        //冻结记录是否已经处理
        List<OrderPayment> orderPaymentUnFreezeList = orderPaymentList.stream()
                .filter(i -> i.getOperation().equals(PayOperationStatusEnum.UNFREEZE.getValue()))
                .filter(i -> i.getStatus().equals(PaymentStatusEnum.SUCCESS.getValue()))
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(orderPaymentUnFreezeList)){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"冻结记录已处理") ;
        }
        OrderPayment orderPaymentOptional = orderPaymentFreezeList.get(0);
        /** 创建记录 新的调整记录 **/
        OrderPayment orderPayment = new OrderPayment()
                .setAmount(param.getFigure())
                .setOrderNo(param.getTradeNo())
                .setRelationNo(orderPaymentOptional.getRelationNo())
                .setSerialNo(orderPaymentOptional.getSerialNo())
                .setPaymentItem(PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "")
                .setStatus(PaymentStatusEnum.CREATE.getValue())
                .setOperation(PayOperationStatusEnum.UNFREEZE.getValue());
        saveOrderPayment(orderPayment);

        /**  调整冻结记录  **/
        FreezeBatchDTO freezeBatchDTO = buildCompleteFreezeBatchDTO(orderPaymentOptional,
                orderPayment.getRelationNo());

        log.info("发起支付请求日志 {}", freezeBatchDTO);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost() +
                HttpEnum.PERFORMANCE_PAY_CLX_ADJUST_DRIVER_FREEZE.getUrl(), JSON.toJSONString(freezeBatchDTO));
        log.info("支付返回日志 {}", notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }
        return notify;
    }

    public List<OrderPayment> checkOrderPaymentExit(PayPlatformFeeParam param){
        //查询冻结记录
        List<OrderPayment> orderPaymentList= orderPaymentDao.listByOrderNo(param.getTradeNo(),
                PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "");
        if (CollectionUtils.isEmpty(orderPaymentList)){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        return orderPaymentList;
    }

    @Override
    public Result paymentCancelPlatformFee(PayPlatformFeeParam param) {
        List<OrderPayment> orderPaymentList = checkOrderPaymentExit(param);
        //如果没有冻结记录
        List<OrderPayment> orderPaymentFreezeList = orderPaymentList.stream()
                .filter(i -> i.getOperation().equals(PayOperationStatusEnum.FREEZE.getValue()))
                .filter(i -> i.getStatus().equals(PaymentStatusEnum.SUCCESS.getValue()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(orderPaymentFreezeList)){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        //冻结记录是否已经处理
        List<OrderPayment> orderPaymentUnFreezeList = orderPaymentList.stream()
                .filter(i -> i.getOperation().equals(PayOperationStatusEnum.UNFREEZE.getValue()))
                .filter(i -> i.getStatus().equals(PaymentStatusEnum.SUCCESS.getValue()))
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(orderPaymentUnFreezeList)){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"冻结记录已处理") ;
        }
        OrderPayment orderPaymentOptional = orderPaymentFreezeList.get(0);
        /** 创建记录 新的调整记录 **/
        OrderPayment orderPayment = new OrderPayment()
                .setAmount(param.getFigure())
                .setOrderNo(param.getTradeNo())
                .setRelationNo(orderPaymentOptional.getRelationNo())
                .setSerialNo(orderPaymentOptional.getSerialNo())
                .setPaymentItem(PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode() + "")
                .setStatus(PaymentStatusEnum.CREATE.getValue())
                .setOperation(PayOperationStatusEnum.UNFREEZE.getValue());
        saveOrderPayment(orderPayment);

        /**  调整冻结记录  **/
        FreezeBatchDTO freezeBatchDTO = buildCanCelFreezeBatchDTO(orderPaymentOptional,
                orderPayment.getRelationNo());

        log.info("发起支付请求日志 {}", freezeBatchDTO);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost() +
                HttpEnum.PERFORMANCE_PAY_CLX_ADJUST_DRIVER_FREEZE.getUrl(), JSON.toJSONString(freezeBatchDTO));
        log.info("支付返回日志 {}", notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }
        return notify;
    }

    @Override
    public void updateOrderPaymentFail(String orderNo, String msg,Integer operation, String paymentItem) {
        //查询冻结记录
        OrderPayment orderPaymentOptional =
                orderPaymentDao.selectByRelationNo(orderNo,operation,paymentItem).orNull();
        if (null == orderPaymentOptional){
            log.error("数据不存在 {}, {}" ,orderNo,msg);
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        orderPaymentOptional.setStatus(PaymentStatusEnum.FAIL.getValue());
        orderPaymentOptional.setReason(msg);
        orderPaymentDao.updateEntityByKey(orderPaymentOptional);
    }

    @Override
    public void updateOrderPaymentSuccess(String orderNo,Integer operation, String paymentItem) {
        //查询冻结记录
        OrderPayment orderPaymentOptional =
                orderPaymentDao.selectByRelationNo(orderNo,operation,paymentItem).orNull();
        if (null == orderPaymentOptional){
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND,"数据不存在") ;
        }
        orderPaymentOptional.setStatus(PaymentStatusEnum.SUCCESS.getValue());
        orderPaymentDao.updateEntityByKey(orderPaymentOptional);
    }


    @Override
    public void updateOrderPaymentStatusById(String id,int status) {
        //查询冻结记录
        OrderPayment orderPaymentOptional = orderPaymentDao.getEntityByKey(Integer.valueOf(id)).orNull();
        if (null == orderPaymentOptional){
            log.error("数据不存在 {}, {}" ,id);
            return;
        }
        orderPaymentOptional.setStatus(status);
        orderPaymentDao.updateEntityByKey(orderPaymentOptional);
    }

    @Override
    public void updateOrderPaymentSerialNoSuccess(String orderNo, String serialNo, Integer operation, String paymentItem) {
        OrderPayment orderPaymentOptional =
                orderPaymentDao.selectByRelationNo(orderNo,operation,paymentItem).orNull();
        if (null == orderPaymentOptional){
            log.error("数据不存在 {}, {}" ,orderNo);
            return;
        }
        orderPaymentOptional.setStatus(PaymentStatusEnum.SUCCESS.getValue());
        orderPaymentOptional.setSerialNo(serialNo);
        orderPaymentDao.updateEntityByKey(orderPaymentOptional);
    }




    /**
     * post请求
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Result<?> postRequest(String requestUrl, String param) {
        ThirdPartRequestLog log = ThirdPartRequestLog.builder()
                .requestId(UUID.randomUUID().toString())
                //应用编号 10000 默认诚联信
                .appNo(Long.valueOf(10000))
                .requestType(ThirdRequestTypeEnum.SEND.getCode())
                .action(ActionConstants.CLX_PAYMENT_PAY)
                .url(requestUrl)
                .requestContent(param)
                //状态: 0-请求中,1-成功,2-失败
                .status(0)
                .build();
        thirdPartRequestLogDao.saveEntity(log);
        return encryptPost(requestUrl, param, log.getId());
    }

    private Result<?> encryptPost(String url, String param, Integer httpLogId) {
        try {
            return HttpUtil.post(url, null,
                    EncryptUtil.buildDTO(TRANSPORT_USER, param, TRANSPORT_KEY, System.currentTimeMillis()))
                    .map(r -> JSON.parseObject(r, new TypeReference<HttpDTO>() {
                    }))
                    .peek(dto -> log.info("http请求返回------dto->{}", dto))
                    .mapTry(dto -> EncryptUtil.decrypt(dto.getData(), TRANSPORT_KEY))

                    .mapWithObj(new TypeReference<Result<Object>>() {
                    }, this::covertResult)
                    .peek(result -> thirdPartRequestLogService.updateResult(httpLogId, result))
//                    .filter(Result::succeed)
                    .orElseThrow();
        } catch (GeneralSecurityException e) {
            log.error("解密失败", e);
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, "http 请求异常");
        }
    }

    private <T> Result<T> covertResult(String result, TypeReference<Result<T>> reference) {
        return new Gson().fromJson(result, reference.getType());
    }


    /**
     * 创建支付流水号
     */
    private String payOrderNoGenerate() {
        return "5" + uniqueOrderNumService.getUniqueOrderNum(
                LocalDateTimeUtils.convertLocalDateTimeToString(LocalDateTime.now(), LocalDateTimeUtils.DATE_DAY));
    }


    /**
     * 构建司机冻结押金支付单元
     * @param payDTO
     * @param orderPayment
     * @return
     */
    public PayUserDTO   buildDriverFreezeBatchDTO(PayPlatformFeeParam payDTO,OrderPayment orderPayment){
        /** 构建支付单元 **/
        PayUnitDTO payUnitDTO = PayUnitDTO.builder()
                .id(orderPayment.getRelationNo())
                .from(payDTO.getFrom())
                .to(mslPaymentConfig.getSystemWalletCode())
                .figure(payDTO.getFigure())
                .type(PayUnitTypeEnum.FREEZE_PLATFORM_FEE.getCode())
                .timestamp(System.currentTimeMillis() / 1000)
                .remark(PayRemarkEnum.toString(PayRemarkEnum.DRIVER_CREDIT.getValue())).build();
        /** 生成签名**/
        PayEncryptTools.sign(payUnitDTO, PrivateKeyConfig.privateKeyByte);
        /** 构建支付支付 ***/
        PayUserDTO payUserDTO = PayUserDTO.builder()
                .pwd("noCheckPwd") // 暂时不校验用户密码
                .system(SystemCodeEnum.PERFORMANCE_SERVICE.getCode())
                .userCode(payDTO.getFrom())
                .orderNo(orderPayment.getRelationNo())
                .uuid(UUID.randomUUID().toString().replaceAll("-", ""))
                .notifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_PLATFORM_FEE_URL)
                .payUnitDTO(payUnitDTO).build();
        return payUserDTO;
    }
    /**
     * 构建 司机平台服务费冻结实体
     */
    public FreezeBatchDTO buildChangeFreezeBatchDTO(OrderPayment orderPaymentOptional,Integer orderNo,Integer figure){
        FreezeBatchDTO freezeBatchDTO = new FreezeBatchDTO();
        List<FreezeUnitDTO> FreezeUnitList = new ArrayList<FreezeUnitDTO>();
        FreezeUnitDTO freightPayUnitDTO = new FreezeUnitDTO();
        /** 操作类型 1撤销 2完成 3修改*/
        freightPayUnitDTO.setAction(PaymentActionEnum.Type.ADJUST.getCode());
        /** 赔偿金额(单位分)0全部返回 */
        freightPayUnitDTO.setFigure(Long.valueOf(figure));
        /** 冻结序列号 （流水号）*/
        freightPayUnitDTO.setFreezeNo(orderPaymentOptional.getSerialNo());
        freightPayUnitDTO.setRemark(PayRemarkEnum.toString(PayRemarkEnum.UPDATE_DRIVER_FREEZE.getValue()));
        freightPayUnitDTO.setTimestamp(System.currentTimeMillis() / 1000);
        PayEncryptTools.sign(freightPayUnitDTO, PrivateKeyConfig.privateKeyByte);
        FreezeUnitList.add(freightPayUnitDTO);

        freezeBatchDTO.setFreezeUnitList(FreezeUnitList);
        freezeBatchDTO.setOrderNo(orderNo+"");
        freezeBatchDTO.setSystem(SystemCodeEnum.PERFORMANCE_SERVICE.getCode());
        //回调地址
        freezeBatchDTO.setNotifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_ADJUST_PLATFORM_FEE_URL);
        freezeBatchDTO.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
        log.info("平衡司机冻结保证金支付调去参数==" + freezeBatchDTO.toString());
        return freezeBatchDTO;
    }

    /**
     * 构建 司机平台服务费取消实体
     */
    public FreezeBatchDTO buildCanCelFreezeBatchDTO(OrderPayment orderPaymentOptional,String orderNo){
        FreezeBatchDTO freezeBatchDTO = new FreezeBatchDTO();
        List<FreezeUnitDTO> FreezeUnitList = new ArrayList<FreezeUnitDTO>();

        FreezeUnitDTO payUnitDTO = new FreezeUnitDTO();
        /** 操作类型 1撤销 2完成 3修改*/
        payUnitDTO.setAction(PaymentActionEnum.Type.CANCEL.getCode());
        /** 赔偿金额(单位分)0全部返回 */
        payUnitDTO.setFigure(0L);
        /** 冻结序列号 （流水号）*/
        payUnitDTO.setFreezeNo(orderPaymentOptional.getSerialNo());
        payUnitDTO.setFee(0L);
        payUnitDTO.setRemark(PayRemarkEnum.toString(PayRemarkEnum.DRIVER_UNFREEZE.getValue()));
        payUnitDTO.setTimestamp(System.currentTimeMillis() / 1000);
        PayEncryptTools.sign(payUnitDTO, PrivateKeyConfig.privateKeyByte);
        FreezeUnitList.add(payUnitDTO);
        freezeBatchDTO.setFreezeUnitList(FreezeUnitList);
        freezeBatchDTO.setOrderNo(orderNo);
        freezeBatchDTO.setSystem(SystemCodeEnum.PERFORMANCE_SERVICE.getCode());
        //回调地址
        freezeBatchDTO.setNotifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_CANCEL_PLATFORM_FEE_URL);
        freezeBatchDTO.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
        log.info("运单取消 退还司机保证金 ==" + freezeBatchDTO.toString());
        return freezeBatchDTO;
    }


    /**
     * 构建 司机平台服务费完成实体
     */
    public FreezeBatchDTO buildCompleteFreezeBatchDTO(OrderPayment orderPaymentOptional,String String){
        FreezeBatchDTO freezeBatchDTO = new FreezeBatchDTO();
        List<FreezeUnitDTO> FreezeUnitList = new ArrayList<FreezeUnitDTO>();

        FreezeUnitDTO payUnitDTO = new FreezeUnitDTO();
        /** 操作类型 1撤销 2完成 3修改*/
        payUnitDTO.setAction(PaymentActionEnum.Type.COMPLETE.getCode());
        /** 赔偿金额(单位分)0全部返回 */
        payUnitDTO.setFigure(0L);
        /** 冻结序列号 （流水号）*/
        payUnitDTO.setFreezeNo(orderPaymentOptional.getSerialNo());
        payUnitDTO.setFee(0L);
        payUnitDTO.setRemark(PayRemarkEnum.toString(PayRemarkEnum.DRIVER_UNFREEZE.getValue()));
        payUnitDTO.setTimestamp(System.currentTimeMillis() / 1000);
        PayEncryptTools.sign(payUnitDTO, PrivateKeyConfig.privateKeyByte);
        FreezeUnitList.add(payUnitDTO);
        freezeBatchDTO.setFreezeUnitList(FreezeUnitList);
        freezeBatchDTO.setOrderNo(orderPaymentOptional.getRelationNo());
        freezeBatchDTO.setSystem(SystemCodeEnum.PERFORMANCE_SERVICE.getCode());
        //回调地址
        freezeBatchDTO.setNotifyUrl(mslPaymentConfig.getNotifyhost() + NOTIFY_COMPLETE_PLATFORM_FEE_URL);
        freezeBatchDTO.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
        log.info("运单 完成 支付 司机保证金 ==" + freezeBatchDTO.toString());
        return freezeBatchDTO;
    }

    /***
     * 获取用户的钱包
     * @param userCode
     * @return
     */
    @Override
    public WalletResidueDTO getWalletAndCard(Integer userCode) {
        WalletParam walletParam = new WalletParam();
        walletParam.setUserCode(userCode);
        Result<Object> notify = (Result<Object>) postRequest(mslPaymentConfig.getHost()
                + HttpEnum.PERFORMANCE_PAY_CLX_WALLET.getUrl(), JSON.toJSONString(walletParam));
        log.info("获取司机钱包 {} 返回日志 {}",userCode, notify);
        if (notify == null) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR);
        }
        if (notify.getCode() != 0) {
            throw new ServiceSystemException(PerformanceResultEnum.HTTP_ERROR, notify.getMsg());
        }

        return JSON.parseObject(notify.getData().toString(), WalletResidueDTO.class);
    }
}
