package com.zhongshu.card.server.core.service.pay;

import cn.hutool.core.util.ArrayUtil;
import com.github.microservice.core.util.JsonUtil;
import com.github.microservice.core.util.bean.BeanUtil;
import com.github.microservice.core.util.queue.ExecuteQueueUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.pay.client.model.AccountModel;
import com.github.microservice.pay.client.model.PayProductParameter;
import com.github.microservice.pay.client.model.chinaSenseless.*;
import com.github.microservice.pay.client.model.ledger.TransactionLogModel;
import com.github.microservice.pay.client.model.ledger.TransferTransactionsModel;
import com.github.microservice.pay.client.model.ledger.TransferTransactionsModels;
import com.github.microservice.pay.client.product.senseless.chinaumsSenseless.conf.ChinaumsSenselessConf;
import com.github.microservice.pay.client.ret.ResultState;
import com.github.microservice.pay.client.service.PayProductAccountService;
import com.github.microservice.pay.client.service.ledger.TransactionLogService;
import com.github.microservice.pay.client.service.product.SenselessPayService;
import com.github.microservice.pay.client.type.ledger.TransactionStatus;
import com.github.microservice.pay.client.type.ledger.TransactionType;
import com.github.microservice.types.payment.PaymentChannelType;
import com.github.microservice.types.payment.PaymentType;
import com.zhongshu.card.client.model.pay.ChinaumsSenselessUserSignInfoModel;
import com.zhongshu.card.client.model.pay.SatInfoModel;
import com.zhongshu.card.client.model.pay.UnionApplySignParam;
import com.zhongshu.card.client.type.ContractState;
import com.zhongshu.card.client.type.ShareOrderType;
import com.zhongshu.card.client.utils.DateUtils;
import com.zhongshu.card.server.core.dao.pay.ChinaumsSenselessUserSignInfoDao;
import com.zhongshu.card.server.core.dao.pay.ShareOrderDao;
import com.zhongshu.card.server.core.domain.pay.ChinaumsSenselessUserSignInfo;
import com.zhongshu.card.server.core.domain.pay.PayAccount;
import com.zhongshu.card.server.core.domain.pay.ShareOrder;
import com.zhongshu.card.server.core.model.pay.RefundVaFld;
import com.zhongshu.card.server.core.model.pay.UnionFrictionlessPayFinishModel;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.paySetting.OrgPayAccountService;
import com.zhongshu.card.server.core.service.paySetting.ProjectMainPaySettingService;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.server.core.util.CommonUtil;
import io.micrometer.common.util.StringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ChinaumsSenselessPayService extends SuperService {

    @Autowired
    OrgPayAccountService orgPayAccountService;

    @Autowired
    ChinaumsSenselessUserSignInfoDao chinaumsSenselessUserSignInfoDao;

    @Autowired
    SenselessPayService senselessPayService;

    @Autowired
    PayProductAccountService payProductAccountService;

    @Autowired
    PayAccountService payAccountService;

    @Autowired
    TransactionLogService transactionLogService;

    @Autowired
    ShareOrderDao shareOrderDao;

    @Autowired
    private ProjectMainPaySettingService projectMainPaySettingService;

    /**
     * 银联申请签约
     *
     * @return
     */
    public ResultContent signApply(UnionApplySignParam param) {

        String projectOid = param.getProjectOid();
        String userId = param.getUserId();

        if (StringUtils.isBlank(userId)) {
            userId = getCurrentUserId();
        }

        if (StringUtils.isBlank(projectOid)) {
            projectOid = getCurrentProjectOid();
        }

        //获取银联支付产品账户及需要签约的商户号
        String accountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        com.github.microservice.pay.client.ret.ResultContent<AccountModel> accountModelResultContent = payProductAccountService.get(accountName);
        if (!accountModelResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(accountModelResultContent.getMsg());
        }
        ChinaumsSenselessConf conf = (ChinaumsSenselessConf) accountModelResultContent.getContent().getConf();
        String mid = conf.getMchId();

        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMidAndExpire(userId, mid, false);
        param.setContractNo(CommonUtil.UUID());

        if (userSignInfo != null && userSignInfo.getContractState() != null) {
            switch (userSignInfo.getContractState()) {
                case SIGNED -> {//已签约
                    return ResultContent.buildFail("签约已完成，请勿重复请求");
                }
                case UNSIGNED -> {//未签约，已解约
                    return signApply(param, accountName, userId, mid);
                }
                case RESCISSION -> {
                    userSignInfo.setExpire(true);
                    chinaumsSenselessUserSignInfoDao.save(userSignInfo);
                    return signApply(param, accountName, userId, mid);
                }
                case APPLY -> {
                    if (System.currentTimeMillis() >= userSignInfo.getExpireTime()) {
                        userSignInfo.setExpire(true);
                        chinaumsSenselessUserSignInfoDao.save(userSignInfo);
                        ChinaumsSenselessUserSignInfo newUserSignInfo = new ChinaumsSenselessUserSignInfo();
                        newUserSignInfo.setContractState(ContractState.UNSIGNED);
                        return ResultContent.buildContent(newUserSignInfo);
                    }
                    return ResultContent.buildContent(toUserSignModel(userSignInfo));
                }
                case UNKNOWN -> {
                    return ResultContent.buildFail("未知状态，请联系管理人员");
                }
                case DELETING_CONTRACT -> {
                    return ResultContent.buildFail("解约中，请等待银行返回结果");
                }
            }
        } else {
            return signApply(param, accountName, userId, mid);
        }

        return ResultContent.buildFail("数据不存在，请联系管理员");
    }

    @SneakyThrows
    private ResultContent signApply(UnionApplySignParam param, String accountName, String userId, String mid) {
        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
        payProductParameter.setAccountName(accountName);
        payProductParameter.setMeta(BeanUtil.bean2Map(param));
        com.github.microservice.pay.client.ret.ResultContent<Object> signApplyResultContent = senselessPayService.signApply(payProductParameter);
        if (signApplyResultContent.getState().equals(ResultState.Success)) {
            Object content = signApplyResultContent.getContent();
            String json = JsonUtil.toJson(content);
            Map resultMap = JsonUtil.toObject(json, Map.class);
            String errMsg = (String) resultMap.get("errMsg");
            if ("success".equals(errMsg)) {
                ChinaumsSenselessUserSignInfo userSignInfo = new ChinaumsSenselessUserSignInfo();
                userSignInfo.setUserId(userId);
                userSignInfo.setContractNo(param.getContractNo());
                userSignInfo.setContractState(ContractState.APPLY);
                userSignInfo.setMid(mid);
                userSignInfo.setRelateSsn((String) resultMap.get("relateSsn"));
                userSignInfo.setCqpMpAppId((String) resultMap.get("cqpMpAppId"));
                userSignInfo.setCqpMpPath((String) resultMap.get("cqpMpPath"));
                userSignInfo.setExpireTime(System.currentTimeMillis() + 30 * 60 * 1000);
                userSignInfo.setExpire(false);
                chinaumsSenselessUserSignInfoDao.save(userSignInfo);
                return ResultContent.buildContent(signApplyResultContent.getContent());
            } else {
                return ResultContent.buildFail((String) resultMap.get("errMsg"));
            }
        }
        return ResultContent.buildFail("银联请求失败");
    }

    public boolean isSigned(String projectOid, String userId) {
        String mid = projectMainPaySettingService.getProjectPaymentMchId(projectOid, PaymentType.UnionFrictionlessPay);
        if (org.apache.commons.lang3.StringUtils.isEmpty(mid)) {
            return false;
        }
        ChinaumsSenselessUserSignInfo topByUserIdAndMidAndExpire = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMidAndExpire(userId, mid, false);
        return topByUserIdAndMidAndExpire.getContractState().equals(ContractState.SIGNED);
    }

    /**
     * 解约
     */
    @SneakyThrows
    public Object signCancel(String userId, String projectOid) {
        if (StringUtils.isBlank(userId)) {
            userId = getCurrentUserId();
        }

        if (StringUtils.isBlank(projectOid)) {
            projectOid = getCurrentProjectOid();
        }

        //获取银联支付产品账户及需要签约的商户号
        String accountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        com.github.microservice.pay.client.ret.ResultContent<AccountModel> accountModelResultContent = payProductAccountService.get(accountName);
        if (!accountModelResultContent.getState().equals(ResultState.Success)) {
            return accountModelResultContent;
        }
        ChinaumsSenselessConf conf = (ChinaumsSenselessConf) accountModelResultContent.getContent().getConf();
        String mid = conf.getMchId();

        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMidAndExpire(userId, mid, false);
        if (userSignInfo == null) {
            return ResultContent.buildFail("用户与该商户未签约");
        }

        if (userSignInfo.getContractState() == null) {
            return ResultContent.buildFail("签约状态数据异常");
        }

        if (userSignInfo.getContractState().equals(ContractState.RESCISSION)) {
            return ResultContent.buildFail("当前已经处于解约状态");
        }

        if (userSignInfo.getContractState().equals(ContractState.SIGNED)) {
            PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
            payProductParameter.setAccountName(accountName);
            payProductParameter.setMeta(Map.of("contractId", userSignInfo.getContractId()));
            com.github.microservice.pay.client.ret.ResultContent<Object> objectResultContent = senselessPayService.signCancel(payProductParameter);
            if (objectResultContent.getState().equals(ResultState.Success)) {
                String json = JsonUtil.toJson(objectResultContent.getContent());
                Map resultMap = JsonUtil.toObject(json, Map.class);
                String errMsg = (String) resultMap.get("errMsg");
                if ("success".equals(errMsg)) {
                    userSignInfo.setContractState(ContractState.RESCISSION);
                    chinaumsSenselessUserSignInfoDao.save(userSignInfo);
                    return ResultContent.buildSuccess();
                }
                return ResultContent.buildFail((String) resultMap.get("errMsg"));
            }
            return ResultContent.buildFail("解约失败");
        }

        return ResultContent.buildFail("当前状态不可解约，请稍后再试");
    }


    //TODO 添加 判断是否在平台外已经签约逻辑
    public ResultContent<ChinaumsSenselessUserSignInfoModel> queryUserSignInfo(String userId, String projectOid) {
        if (StringUtils.isBlank(userId)) {
            userId = getCurrentUserId();
        }

        if (StringUtils.isBlank(projectOid)) {
            projectOid = getCurrentProjectOid();
        }

        //获取银联支付产品账户及需要签约的商户号
        String accountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        com.github.microservice.pay.client.ret.ResultContent<AccountModel> accountModelResultContent = payProductAccountService.get(accountName);
        if (!accountModelResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(accountModelResultContent.getMsg());
        }
        ChinaumsSenselessConf conf = (ChinaumsSenselessConf) accountModelResultContent.getContent().getConf();
        String mid = conf.getMchId();

        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMidAndExpire(userId, mid, false);
        if (userSignInfo == null) {
            ChinaumsSenselessUserSignInfoModel model = new ChinaumsSenselessUserSignInfoModel();
            model.setUserId(userId);
            model.setContractState(ContractState.UNSIGNED);
            return ResultContent.buildContent(model);
        }
        return ResultContent.buildContent(toUserSignModel(userSignInfo));
    }

    /**
     * 支付
     */
    @SneakyThrows
    public ResultContent senselessPay(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String remark, List<SatInfoModel> satInfoModel) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("获取支付配置");
        String projectAccountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        //获取银联支付产品账户及需要签约的商户号

        com.github.microservice.pay.client.ret.ResultContent<AccountModel> projectAccountModelResultContent = payProductAccountService.get(projectAccountName);
        if (!projectAccountModelResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(projectAccountModelResultContent.getMsg());
        }
        ChinaumsSenselessConf projectConf = (ChinaumsSenselessConf) projectAccountModelResultContent.getContent().getConf();
        String mid = projectConf.getMchId();
        stopWatch.stop();

        stopWatch.start("获取签约参数");
        //获取用户签约协议号
        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMidAndExpire(userId, mid, false);
        if (userSignInfo == null || !userSignInfo.getContractState().equals(ContractState.SIGNED)) {
            return ResultContent.buildFail("用户未签约或状态未知");
        }
        stopWatch.stop();

        stopWatch.start("构建支付参数");
        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
        payProductParameter.setAccountName(projectAccountName);
        ChinaSenselessPayRequest request = new ChinaSenselessPayRequest();
        request.setMchntOrderId(orderNo);

        request.setContractId(userSignInfo.getContractId());
        request.setTotalAmount(total.toBigInteger().toString());
        request.setAttachedData(remark);

        VaFld vaFld = new VaFld();

        List<SatInfo> satInfos = buildSatInfo(projectOid, total, orderNo, projectConf.getSysSourceNo(), satInfoModel);
        vaFld.setSatInfo(satInfos);

        request.setVaFld(vaFld);
        request.setSrcReserve(JsonUtil.toJson(Map.of("userId", userId, "oid", oid, "projectOid", projectOid, "orderNo", orderNo, "prefix", projectConf.getOrderNoPrefix())));
        payProductParameter.setMeta(BeanUtil.bean2Map(request));

        stopWatch.stop();
        stopWatch.start("请求银联");
        com.github.microservice.pay.client.ret.ResultContent<Object> collectionResultContent = senselessPayService.collection(payProductParameter);
        if (!collectionResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail("请求失败");
        }
        stopWatch.stop();
        stopWatch.start("转换支付结果");


        Map bodyMap = JsonUtil.toObject(JsonUtil.toJson(collectionResultContent.getContent()), Map.class);
        stopWatch.stop();
        log.info("time==; {}", stopWatch.prettyPrint());
        if (bodyMap.get("respCode").equals("0000")) {
            return ResultContent.buildContent(collectionResultContent.getContent());
        }

        return ResultContent.buildFail(bodyMap.get("respDesc").toString());
    }

    private List<SatInfo> buildSatInfo(String projectOid, BigDecimal total, String orderNo, String sysSourceNo, List<SatInfoModel> satInfoModels) {

        return satInfoModels.stream().map(model -> {
            if (BigDecimal.ZERO.compareTo(model.getRatio()) >= 0) {
                return null;
            }
            String orgAccountName = orgPayAccountService.queryOgPayAccount(model.getOid(), PaymentType.UnionFrictionlessPay);

            com.github.microservice.pay.client.ret.ResultContent<AccountModel> orgAccountModelResultContent = payProductAccountService.get(orgAccountName);
            if (!orgAccountModelResultContent.getState().equals(ResultState.Success)) {
                throw new RuntimeException("orgAccountModelResultContent.getMsg()");
            }
            ChinaumsSenselessConf orgConf = (ChinaumsSenselessConf) orgAccountModelResultContent.getContent().getConf();

            String shareOrderNo = buildShareOrderNo(sysSourceNo);

            SatInfo satInfo = new SatInfo();
            satInfo.setMerId(orgConf.getMchId());
            satInfo.setFeeBear("Y");
            BigDecimal ratioTotal = total.multiply(model.getRatio().movePointLeft(2));
            satInfo.setSatAmt(ratioTotal.toBigInteger().toString());
            satInfo.setMerOrderId(shareOrderNo);

            ShareOrder shareOrder = new ShareOrder();
            shareOrder.setOrderNo(orderNo);
            shareOrder.setOid(model.getOid());
            shareOrder.setProjectOid(projectOid);

            shareOrder.setAmount(ratioTotal.toBigInteger().longValue());
            shareOrder.setRatio(model.getRatio().movePointLeft(2));
            shareOrder.setShareOrderType(ShareOrderType.Pay);
            shareOrder.setShareOrderNo(shareOrderNo);
            shareOrderDao.save(shareOrder);
            return satInfo;
        }).toList();
    }

    private String buildShareOrderNo(String sysSourceNo){
        return sysSourceNo + DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyyMMddHHmmssSSS) + CommonUtil.randomCode(7);
    }

    /**
     * orderNo: 支付订单号
     * refundOrderNo 退款订单号
     */
    @SneakyThrows
    public ResultContent<UnionFrictionlessPayFinishModel> refund(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String refundOrderNo, String remark, String targetOrderId) {

        String projectAccountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        //获取银联支付产品账户及需要签约的商户号


        com.github.microservice.pay.client.ret.ResultContent<AccountModel> projectAccountModelResultContent = payProductAccountService.get(projectAccountName);
        if (!projectAccountModelResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(projectAccountModelResultContent.getMsg());
        }

        ChinaumsSenselessConf projectConf = (ChinaumsSenselessConf) projectAccountModelResultContent.getContent().getConf();

        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
        payProductParameter.setAccountName(projectAccountName);
        ChinaSenselessRefundRequest request = new ChinaSenselessRefundRequest();
        request.setMchntOrderId(orderNo);
        request.setRefundOrderId(refundOrderNo);
        request.setRefundAmount(total.toBigInteger().toString());
        request.setTargetOrderId(targetOrderId);

        //TODO 放到扩展字段里，然后收到回调的时候再处理
        List<ShareOrder> shareOrderList = shareOrderDao.findByOrderNoAndProjectOidAndShareOrderType(orderNo, projectOid, ShareOrderType.Pay);
        List<SatInfo> satInfos = shareOrderList.stream().map(shareOrder -> {
            String orgAccountName = orgPayAccountService.queryOgPayAccount(shareOrder.getOid(), PaymentType.UnionFrictionlessPay);
            com.github.microservice.pay.client.ret.ResultContent<AccountModel> orgAccountModelResultContent = payProductAccountService.get(orgAccountName);
            if (!orgAccountModelResultContent.getState().equals(ResultState.Success)) {
                throw new RuntimeException(orgAccountModelResultContent.getMsg());
            }
            ChinaumsSenselessConf orgConf = (ChinaumsSenselessConf) orgAccountModelResultContent.getContent().getConf();

            String shareOrderNo = projectConf.getSysSourceNo() + DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyyMMddHHmmssSSS) + CommonUtil.randomCode(7);

            SatInfo satInfo = new SatInfo();
            satInfo.setMerId(orgConf.getMchId());
            BigDecimal multiplyTotal = total.multiply(shareOrder.getRatio(), new MathContext(4));
            satInfo.setRefundAmt(multiplyTotal.toBigInteger().toString());
            satInfo.setRefundOrderId(shareOrderNo);
            satInfo.setOriMerOrderId(shareOrder.getShareOrderNo());
            ShareOrder refundShareOrder = new ShareOrder();
            refundShareOrder.setOrderNo(orderNo);
            refundShareOrder.setOid(shareOrder.getOid());
            refundShareOrder.setProjectOid(projectOid);
            refundShareOrder.setAmount(multiplyTotal.toBigInteger().longValue());
            refundShareOrder.setRatio(shareOrder.getRatio());
            refundShareOrder.setShareOrderType(ShareOrderType.Refund);
            refundShareOrder.setShareOrderNo(shareOrderNo);
            refundShareOrder.setOriShareOrderNo(shareOrder.getShareOrderNo());
            shareOrderDao.save(refundShareOrder);
            return satInfo;
        }).toList();

        VaFld vaFld = new VaFld();
        vaFld.setSatInfo(satInfos);
        request.setVaFld(vaFld);

        request.setSrcReserve(JsonUtil.toJson(Map.of("userId", userId, "oid", oid, "projectOid", projectOid, "orderNo", refundOrderNo, "prefix", projectConf.getOrderNoPrefix())));
        payProductParameter.setMeta(BeanUtil.bean2Map(request));
        com.github.microservice.pay.client.ret.ResultContent<Object> refundResultContent = senselessPayService.refund(payProductParameter);
        if (!refundResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(refundResultContent.getMsg());
        }
        Map bodyMap = JsonUtil.toObject(JsonUtil.toJson(refundResultContent.getContent()), Map.class);

        if (bodyMap.get("respCode").equals("TARGET_PROCESSING")) {
            UnionFrictionlessPayFinishModel unionFrictionlessPayFinishModel = ExecuteQueueUtil.execute(5, index -> {
                return Map.of(1, 1000L, 2, 1000L, 3, 1000L, 4, 2000L).getOrDefault(index, 3000L);
            }, it -> {
                var result = new ExecuteQueueUtil.Result<UnionFrictionlessPayFinishModel>();

                ResultContent<UnionFrictionlessPayFinishModel> refundQuery = refundQuery(projectOid, userId, oid, refundOrderNo, true);
                if (!refundQuery.getState().equals(com.github.microservice.net.ResultState.Success)) {
                    log.info("查询退款结果失败：{}", refundQuery.getMsg());
                    return null;
                }
                if (refundQuery.getContent().getRefundStatus().equals("SUCCESS") || refundQuery.getContent().getRefundStatus().equals("FAIL")) {
                    result.setData(refundQuery.getContent());
                    result.setDone(true);
                    return result;
                }else if (refundQuery.getContent().getRefundStatus().equals("PROCESSING")) {
                    if (it.getIndex()>4){
                        result.setData(refundQuery.getContent());
                        result.setDone(true);
                        return result;
                    }
                    return null;
                }

                log.info("退款状态未知或退款中，继续查询，index:{}", it.getIndex());
                return null;
            });
            return ResultContent.buildContent(unionFrictionlessPayFinishModel);
        }
        return ResultContent.buildFail(bodyMap.get("respDesc").toString());
    }

    @SneakyThrows
    public ResultContent<UnionFrictionlessPayFinishModel> refundQuery(String projectOid, String userId, String oid, String refundOrderNo, Boolean handle) {
        String projectAccountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
        com.github.microservice.pay.client.ret.ResultContent<AccountModel> projectAccountModelResultContent = payProductAccountService.get(projectAccountName);
        if (!projectAccountModelResultContent.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail(projectAccountModelResultContent.getMsg());
        }
        ChinaumsSenselessConf projectConf = (ChinaumsSenselessConf) projectAccountModelResultContent.getContent().getConf();

        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
        payProductParameter.setAccountName(projectAccountName);
        payProductParameter.setMeta(Map.of("mchntOrderId", refundOrderNo, "srcReserve", JsonUtil.toJson(Map.of("userId", userId, "oid", oid, "projectOid", projectOid, "orderNo", refundOrderNo, "prefix", projectConf.getOrderNoPrefix()))));

        com.github.microservice.pay.client.ret.ResultContent<Object> refundQuery = senselessPayService.refundQuery(payProductParameter);
        if (!refundQuery.getState().equals(ResultState.Success)) {
            return ResultContent.buildFail("请求失败");
        }

        Map refundBody = JsonUtil.toObject(JsonUtil.toJson(refundQuery.getContent()), Map.class);
        if (!refundBody.get("respCode").equals("0000")) {
            return ResultContent.buildFail(refundBody.get("respDesc").toString());
        }
//        String refundOrderId = (String) refundBody.get("refundOrderId");
//        ChinaumsSenselessSrcReserve srcReserve = JsonUtil.toObject(JsonUtil.toJson(refundBody.get("srcReserve")), ChinaumsSenselessSrcReserve.class);
//
//        if (org.apache.commons.lang3.StringUtils.isNotEmpty(refundOrderId) && refundOrderId.startsWith(srcReserve.getPrefix())){
//            refundOrderId = refundOrderId.substring(srcReserve.getPrefix().length());
//        }

        UnionFrictionlessPayFinishModel unionFrictionlessPayFinishModel = new UnionFrictionlessPayFinishModel();
        unionFrictionlessPayFinishModel.setStatus((String) refundBody.get("status"));
        unionFrictionlessPayFinishModel.setRefundStatus((String) refundBody.get("refundStatus"));
        unionFrictionlessPayFinishModel.setRefundOrderId(refundOrderNo);
        unionFrictionlessPayFinishModel.setMerOrderId(((String) refundBody.get("mchntOrderId")).substring(projectConf.getOrderNoPrefix().length()));
        unionFrictionlessPayFinishModel.setTargetOrderId((String) refundBody.get("refundTargetOrderId"));

        if (handle && refundBody.get("status").equals("TRADE_SUCCESS") && refundBody.get("refundStatus").equals("SUCCESS")) {
            RefundVaFld vaFld = JsonUtil.toObject(JsonUtil.toJson(refundBody.get("vaFld")), RefundVaFld.class);
            com.github.microservice.pay.client.ret.ResultContent<List<TransactionLogModel>> listResultContent = handleRefund(projectOid,
                    oid,
                    userId,
                    new BigDecimal((String) refundBody.get("sendBackAmount")),
                    refundOrderNo, null, vaFld);
            unionFrictionlessPayFinishModel.setTransactionLogModelList(listResultContent);
        }
        return ResultContent.buildContent(unionFrictionlessPayFinishModel);
    }


    public com.github.microservice.pay.client.ret.ResultContent<List<TransactionLogModel>> handlePay(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String remark) {
        //TODO 判断支付状态

        //获取项目总账
//        PayAccount projectAccount = payAccountService.getProjectChildren(projectOid, PaymentChannelType.SecretFreePayment);
        //获取用户无感支付子账户
        PayAccount userBalancePayment = payAccountService.getUserChildren(projectOid, userId, PaymentChannelType.SecretFreePayment);
        //获取机构待结算账户
//        PayAccount orgWaitSettle = payAccountService.getOrgChildren(projectOid, oid, PaymentChannelType.WaitSettle);
//        //支付：项目余额子账- 用户无感支付子账+
//        //构建转账参数
//        TransferTransactionsModel transferModel = new TransferTransactionsModel();
//        //构建出账账户
//        TransferTransactionsModel.GeneralLedgerTransaction sourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        sourceTransaction.setGeneralLedgerId(projectAccount.getLedgerId());
//        sourceTransaction.setOrderNumber(orderNo);
//        //TODO 修改交易类型为：无感支付-借贷
//        sourceTransaction.setTransactionType(TransactionType.Pay);
//        sourceTransaction.setTransactionStatus(TransactionStatus.Success);
//        sourceTransaction.setAmount(total.negate().longValue());
//        sourceTransaction.setRemark(remark);
//        sourceTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户支付"));
//        transferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{sourceTransaction});
//
//        //构建入账账户
//        TransferTransactionsModel.GeneralLedgerTransaction destinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        destinationTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
//        destinationTransaction.setOrderNumber(orderNo);
//        //TODO 修改交易类型为：无感支付-借贷
//        destinationTransaction.setTransactionType(TransactionType.Pay);
//        destinationTransaction.setTransactionStatus(TransactionStatus.Success);
//        destinationTransaction.setAmount(total.longValue());
//        destinationTransaction.setRemark(remark);
//        destinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户支付"));
//        transferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{destinationTransaction});
//        transactionLogService.transfer(transferModel);

        //支付：用户余额子账- 机构无感支付子账+
        //构建转账参数
        TransferTransactionsModel payTransferModel = new TransferTransactionsModel();
        //构建出账账户
        TransferTransactionsModel.GeneralLedgerTransaction userSourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
        userSourceTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
        userSourceTransaction.setOrderNumber(orderNo);
        userSourceTransaction.setTransactionType(TransactionType.Pay);
        userSourceTransaction.setTransactionStatus(TransactionStatus.Success);
        userSourceTransaction.setAmount(total.negate().longValue());
        userSourceTransaction.setRemark(remark);
        userSourceTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户支付"));
        payTransferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{userSourceTransaction});

        List<ShareOrder> shareOrderList = shareOrderDao.findByOrderNoAndProjectOidAndShareOrderType(orderNo, projectOid, ShareOrderType.Pay);

        List<TransferTransactionsModel.GeneralLedgerTransaction> orgDestinationTransactions = shareOrderList.stream().map(shareOrder -> {
            //获取机构待结算账户
            PayAccount orgWaitSettle = payAccountService.getOrgChildren(projectOid, shareOrder.getOid(), PaymentChannelType.WaitSettle);
            TransferTransactionsModel.GeneralLedgerTransaction orgDestinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
            orgDestinationTransaction.setGeneralLedgerId(orgWaitSettle.getLedgerId());
            orgDestinationTransaction.setOrderNumber(orderNo);
            orgDestinationTransaction.setTransactionType(TransactionType.Pay);
            orgDestinationTransaction.setTransactionStatus(TransactionStatus.Success);
            orgDestinationTransaction.setAmount(shareOrder.getAmount());
            orgDestinationTransaction.setRemark(remark);
            orgDestinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户支付"));
            return orgDestinationTransaction;
        }).toList();

