package com.fs.his.service.impl;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.annotation.Log;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.company.mapper.CompanyConfigMapper;
import com.fs.company.param.FsStoreStatisticsParam;
import com.fs.company.vo.FsStorePaymentStatisticsVO;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.course.config.RedPacketConfig;
import com.fs.course.domain.FsCourseRedPacketLog;
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
import com.fs.course.service.IFsCourseRedPacketLogService;
import com.fs.course.service.IFsUserCourseOrderService;
import com.fs.course.service.IFsUserVipOrderService;
import com.fs.erp.dto.ErpRefundUpdateRequest;
import com.fs.his.domain.FsExportTask;
import com.fs.his.domain.FsPayConfig;
import com.fs.his.domain.FsStorePayment;
import com.fs.his.dto.PayConfigDTO;
import com.fs.his.mapper.FsExportTaskMapper;
import com.fs.his.mapper.FsStorePaymentMapper;
import com.fs.his.param.FsStoreOrderParam;
import com.fs.his.param.FsStorePaymentParam;
import com.fs.his.param.WxSendRedPacketParam;
import com.fs.his.service.IFsInquiryOrderService;
import com.fs.his.service.IFsPackageOrderService;
import com.fs.his.service.IFsStoreOrderService;
import com.fs.his.vo.FsStorePaymentExcelVO;
import com.fs.his.vo.FsStorePaymentVO;
import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBankPay.TzBankService.TzBankService;
import com.fs.tzBankPay.TzBankService.TzBankServiceImpl.TzBankServiceImpl;
import com.fs.tzBankPay.doman.QueryOrderResult;
import com.fs.tzBankPay.doman.RefundParam;
import com.fs.tzBankPay.doman.TzBankResult;
import com.fs.tzBankPay.doman.payQueryOrder;
import com.fs.ybPay.domain.OrderResult;
import com.fs.ybPay.dto.OrderQueryDTO;
import com.fs.ybPay.dto.RefundDTO;
import com.fs.ybPay.service.IPayService;
import com.github.binarywang.wxpay.bean.merchanttransfer.TransferCreateRequest;
import com.github.binarywang.wxpay.bean.merchanttransfer.TransferCreateResult;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.transfer.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MerchantTransferService;
import com.github.binarywang.wxpay.service.RedpackService;
import com.github.binarywang.wxpay.service.TransferService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.RedpackServiceImpl;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.gson.Gson;
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.fs.his.service.IFsStorePaymentService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;

/**
 * 支付明细Service业务层处理
 *
 * @author fs
 * @date 2023-08-11
 */