//        //构建入账账户
//        TransferTransactionsModel.GeneralLedgerTransaction orgDestinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        orgDestinationTransaction.setGeneralLedgerId(orgWaitSettle.getLedgerId());
//        orgDestinationTransaction.setOrderNumber(orderNo);
//        orgDestinationTransaction.setTransactionType(TransactionType.Pay);
//        orgDestinationTransaction.setTransactionStatus(TransactionStatus.Success);
//        orgDestinationTransaction.setAmount(total.longValue());
//        orgDestinationTransaction.setRemark(remark);
//        orgDestinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户支付"));
//        payTransferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{orgDestinationTransaction});
        payTransferModel.setDestinations(orgDestinationTransactions.toArray(new TransferTransactionsModel.GeneralLedgerTransaction[]{}));
        TransferTransactionsModels transactionsModels = new TransferTransactionsModels();
        transactionsModels.setItems(new TransferTransactionsModel[]{payTransferModel});
        return transactionLogService.transfers(transactionsModels);
    }

    public com.github.microservice.pay.client.ret.ResultContent<List<TransactionLogModel>> handleRefund(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String remark, RefundVaFld vaFld) {
        //TODO 判断支付状态

//        //获取项目总账
//        PayAccount projectAccount = payAccountService.getProjectChildren(projectOid, PaymentChannelType.SecretFreePayment);
        //获取用户无感支付子账户
        PayAccount userBalancePayment = payAccountService.getUserChildren(projectOid, userId, PaymentChannelType.SecretFreePayment);
        //获取机构待结算账户

//        //支付：项目余额子账+ 用户无感支付子账-
//        //构建转账参数
//        TransferTransactionsModel transferModel = new TransferTransactionsModel();
//        //构建出账账户
//        TransferTransactionsModel.GeneralLedgerTransaction sourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        sourceTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
//        sourceTransaction.setOrderNumber(orderNo);
//        //TODO 修改交易类型为：无感支付-借贷
//        sourceTransaction.setTransactionType(TransactionType.Refund);
//        sourceTransaction.setTransactionStatus(TransactionStatus.Success);
//        sourceTransaction.setAmount(total.negate().longValue());
//        sourceTransaction.setRemark(remark);
//        sourceTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户退款"));
//        transferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{sourceTransaction});
//
//        //构建入账账户
//        TransferTransactionsModel.GeneralLedgerTransaction destinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        destinationTransaction.setGeneralLedgerId(projectAccount.getLedgerId());
//        destinationTransaction.setOrderNumber(orderNo);
//        //TODO 修改交易类型为：无感支付-借贷
//        destinationTransaction.setTransactionType(TransactionType.Refund);
//        destinationTransaction.setTransactionStatus(TransactionStatus.Success);
//        destinationTransaction.setAmount(total.longValue());
//        destinationTransaction.setRemark(remark);
//        destinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "用户余额支付", "summary", "用户退款"));
//        transferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{destinationTransaction});
//        transactionLogService.transfer(transferModel);

        //支付：机构余额子账- 用户无感支付子账+
        //构建转账参数
        List<RefundVaFld.SatDetail> satDetailList = vaFld.getSatDetail();
        List<TransferTransactionsModel.GeneralLedgerTransaction> list = satDetailList.stream().map(satDetail -> {

            ShareOrder shareOrderNo = shareOrderDao.findTopByShareOrderNo(satDetail.getRefundMerOrderId());
            PayAccount orgWaitSettle = payAccountService.getOrgChildren(projectOid, shareOrderNo.getOid(), PaymentChannelType.WaitSettle);


            TransferTransactionsModel.GeneralLedgerTransaction orgDestinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
            orgDestinationTransaction.setGeneralLedgerId(orgWaitSettle.getLedgerId());
            orgDestinationTransaction.setOrderNumber(orderNo);
            orgDestinationTransaction.setTransactionType(TransactionType.Refund);
            orgDestinationTransaction.setTransactionStatus(TransactionStatus.Success);
            orgDestinationTransaction.setAmount(shareOrderNo.getAmount());
            orgDestinationTransaction.setRemark(remark);
            orgDestinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户退款"));
            return orgDestinationTransaction;
        }).toList();

        TransferTransactionsModel payTransferModel = new TransferTransactionsModel();
//        //构建出账账户
//        TransferTransactionsModel.GeneralLedgerTransaction orgDestinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
//        orgDestinationTransaction.setGeneralLedgerId(orgWaitSettle.getLedgerId());
//        orgDestinationTransaction.setOrderNumber(orderNo);
//        orgDestinationTransaction.setTransactionType(TransactionType.Refund);
//        orgDestinationTransaction.setTransactionStatus(TransactionStatus.Success);
//        orgDestinationTransaction.setAmount(total.negate().longValue());
//        orgDestinationTransaction.setRemark(remark);
//        orgDestinationTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户退款"));
//        payTransferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{orgDestinationTransaction});
        payTransferModel.setSource(list.toArray(new TransferTransactionsModel.GeneralLedgerTransaction[]{}));

        //构建入账账户
        TransferTransactionsModel.GeneralLedgerTransaction userSourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
        userSourceTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
        userSourceTransaction.setOrderNumber(orderNo);
        userSourceTransaction.setTransactionType(TransactionType.Refund);
        userSourceTransaction.setTransactionStatus(TransactionStatus.Success);
        userSourceTransaction.setAmount(total.longValue());
        userSourceTransaction.setRemark(remark);
        userSourceTransaction.setMeta(Map.of("paymentType", PaymentType.UnionFrictionlessPay, "description", "银联无感支付", "summary", "用户退款"));
        payTransferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{userSourceTransaction});
        TransferTransactionsModels transactionsModels = new TransferTransactionsModels();
        transactionsModels.setItems(new TransferTransactionsModel[]{payTransferModel});
        return transactionLogService.transfers(transactionsModels);
    }


    private ChinaumsSenselessUserSignInfoModel toUserSignModel(ChinaumsSenselessUserSignInfo userSignInfo) {
        ChinaumsSenselessUserSignInfoModel model = new ChinaumsSenselessUserSignInfoModel();
        if (userSignInfo != null) {
            BeanUtils.copyProperties(userSignInfo, model);
        }
        return model;
    }

    public void handleSignRetMessage(ChinaSenselessSignRet chinaSenselessSignRet) {
        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByContractNo(chinaSenselessSignRet.getContractNo());
        if (userSignInfo == null) {
            log.info("签约通知回调：找不到签约用户信息 contractNo:{}", chinaSenselessSignRet.getContractNo());
            return;
        }
        userSignInfo.setContractState(ContractState.valueOf(chinaSenselessSignRet.getContractState()));
        userSignInfo.setContractId(chinaSenselessSignRet.getContractId());
        userSignInfo.setContractSignedTime(chinaSenselessSignRet.getContractSignedTime());
        userSignInfo.setContractExpiredTime(chinaSenselessSignRet.getContractExpiredTime());
        userSignInfo.setAcpId(chinaSenselessSignRet.getAcpId());
        chinaumsSenselessUserSignInfoDao.save(userSignInfo);
    }
}