@Service
public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;
    @Autowired
    private TzBankService tzBankService;
    @Autowired
    private IFsInquiryOrderService inquiryOrderService;
    @Autowired
    private IFsStoreOrderService storeOrderService;
    @Autowired
    private IFsPackageOrderService packageOrderService;
    @Autowired
    private IPayService ybPayService;
    @Autowired
    private HuiFuService huiFuService;
    @Autowired
    private IFsUserCourseOrderService courseOrderService;
    @Autowired
    private IFsUserVipOrderService vipOrderService;
    @Autowired
    SysConfigMapper sysConfigMapper;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    FsExportTaskMapper fsExportTaskMapper;
    @Autowired
    private IFsCourseRedPacketLogService redPacketLogService;
    @Autowired
    private CompanyConfigMapper companyConfigMapper;
    /**
     * 查询支付明细
     *
     * @param paymentId 支付明细主键
     * @return 支付明细
     */
    @Override
    public FsStorePayment selectFsStorePaymentByPaymentId(Long paymentId) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
    }

    /**
     * 查询支付明细列表
     *
     * @param fsStorePayment 支付明细
     * @return 支付明细
     */
    @Override
    public List<FsStorePayment> selectFsStorePaymentList(FsStorePayment fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentList(fsStorePayment);
    }

    /**
     * 新增支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int insertFsStorePayment(FsStorePayment fsStorePayment) {
        fsStorePayment.setCreateTime(DateUtils.getNowDate());
        return fsStorePaymentMapper.insertFsStorePayment(fsStorePayment);
    }

    /**
     * 修改支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int updateFsStorePayment(FsStorePayment fsStorePayment) {
        return fsStorePaymentMapper.updateFsStorePayment(fsStorePayment);
    }

    /**
     * 批量删除支付明细
     *
     * @param paymentIds 需要删除的支付明细主键
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentByPaymentIds(Long[] paymentIds) {
        return fsStorePaymentMapper.deleteFsStorePaymentByPaymentIds(paymentIds);
    }

    /**
     * 删除支付明细信息
     *
     * @param paymentId 支付明细主键
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentByPaymentId(Long paymentId) {
        return fsStorePaymentMapper.deleteFsStorePaymentByPaymentId(paymentId);
    }

    @Override
    public List<FsStorePaymentVO> selectFsStorePaymentListVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentListVO(fsStorePayment);
    }

    @Override
    public FsStorePaymentVO selectFsStorePaymentByPaymentIdVO(Long paymentId) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentIdVO(paymentId);
    }

    @Override
    public List<FsStorePaymentStatisticsVO> selectFsStorePaymentStatisticsList(FsStoreStatisticsParam param) {
        return fsStorePaymentMapper.selectFsStorePaymentStatisticsList(param);
    }

    @Override
    public List<JSONObject> selectFsStorePaymentCounts(Map<String, Object> toMap) {
        return fsStorePaymentMapper.selectFsStorePaymentCounts(toMap);
    }

    @Override
    public Long selectFsStorePaymentCount(int type, Long companyId) {
        return fsStorePaymentMapper.selectFsStorePaymentCount(type, companyId);
    }

    @Override
    public List<FsStorePaymentExcelVO> selectFsStorePaymentExcelVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentExcelVO(fsStorePayment);
    }

    @Override
    public String updateFsStorePaymentByDecryptForm(Long paymentId) {
        FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
        logger.info("手动查询单号:" + paymentId + ":" + fsStorePayment);
        if (fsStorePayment.getPayMode().equals("tz")) {
            payQueryOrder payQueryOrder = new payQueryOrder();
            payQueryOrder.setOrderFlowNo(fsStorePayment.getTradeNo());
            TzBankResult<QueryOrderResult> result = tzBankService.queryOrder(payQueryOrder);
            logger.info("手动查询内容:" + paymentId + ":" + result);
            if (result.getRetType().equals("S") && result.getBody().getStatus().equals("90")) {
                QueryOrderResult body = result.getBody();
                logger.info("手动回调内容:" + body);
                if (fsStorePayment.getBusinessType() == 1) {
                    inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1);
                } else if (fsStorePayment.getBusinessType() == 2) {
                    storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1);
                } else if (fsStorePayment.getBusinessType() == 3) {
                    packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1);
                }else if (fsStorePayment.getBusinessType() == 4) {
                    courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                }else if (fsStorePayment.getBusinessType() == 5) {
                    vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                }
            }
        }
        if (fsStorePayment.getPayMode().equals("yb")) {
            OrderQueryDTO o = new OrderQueryDTO();
            o.setUpOrderId(fsStorePayment.getTradeNo());
            OrderResult orderResult = ybPayService.getOrder(o);

            if ("0".equals(orderResult.getState())) {
                if (orderResult.getStatus().equals("100")) {
                    logger.info("手动查询内容:" + paymentId + ":" + orderResult);
                    if (orderResult.getStatus().equals("100")) {
                        if (fsStorePayment.getBusinessType() == 1) {
                            inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        } else if (fsStorePayment.getBusinessType() == 2) {
                            storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        } else if (fsStorePayment.getBusinessType() == 3) {
                            packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        }else if (fsStorePayment.getBusinessType() == 4) {
                            courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                        }else if (fsStorePayment.getBusinessType() == 5) {
                            vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                        }
                    }
                }
            }
        }
        if (fsStorePayment.getPayMode().equals("hf")) {
            V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
            request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(fsStorePayment.getCreateTime()));
            request.setOrgHfSeqId(fsStorePayment.getTradeNo());
            HuiFuQueryOrderResult queryOrderResult = null;
            try {
                queryOrderResult = huiFuService.queryOrder(request);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            logger.info("汇付返回"+queryOrderResult);
            if ("00000000".equals(queryOrderResult.getResp_code())) {
                if (queryOrderResult.getTrans_stat().equals("S")) {
                    logger.info("手动查询内容:" + paymentId + ":" + request);
                        if (fsStorePayment.getBusinessType() == 1) {
                            inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        } else if (fsStorePayment.getBusinessType() == 2) {
                            storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        } else if (fsStorePayment.getBusinessType() == 3) {
                            packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1);
                        }  else if (fsStorePayment.getBusinessType() == 4) {
                            courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                        }else if (fsStorePayment.getBusinessType() == 5) {
                            vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1);
                        }

                }
            }
        }
        return "同步完成";
}
    @Autowired
    IPayService payService;
    @Override
    public R refundFsStorePayment(Long paymentId) {
        FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
        if(fsStorePayment!=null){
            String orderType="";
            if (fsStorePayment.getBusinessType()==1){
                orderType="inquiry";
            }else if (fsStorePayment.getBusinessType()==2){
                orderType="store";
            }else if (fsStorePayment.getBusinessType()==3){
                orderType="package";
            }else if (fsStorePayment.getBusinessType()==4){
                orderType="course";
            }else if (fsStorePayment.getBusinessType()==5){
                orderType="appvip";
            }

            if(fsStorePayment.getPayMode().equals("wx")){
                WxPayConfig payConfig = new WxPayConfig();
                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setKeyPath(wxPayProperties.getKeyPath());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                wxPayService.setConfig(payConfig);
                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
                refundRequest.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
                refundRequest.setOutRefundNo(orderType+"-"+fsStorePayment.getPayCode());
                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
                try {
                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
                    if(refundQueryResult!=null&&refundQueryResult.getResultCode().equals("SUCCESS")){
                        FsStorePayment paymentMap=new FsStorePayment();
                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                        paymentMap.setStatus(-1);
                        paymentMap.setRefundTime(DateUtils.getNowDate());
                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    }
                    else {
                        throw new CustomException("退款请求失败"+refundQueryResult.getReturnMsg());
                    }
                } catch (WxPayException e) {
                    throw new CustomException("退款请求失败"+e.getReturnMsg());
                }
            }
            else if(fsStorePayment.getPayMode().equals("yb")){
                //易宝
                RefundDTO refundDTO=new RefundDTO();
                refundDTO.setRefundMoney(fsStorePayment.getPayMoney().toString());
                refundDTO.setLowRefundNo(orderType+"-"+fsStorePayment.getPayCode());
                refundDTO.setUpOrderId(fsStorePayment.getTradeNo());
                com.fs.ybPay.domain.RefundResult result=payService.refund(refundDTO);
                logger.info("订单退款返回结果:退款订单id:"+paymentId+result);
                if(result.getState().equals("5")){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                }else {
                    throw new CustomException("退款请求失败"+result.getMessage());
                }
            } else if(fsStorePayment.getPayMode().equals("tz")){
                RefundParam tzBankResult = new RefundParam();
                // 使用set方法为对象的字段赋值
                //商户原支付订单号
                tzBankResult.setOldPayOutOrderNo(orderType+fsStorePayment.getPayCode());
                // 商户退款订单号 对接平台系统里自己生成的退款订单号
                tzBankResult.setRefundOrderNo(orderType+fsStorePayment.getPayCode());
                // 交易发送时间 yyyyMMddHHmmss
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                tzBankResult.setTrxSendTime(sdf.format(new Date()));
                // 退款金额
                tzBankResult.setRefundOrdTransAmt(fsStorePayment.getPayMoney().doubleValue());
                TzBankResult<com.fs.tzBankPay.doman.RefundResult> result = tzBankService.refund(tzBankResult);
                logger.info("订单退款返回结果:退款订单id:"+paymentId+result);
                if(result.getBody().getRefundOrdStatus().equals("90")||result.getBody().getRefundOrdStatus().equals("60")){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                }else {
                    throw new CustomException("退款请求失败"+result.getRetMsg());
                }
            }
            else if(fsStorePayment.getPayMode().equals("hf")){
                V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                request.setOrdAmt(fsStorePayment.getPayMoney().toString());
                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(fsStorePayment.getCreateTime()));
                request.setReqSeqId("refund-"+fsStorePayment.getPayCode());
                Map<String, Object> extendInfoMap = new HashMap<>();
                extendInfoMap.put("org_req_seq_id", orderType+"-"+fsStorePayment.getPayCode());
                request.setExtendInfo(extendInfoMap);
                HuiFuRefundResult refund = huiFuService.refund(request);
                logger.info("订单退款返回结果:"+paymentId+""+refund);
                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                }else {
                    throw new CustomException("退款请求失败"+refund.getResp_desc());
                }
            }
        }
        return R.ok();
    }

    @Override
    public FsStorePayment selectFsStorePaymentByPaymentCode(String payCode) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
    }


    @Override
    @Transactional
    public R sendRedPacket(WxSendRedPacketParam param) {

        String json;
        RedPacketConfig config = new RedPacketConfig();
        // 根据红包模式获取配置
        switch (param.getRedPacketMode()){
            case 1:
                json = configService.selectConfigByKey("redPacket.config");
                config = JSONUtil.toBean(json, RedPacketConfig.class);
                break;
            case 2:
                json = companyConfigMapper.selectRedPacketConfigByKey(param.getCompanyId());
                config = JSONUtil.toBean(json, RedPacketConfig.class);
                break;
        }
        //组合返回参数
        R result = new R();
        // 根据 isNew 判断使用哪种发红包方式
        if (config.getIsNew() != null && config.getIsNew() == 1) {
            result = sendRedPacketV3Internal(param, config);
        } else {
            result= sendRedPacketLegacyInternal(param, config);
        }
        result.put("isNew",config.getIsNew());
        return result;
    }

    // 内部方法：处理新版本的发红包逻辑
    private R sendRedPacketV3Internal(WxSendRedPacketParam param, RedPacketConfig config) {
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config, payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBillsRequest request = new TransferBillsRequest();
        request.setAppid(config.getAppId());
        request.setOpenid(param.getOpenId());

        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBillNo("fsCourse" + code);

        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount() != null ? param.getAmount().toString() : "0.1");
        request.setTransferAmount(amount);
        request.setTransferRemark("活动奖励");
        request.setUserRecvPerception("活动奖励");
        request.setNotifyUrl(config.getNotifyUrl());
        request.setTransferSceneId("1000");

        // 设置场景信息
        List<TransferBillsRequest.TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<>();
        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
        info1.setInfoType("活动名称");
        info1.setInfoContent("新会员有礼");
        transferSceneReportInfos.add(info1);

        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
        info2.setInfoType("奖励说明");
        info2.setInfoContent("注册会员抽奖一等奖");
        transferSceneReportInfos.add(info2);
        request.setTransferSceneReportInfos(transferSceneReportInfos);

        try {
            TransferBillsResult transferBillsResult = transferService.transferBills(request);
            logger.info("商家转账支付完成:[msg:{}]", transferBillsResult);
            return R.ok("发送红包成功").put("data", transferBillsResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.info("商家转账支付失败：[msg:{}]", e.getMessage());
            return R.error("发送失败");
        }
    }

    // 内部方法：处理旧版本的发红包逻辑
    private R sendRedPacketLegacyInternal(WxSendRedPacketParam param, RedPacketConfig config) {
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config, payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBatchesRequest request = new TransferBatchesRequest();
        request.setAppid(config.getAppId());
        String code = IdUtil.getSnowflake(0, 0).nextIdStr();
        request.setOutBatchNo("fsCourse" + code);
        request.setBatchRemark("课堂答题奖励");
        request.setBatchName("课堂答题奖励");
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount().toString());
        request.setTotalAmount(amount);
        request.setTotalNum(1);
        request.setNotifyUrl(config.getNotifyUrl());

        ArrayList<TransferBatchesRequest.TransferDetail> transferDetailList = new ArrayList<>();
        TransferBatchesRequest.TransferDetail transferDetail = new TransferBatchesRequest.TransferDetail();
        transferDetail.setOpenid(param.getOpenId());
        String code1 = IdUtil.getSnowflake(0, 0).nextIdStr();
        transferDetail.setOutDetailNo("fsCourse" + code1);
        transferDetail.setTransferAmount(amount);
        transferDetail.setTransferRemark("恭喜同学，认真听课，奖励你一朵小红花!");
        transferDetailList.add(transferDetail);
        request.setTransferDetailList(transferDetailList);

        try {
            TransferBatchesResult transferBatchesResult = transferService.transferBatches(request);
            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo());
        } catch (WxPayException e) {
            e.printStackTrace();
            return R.error("发送失败");
        }
    }


    @Override
    public String transferNotify(String notifyData, HttpServletRequest request) {
        logger.info("zyp \n【收到转账回调】：{}",notifyData);
        try {
            String json = configService.selectConfigByKey("redPacket.config");
            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
            //创建微信订单
            WxPayConfig payConfig = new WxPayConfig();
            BeanUtils.copyProperties(config,payConfig);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            SignatureHeader signatureHeader = new SignatureHeader();
            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
            WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
            logger.info("到零钱回调：{}",result.getResult());
            if (result.getResult().getBatchStatus().equals("FINISHED")) {
                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo());
                logger.info("result:{}",r);
                if (r.get("code").equals(200)){
                    return WxPayNotifyResponse.success("处理成功");
                }else {
                    return WxPayNotifyResponse.fail("");
                }
            }else {
                return WxPayNotifyResponse.fail("");
            }
        } catch (WxPayException e) {
            logger.error("zyp \n【转账回调异常】：{}", e.getReturnMsg());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    @Override
    public Boolean isEntityNull(FsStorePaymentParam param) {
        if (param == null) {
            return true; // 整个实体对象为null
        }

        Class<? extends FsStorePaymentParam> entityClass = param.getClass();
        Field[] fields = entityClass.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(param);
                if (value != null) {
                    return false; // 实体对象中有字段不为null
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return true; // 实体对象内所有字段为null
    }

    @Override
    public Long selectFsStorePaymentExcelVOCount(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentExcelVOCount(fsStorePayment);
    }


    @Override
    public R sendRedPacketV3(WxSendRedPacketParam param) {
        String json = configService.selectConfigByKey("redPacket.config");
        RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);

        //创建微信订单
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config,payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        //商家转账请求
        TransferBillsRequest request = new TransferBillsRequest();
        request.setAppid(config.getAppId());
        request.setOpenid(param.getOpenId());

//        String code =  OrderCodeUtils.getH5RedPacketOrderSn();
//        if(StringUtils.isEmpty(code)){
//            return R.error("订单生成失败，请重试");
//        }
        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBillNo("fsCourse"+code);
        //转账金额
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount()!=null ? param.getAmount().toString() : "0.1");
        request.setTransferAmount(amount);
        request.setTransferRemark("活动奖励");
        //用户感知
        request.setUserRecvPerception("活动奖励");
        request.setNotifyUrl(config.getNotifyUrl());
        request.setTransferSceneId("1000");
        List<TransferBillsRequest.TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<>();
        // 添加第一条数据
        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
        info1.setInfoType("活动名称");
        info1.setInfoContent("新会员有礼");
        transferSceneReportInfos.add(info1);

        // 添加第二条数据
        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
        info2.setInfoType("奖励说明");
        info2.setInfoContent("注册会员抽奖一等奖");
        transferSceneReportInfos.add(info2);
        request.setTransferSceneReportInfos(transferSceneReportInfos);

        //发起商家转账API(新)
        TransferBillsResult transferBillsResult=null;
        try {
            transferBillsResult = transferService.transferBills(request);
            logger.info("商家转账支付完成:[msg:{}]",transferBillsResult);
            return R.ok("发送红包成功").put("data",transferBillsResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.info("商家转账支付失败：[msg:{}]",e.getMessage());
            return R.error("发送失败");
        }
    }


    @Override
    public String v3TransferNotify(String notifyData, HttpServletRequest request) {
        logger.info("zyp \n【收到转账回调】：{}",notifyData);
        try {
            String json = configService.selectConfigByKey("redPacket.config");
            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
            //创建微信订单
            WxPayConfig payConfig = new WxPayConfig();
            BeanUtils.copyProperties(config,payConfig);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            SignatureHeader signatureHeader = new SignatureHeader();
            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
            TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
            logger.info("到零钱回调：{}",result.getResult());
            if (result.getResult().getState().equals("SUCCESS")) {
                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo());
                logger.info("result:{}",r);
                if (r.get("code").equals(200)){
                    return WxPayNotifyResponse.success("处理成功");
                }else {
                    return WxPayNotifyResponse.fail("");
                }
            }else {
                return WxPayNotifyResponse.fail("");
            }
        } catch (WxPayException e) {
            logger.error("zyp \n【转账回调异常】：{}", e.getReturnMsg());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    @Override
    @Transactional
    public R sendRedPacketTest(WxSendRedPacketParam param) {

        String json = configService.selectConfigByKey("redPacket.config");
        RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
        //创建微信订单
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config,payConfig);
        payConfig.setAppId("wxc3f0a952b7bc2b94");
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBatchesRequest request = new TransferBatchesRequest();

//        request.setAppid(config.getAppId());
        request.setAppid("wxc3f0a952b7bc2b94");
//        String code =  OrderCodeUtils.getOrderSn();
//        if(StringUtils.isEmpty(code)){
//            return R.error("订单生成失败，请重试");
//        }
        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBatchNo("fsCourse"+code);
        request.setBatchRemark("课堂答题奖励");
        request.setBatchName("课堂答题奖励");
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount()!=null ? param.getAmount().toString() : "0.1");
        request.setTotalAmount(amount);
        request.setTotalNum(1);
        request.setNotifyUrl(config.getNotifyUrl());
        ArrayList<TransferBatchesRequest.TransferDetail> transferDetailList = new ArrayList<>();
        TransferBatchesRequest.TransferDetail transferDetail = new TransferBatchesRequest.TransferDetail();
        transferDetail.setOpenid(param.getOpenId());
        String code1 =  String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        transferDetail.setOutDetailNo("fsCourse"+code1);
        transferDetail.setTransferAmount(amount);
        transferDetail.setTransferRemark("恭喜同学，认真听课，奖励你一朵小红花!");
        transferDetailList.add(transferDetail);
        request.setTransferDetailList(transferDetailList);
        TransferBatchesResult transferBatchesResult=null;
        try {
            transferBatchesResult = transferService.transferBatches(request);
            logger.info("商家转账支付完成:[msg:{}]",transferBatchesResult);
            return R.ok("发送红包成功").put("orderCode",transferBatchesResult.getOutBatchNo());
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.info("商家转账支付失败：[msg:{}]",e.getMessage());
            return R.error("发送失败");
        }
    }
}
