package com.thinkgem.jeesite.modules.pay.service;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.thinkgem.jeesite.common.baseBean.Request;
import com.thinkgem.jeesite.common.baseBean.Response;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.constant.ComCode;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.modules.commonError.MyException;
import com.thinkgem.jeesite.modules.pay.alipay.service.AlipayService;
import com.thinkgem.jeesite.modules.pay.dao.PayApiDao;
import com.thinkgem.jeesite.modules.pay.entity.BenefitEntity;
import com.thinkgem.jeesite.modules.pay.entity.OrderEntity;
import com.thinkgem.jeesite.modules.pay.entity.RateEntity;
import com.thinkgem.jeesite.modules.pay.entity.UserRateEntity;
import com.thinkgem.jeesite.modules.pay.huanqiuhuiju.service.HuanqiuhuijuService;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.ApiQuickPayDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.MerchantDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.PayBackDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.QuickDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayIntegralService;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayJFenService;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayService;
import com.thinkgem.jeesite.modules.pay.juhezhong.utils.MakeOrderNum;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.user.bean.JuHeZhongPayRequest;
import com.thinkgem.jeesite.modules.user.bean.UserRequest;
import com.thinkgem.jeesite.modules.user.entity.*;
import com.thinkgem.jeesite.modules.user.service.UserApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 支付相关
 */

@Service
@Lazy(false)
@Transactional(readOnly = true)
public class PayApiService {
    @Autowired
    private PayApiDao payDao;
    @Autowired
    private UserApiService userService;
    @Autowired
    private JuHeZhongPayService juHeZhongPayService;

    @Autowired
    private JuHeZhongPayIntegralService juHeZhongPayIntegralService;

    @Autowired
    private JuHeZhongPayJFenService juHeZhongPayJFenService;

    @Autowired
    private HuanqiuhuijuService huanqiuhuijuService;

    @Autowired
    private AlipayService alipayService;

    @Transactional(readOnly = false)
    public PayBackDto quickPay(JuHeZhongPayRequest request) throws MyException, Exception {
        if(ComCode.PAYCHANNEL_HL2.equals(request.getPayChannel())){
            PayBackDto payBackDto = this.jFenPayJuhezhong(request);
            payBackDto.setIsUrl("0");
            return payBackDto;
        }

        // 1. 根据入参获取用户详情信息，包括支付卡片信息
        UserEntity userEntity = userService.getUserInfo(new Request(request.getSubMerchantCode()));
        userEntity = userService.getUserDetailInfo(userEntity);
        UserRequest userRequest = new UserRequest();
        userRequest.setSubMerchantCode(request.getSubMerchantCode());

        CardEntity cardEntity = userService.getDebitCardByUserCode(userRequest);
        userEntity.getUserDetail().setCard(cardEntity);
        // 2. 创建支付订单信息，并保存
        String code = IdGen.randomBase62(64);
        String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
        String payCode = IdGen.randomBase62(64);
        DecimalFormat df = new DecimalFormat("######0.00");
        String amount = df.format(Double.valueOf(request.getAmount()));
        // 4. JuHeZhong支付
        PayBackDto payBackDto = new PayBackDto();
        if(ComCode.PAYCHANNEL_HL1.equals(request.getPayChannel())){
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,"quick", request.getPayChannel(), "1",amount , request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            payDao.saveOrderInfo(orderEntity);
            // 3. 创建分润信息，并保存
            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
            for (String key : userBenefits.keySet()) {
                String benefitCode = IdGen.randomBase62(64);
                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
                benefitEntity.setPayMethod(orderEntity.getPayMethod());
                payDao.saveBenefitInfo(benefitEntity);
            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            payBackDto = quickPayJuHeZhongPay(userEntity, orderEntity, request,cardEntityPay);
        }else if(ComCode.PAYCHANNEL_HL3.equals(request.getPayChannel())){
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,"quick", request.getPayChannel(), "1",amount , request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            payDao.saveOrderInfo(orderEntity);
            // 3. 创建分润信息，并保存
            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
            for (String key : userBenefits.keySet()) {
                String benefitCode = IdGen.randomBase62(64);
                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
                benefitEntity.setPayMethod(orderEntity.getPayMethod());
                payDao.saveBenefitInfo(benefitEntity);
            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            if(!"C".equals(cardEntityPay.getCardType())){
                payBackDto.setMessage("只能用信用卡支付");
            }else if(cardEntityPay.getSupportPayChannel()==null || !cardEntityPay.getSupportPayChannel().contains(request.getPayChannel())){
                payBackDto.setMessage("不支持"+cardEntityPay.getBankName());
            }else{
                payBackDto = this.quickPayJuHeZhongIntegralPay(userEntity, orderEntity, request,cardEntityPay);
            }

        }else if(ComCode.PAYCHANNEL_HUANQIUHUIJU.equals(request.getPayChannel())){
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,"quick", request.getPayChannel(), "1",amount , request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            payDao.saveOrderInfo(orderEntity);
            // 3. 创建分润信息，并保存
            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
            for (String key : userBenefits.keySet()) {
                String benefitCode = IdGen.randomBase62(64);
                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
                benefitEntity.setPayMethod(orderEntity.getPayMethod());
                payDao.saveBenefitInfo(benefitEntity);
            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);

            payBackDto = this.huanqiuhujuPay(userEntity, orderEntity, request,cardEntityPay);
        }else {
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,"quick", ComCode.PAYCHANNEL_HL3, "1",amount , request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            payDao.saveOrderInfo(orderEntity);
            // 3. 创建分润信息，并保存
            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
            for (String key : userBenefits.keySet()) {
                String benefitCode = IdGen.randomBase62(64);
                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
                benefitEntity.setPayMethod(orderEntity.getPayMethod());
                payDao.saveBenefitInfo(benefitEntity);
            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            if(!"C".equals(cardEntityPay.getCardType())){
                payBackDto.setMessage("只能用信用卡支付");
            }else if(cardEntityPay.getSupportPayChannel()==null || !cardEntityPay.getSupportPayChannel().contains("ComCode.PAYCHANNEL_HL3,")){
                payBackDto.setMessage("不支持"+cardEntityPay.getBankName());
            }else{
                payBackDto = this.quickPayJuHeZhongIntegralPay(userEntity, orderEntity, request,cardEntityPay);
            }
        }


        return payBackDto;
    }



    /*
     * 以下为类内使用方法
     */

    /**
     * JuHeZhong 无积分快捷支付
     *
     * @param userEntity
     * @param request
     * @throws Exception
     */
    public PayBackDto quickPayJuHeZhongPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request,CardEntity cardEntity) throws Exception {
        // 快捷支付
//        ApiQuickPayDto quickPayDto = new ApiQuickPayDto();
//        quickPayDto.setMerchantId(ComCode.MERCHANT_ID);
//        quickPayDto.setOrderId(orderEntity.getPayCode()); // 将订单的支付号传给第三方平台
//        quickPayDto.setSubMchId(userEntity.getUserDetail().getCard().getSubMerchantId());//子商户号
//        quickPayDto.setAmount(Long.parseLong(request.getAmount()));
//        quickPayDto.setBody(request.getSubject());
//        quickPayDto.setType("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0));
//        quickPayDto.setAccName(userEntity.getUserDetail().getRealName());
//        quickPayDto.setAccNo(userEntity.getUserDetail().getCard().getCardNo());
//        quickPayDto.setMobile(userEntity.getUserDetail().getCard().getCardMobile());
//        quickPayDto.setIdNo(userEntity.getUserDetail().getIdCard());
//
//
//        quickPayDto.setAccName("聂换换");
//        quickPayDto.setAccNo("6217000180000770507");
//        quickPayDto.setMobile("13722537737");
//        quickPayDto.setIdNo("130434199212214429");
//        quickPayDto.setFrontUrl("");// 前台地址
//        quickPayDto.setNotifyUrl("");// 通知url
//        quickPayDto.setTimestamp(System.currentTimeMillis());
//        quickPayDto.setMerchantKey(ComCode.MERCHANT_KEY);


        QuickDto quickDto = new QuickDto();
        quickDto.setTrxType(3);
        quickDto.setMerchantId(ComCode.MERCHANT_ID);
        quickDto.setOrderId(orderEntity.getPayCode()); // 将订单的支付号传给第三方平台
        quickDto.setAmount(Long.parseLong(request.getAmount())*100);

        // 获取支付卡号
        quickDto.setBankNo(cardEntity.getCardNo()); // 支付卡号

        quickDto.setSettleBankName(userEntity.getUserDetail().getCard().getBelongBank());
        quickDto.setSettleBankNo(userEntity.getUserDetail().getCard().getCardNo());
        quickDto.setSettleBankPhone(userEntity.getUserDetail().getCard().getCardMobile());
        quickDto.setName(userEntity.getUserDetail().getRealName());
        quickDto.setCertificateCode(userEntity.getUserDetail().getIdCard());

        quickDto.setType("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0));

        RateEntity rateEntity = new RateEntity();
        rateEntity.setUserLevel(userEntity.getLevel());
        rateEntity.setPayMethod("quick");
        rateEntity.setPayChannel(ComCode.PAYCHANNEL_HL1);
        rateEntity = userService.getRateByLevel(rateEntity);
        if(rateEntity!=null){
            double userFee = Long.parseLong(request.getAmount())*100*Double.valueOf(rateEntity.getRate());
            if(userFee<100){
                userFee = 100;
            }
            BigDecimal bigDecimal = new BigDecimal(100+ Double.valueOf(Global.getConfig("pay.y"))*100 );
            quickDto.setUserFee(bigDecimal); // 手续费 单位：分 ，D0 业务必传

        }else{
            quickDto.setUserFee(new BigDecimal(0));
        }
        quickDto.setFrontUrl(Global.getConfig("project.access.url")+"/api/pay/notifyPay");// 前台地址
        quickDto.setNotifyUrl(Global.getConfig("project.access.url")+"/api/pay/notifyPay");// 通知url
        quickDto.setTimestamp(System.currentTimeMillis());
        quickDto.setMerchantKey(ComCode.MERCHANT_KEY);
        JSONObject jsonObject = juHeZhongPayService.quickPay(quickDto);
        System.out.println(jsonObject.toString());
        PayBackDto payBackDto = new PayBackDto();
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));

        }else{
            payBackDto.setUrl(jsonObject.getString("url"));
        }
        return payBackDto;
    }




    /**
     * JuHeZhong积分快捷支付
     *
     * @param userEntity
     * @param request
     * @throws Exception
     */
    public PayBackDto quickPayJuHeZhongIntegralPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request,CardEntity cardEntity) throws Exception {
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL3);
        userSubMchId.setUserCode(userEntity.getCode());
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        String subMchId = null;
        if(userSubMchId==null){
            UserRequest userRequest = new UserRequest();
            userRequest.setSubMerchantCode(request.getSubMerchantCode());
            userRequest.setBelongBank(userEntity.getUserDetail().getCard().getBelongBank());
            userRequest.setRealName(userEntity.getUserDetail().getRealName());
            userRequest.setCardNo(userEntity.getUserDetail().getCard().getCardNo());
            userRequest.setMobile(userEntity.getMobile());
            userRequest.setIdCard(userEntity.getUserDetail().getIdCard());
            userRequest.setCardPlace(userEntity.getUserDetail().getCard().getCardPlace());
            subMchId = userService.quickPayHandleJuhezhong(userRequest,"",userEntity.getLevel());
            userSubMchId = new UserSubMchId();
            userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL3);
            userSubMchId.setUserCode(userEntity.getCode());
            userSubMchId.setSubmchid(subMchId);
            userService.addUserSubmchid(userSubMchId);
        }else{
            subMchId = userSubMchId.getSubmchid();
        }
        JSONObject dto = new JSONObject();

        dto.put("serviceType", 4);// 服务类型
        dto.put("orderId", orderEntity.getPayCode());//订单号
        dto.put("amount", Long.parseLong(request.getAmount())*100);//交易金额
        dto.put("merchantId",ComCode.INTEGRAL_MERCHANT_ID);//商户号
//        dto.put("subMchId", userEntity.getUserDetail().getCard().getSubMerchantId());//由系统分配的商户号
        dto.put("subMchId",subMchId);
        dto.put("accNo", cardEntity.getCardNo());//开卡 唯一标识
//        dto.put("accNo", "6210210010501799229");//开卡 唯一标识
        dto.put("mobile",cardEntity.getCardMobile());

        dto.put("productName", "收款");//标题
        dto.put("notifyUrl", Global.getConfig("project.access.url")+"/api/pay/notifyPay");//支付完成  异步通知结果
        dto.put("frontUrl", Global.getConfig("project.access.url")+"/api/pay/notifyPay");//返回商户页面
        dto.put("merchantKey", ComCode.INTEGRAL_MERCHANT_KEY);//商户key
        dto.put("timestamp", System.currentTimeMillis());//时间戳
        System.out.println(dto.toJSONString());
        JSONObject jsonObject = juHeZhongPayIntegralService.quickPayHandle(dto);

        System.out.println(jsonObject.toString());
        PayBackDto payBackDto = new PayBackDto();
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));

        }else{
            payBackDto.setUrl(jsonObject.getString("url"));
        }
        return payBackDto;
    }
    public Map<String, String> getUserBenefit(UserEntity userEntity, JuHeZhongPayRequest request) {
        Map<String, String> userBenefit = new HashMap<>();
        String[] pathIds = (userEntity.getRecommendedPath() + userEntity.getId() + ",").split(",");
        // 获取三级的会员
        List<UserRateEntity> pathCDEUsers = payDao.getCDEUsers(pathIds);
        int countLevelC = 0;
        // 判断上级有几个黄金会员（C）
        for (UserRateEntity entity : pathCDEUsers) {
            // 不考虑该用户本身
            if (entity.getUserCode().equals(userEntity.getCode())) {
                continue;
            }
            if ("C".equals(entity.getUserLevel())) {
                countLevelC++;
            }
        }
        double minRate = 1;
        int levelCPosition = 0;
        for (UserRateEntity entity : pathCDEUsers) {
            levelCPosition++;
            minRate = minRate >= Double.parseDouble(entity.getRate()) ? Double.parseDouble(entity.getRate()) : minRate;
            if (entity.getUserCode().equals(userEntity.getCode())) {
                continue;
            }
            // 只有黄金会员（C）以上才分润
            if ("C".equals(entity.getUserLevel())) {
                double percent = countLevelC == 1 ? 1d : (levelCPosition == 2 ? 0.95 : 0.05);
                userBenefit.put(entity.getUserCode(), String.valueOf((minRate - Double.parseDouble(entity.getRate())) > 0 ? (minRate - Double.parseDouble(entity.getRate())) * Double.parseDouble(request.getAmount()) * percent : "0"));
            }
        }
        // 获取顶级管理员
        List<UserRateEntity> pathSABUsers = payDao.getSABUsers(pathIds,request.getPayChannel());
        for (UserRateEntity entity : pathSABUsers) {
            userBenefit.put(entity.getUserCode(), String.valueOf((minRate - Double.parseDouble(entity.getRate())) * Double.parseDouble(request.getAmount())));
            minRate = Double.valueOf(entity.getRate());
        }
        return userBenefit;
    }


    /**
     * HL2 通道 即JFEN 开卡 需要得参数
     * @param request
     * @return
     */
    public Response openCardJFen(UserRequest request){
        Response response = new Response();

        CardEntity cardEntity = userService.getCardInfo(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        UserEntity userEntity = userService.getUserInfo(request);
        UserDetailEntity userDetailEntity = userService.getUserDetailByCode(request.getSubMerchantCode());

        // 如果没有注册 则先注册
        if(userSubMchId == null){
            CardEntity cardEntityDebit = userService.getCardInfoByCode(userEntity);
            JSONObject dto = new JSONObject();

            String orderId = MakeOrderNum.makeOrderNum();

            dto.put("orderId", MakeOrderNum.makeOrderNum());
//
            dto.put("serviceType",1);
            dto.put("subMerchantName",userDetailEntity.getRealName()+System.currentTimeMillis());
            dto.put("subMerchantType","PERSON");
            dto.put("businessLicense",userDetailEntity.getRealName()+System.currentTimeMillis());
            dto.put("legalPersonName",userDetailEntity.getRealName());

            dto.put("legalPersonID",userDetailEntity.getIdCard());
            dto.put("subMerchantPersonName",userDetailEntity.getRealName());
            dto.put("subMerchantPersonPhone",cardEntityDebit.getCardMobile());
            dto.put("bankType","TOPRIVATE");

            dto.put("accountName",userDetailEntity.getRealName());
            dto.put("accountNo",cardEntityDebit.getCardNo());
            dto.put("bankName",cardEntityDebit.getBankName());
            dto.put("bankProv","天津市");
            dto.put("bankCity","天津市");
            dto.put("bankBranch","天津市职场");

//            dto.put("bankProv",cardEntityDebit.getCity());
//            dto.put("bankCity",cardEntityDebit.getCity());
//            dto.put("bankBranch",cardEntityDebit.getCardPlace());
            dto.put("bankCode",cardEntityDebit.getBelongBank());

            dto.put("timestamp",System.currentTimeMillis());
//            dto.put("legalPersonID",userDetailEntity.getIdCard());
//            dto.put("subMerchantPersonName",userDetailEntity.getRealName());
//            dto.put("subMerchantPersonPhone",cardEntityDebit.getCardMobile());
//            dto.put("bankType","TOPRIVATE");
//
//            dto.put("accountName",userDetailEntity.getRealName());
//            dto.put("accountNo",cardEntityDebit.getCardNo());
//            dto.put("bankName",cardEntityDebit.getBankName());
//            dto.put("bankProv",cardEntityDebit.getProvince());
//            dto.put("bankCity",cardEntityDebit.getCity());
//            dto.put("bankBranch",cardEntityDebit.getCardPlace());
//            dto.put("bankCode",cardEntityDebit.getBelongBank());
//
//            dto.put("timestamp",System.currentTimeMillis());


//            dto.put("legalPersonID","130434199212214429");
//            dto.put("subMerchantPersonName","聂换换");
//            dto.put("subMerchantPersonPhone","13722537737");
//            dto.put("bankType","TOPRIVATE");
//
//            dto.put("accountName","聂换换");
//            dto.put("accountNo","6217000060031684713");
//            dto.put("bankName","中国建设银行");
//            dto.put("bankProv","天津");
//            dto.put("bankCity","天津市");
//            dto.put("bankBranch","开户地址new");
//            dto.put("bankCode","105100000017");
//
//            dto.put("timestamp",System.currentTimeMillis());

            JSONObject jsonObject = null;
            try {
                jsonObject = juHeZhongPayJFenService.merchantIn(dto);
            } catch (Exception e) {
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(ComCode.STATUS_CODE_9998_DESC);
                response.setError(e.getMessage());
                return response;
            }
            if (!"0000".equals(jsonObject.getString("code"))) {
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(jsonObject.getString("msg"));
                return response;
            }
            String subMchId = jsonObject.getString("subMchId");
            userSubMchId.setUserCode(request.getSubMerchantCode());
            userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
            userSubMchId.setSubmchid(subMchId);
            userService.addUserSubmchid(userSubMchId);
        }

        // 获取费率
        RateEntity rateEntity = new RateEntity();
        rateEntity.setUserLevel(userEntity.getLevel());
        rateEntity.setPayChannel(ComCode.PAYCHANNEL_HL2);
        rateEntity.setPayMethod("quick");
        rateEntity = userService.getRateByLevel(rateEntity);



        JSONObject dto = new JSONObject();
        dto.put("orderId", MakeOrderNum.makeOrderNum());
        dto.put("merchantId",ComCode.JFEN_MERCHANT_ID);
        dto.put("serviceType","8");
        dto.put("subMchId",userSubMchId.getSubmchid());
        dto.put("idType","01");
        dto.put("idNo",userDetailEntity.getIdCard());
        if(rateEntity==null){
            dto.put("d0Fee","0.0043");
        }else{
            dto.put("d0Fee",rateEntity.getRate());
        }

        dto.put("accountName",userDetailEntity.getRealName());
        dto.put("accountNo",cardEntity.getCardNo());
        dto.put("mobile",cardEntity.getCardMobile());
        dto.put("notifyUrl",Global.getConfig("project.access.url")+"/api/pay/openCardCallback");
        dto.put("merchantKey",ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp",System.currentTimeMillis());
        PayBackDto payBackDto = new PayBackDto();
        try {
            JSONObject jsonObject = juHeZhongPayJFenService.openCard(dto);
            if("0000".equals(jsonObject.get("code"))){
                payBackDto.setUrl(jsonObject.getString("url"));
                response.setData(payBackDto);
                response.setStatus(ComCode.STATUS_CODE_2000);
                return response;
            }else{
                payBackDto.setUrl(jsonObject.getString("url"));

                response.setData(payBackDto);
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(jsonObject.getString("msg"));
                return response;
            }

        } catch (Exception e) {
            response.setData(payBackDto);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(ComCode.STATUS_CODE_9998_DESC);
        }

        return response;
    }

    // HL2 通道 即JFEN  发送验证码  需要的参数 SubMerchantCode\amount\cardCode\PayChannel 通道\
    @Transactional(readOnly = false)
    public Response sendMessageJFen (JuHeZhongPayRequest request){
        request.setPayMethod("quick");
        CardEntity cardEntity = userService.getCardInfoSwpaccid(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        UserEntity userEntity = userService.getUserInfo(request);
        UserDetailEntity userDetailEntity = userService.getUserDetailByCode(request.getSubMerchantCode());
        userEntity.setUserDetail(userDetailEntity);

        // 2. 创建支付订单信息，并保存
        String code = IdGen.randomBase62(64);
        String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
        String payCode = IdGen.randomBase62(64);
        DecimalFormat df = new DecimalFormat("######0.00");
        String amount = df.format(Double.valueOf(request.getAmount()));
        OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,"quick", request.getPayChannel(), "1",amount , request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userDetailEntity.getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userDetailEntity.getCard().getCardType()) ? 6 : 0)), request.getCardCode());

        payDao.saveOrderInfo(orderEntity);
        // 3. 创建分润信息，并保存
        Map<String, String> userBenefits = getUserBenefit(userEntity, request);
        for (String key : userBenefits.keySet()) {
            String benefitCode = IdGen.randomBase62(64);
            BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
            benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
            benefitEntity.setPayMethod(orderEntity.getPayMethod());
            payDao.saveBenefitInfo(benefitEntity);
        }
        Response response = new Response();

        JSONObject dto = new JSONObject();
        dto.put("orderId",payCode); // 订单号
        dto.put("merchantId",ComCode.JFEN_MERCHANT_ID);
        dto.put("serviceType","4");
        dto.put("subMchId",userSubMchId.getSubmchid());
        dto.put("merchantKey",ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp",System.currentTimeMillis());
        dto.put("amount",amount);
        dto.put("idNo",userDetailEntity.getIdCard());
        dto.put("accountName",userDetailEntity.getRealName());
        dto.put("accountNo",cardEntity.getCardNo());

        dto.put("mobile",cardEntity.getCardMobile());
        dto.put("swpaccid",cardEntity.getSwpaccid());
        dto.put("notifyUrl",Global.getConfig("project.access.url")+"/api/pay/openCardCallback");
        try {
            JSONObject jsonObject = juHeZhongPayJFenService.openCard(dto);
            if("0000".equals(jsonObject.get("code"))){
                orderEntity.setTradeNo(jsonObject.getString("trade_no"));
                payDao.updateOrderTradeNo(orderEntity);
                response.setData(orderEntity);
                response.setStatus(ComCode.STATUS_CODE_2000);
                response.setMessage(ComCode.STATUS_CODE_2000_DESC);
                return response;
            }
            response.setData(orderEntity);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(jsonObject.getString("msg"));
            return response;
        } catch (Exception e) {
            response.setData(orderEntity);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(ComCode.STATUS_CODE_9998_DESC);
            response.setError(e.getMessage());

        }

        return response;
    }

    // HL2 通道 即JFEN  发送验证码  需要的参数 SubMerchantCode\payNo\passwd\cardCode \
    @Transactional(readOnly = false)
    public PayBackDto jFenPayJuhezhong (JuHeZhongPayRequest request) throws Exception {

        request.setPayMethod("quick");
        CardEntity cardEntity = userService.getCardInfoSwpaccid(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        // 如果没有注册 则先注册
        if(userSubMchId == null){
            throw  new MyException("未开卡，请先开卡");
//            UserEntity userEntity = userService.getUserInfo(request);
//            UserDetailEntity userDetailEntity = userService.getUserDetailByCode(request.getSubMerchantCode());
//            CardEntity cardEntityDebit = userService.getCardInfoByCode(userEntity);
//            JSONObject dto = new JSONObject();
//
//            String orderId = MakeOrderNum.makeOrderNum();
//
//            dto.put("orderId", MakeOrderNum.makeOrderNum());
//
//            dto.put("serviceType",1);
//            dto.put("subMerchantName",userDetailEntity.getRealName()+orderId);
//            dto.put("subMerchantType","PERSON");
//            dto.put("businessLicense",userDetailEntity.getRealName()+orderId);
//            dto.put("legalPersonName",userDetailEntity.getRealName());
//            dto.put("legalPersonID",userDetailEntity.getIdCard());
//            dto.put("subMerchantPersonName",userDetailEntity.getRealName());
//            dto.put("subMerchantPersonPhone",userEntity.getMobile());
//            dto.put("bankType","TOPRIVATE");
//
//            dto.put("accountName",userDetailEntity.getRealName());
//            dto.put("accountNo",cardEntityDebit.getCardNo());
//            dto.put("bankName",cardEntityDebit.getBankName());
//            dto.put("bankProv",cardEntityDebit.getProvince());
//            dto.put("bankCity",cardEntityDebit.getCity());
//            dto.put("bankBranch",cardEntityDebit.getCardPlace());
//            dto.put("bankCode",cardEntityDebit.getBelongBank());
//
//            dto.put("timestamp",System.currentTimeMillis());
//
//            JSONObject jsonObject = null;
//            try {
//                jsonObject = juHeZhongPayJFenService.merchantIn(dto);
//            } catch (Exception e) {
//
//            }
//            if (!"0000".equals(jsonObject.getString("code"))) {
//                new MyException(jsonObject.getString("msg"));
//            }
//            String subMchId = jsonObject.getString("subMchId");
//            userSubMchId = new UserSubMchId();
//            userSubMchId.setUserCode(request.getSubMerchantCode());
//            userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
//            userSubMchId.setSubmchid(subMchId);
//            userService.addUserSubmchid(userSubMchId);
        }
//        if(){
//
//        }
        OrderEntity orderEntity = this.getOrder(request.getPayNo());

        PayBackDto payBackDto = new PayBackDto();
        payBackDto.setIsUrl("0");

        JSONObject dto = new JSONObject();
        dto.put("orderId",MakeOrderNum.makeOrderNum()); // 非订单号
        dto.put("merchantId",ComCode.JFEN_MERCHANT_ID);// 商户号
        dto.put("serviceType","5");// 操作类型 5
        dto.put("subMchId",userSubMchId.getSubmchid());// 子商户号
        dto.put("merchantKey",ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp",System.currentTimeMillis());
        dto.put("passwd",request.getPasswd());
        dto.put("productName","productName");
        dto.put("tradeNo",orderEntity.getTradeNo());

        dto.put("swpaccid",cardEntity.getSwpaccid());

        JSONObject jsonObject = juHeZhongPayJFenService.openCard(dto);

        this.notifyPay(orderEntity);
        if("0000".equals(jsonObject.get("code"))){
            payBackDto.setMessage(jsonObject.getString("msg"));
            return payBackDto;
        }else{

            payBackDto.setMessage(jsonObject.getString("msg"));
            throw new MyException(jsonObject.getString("msg"));
        }

    }


    /**
     * huanqiuhuiju 快捷支付
     * @param request
     * @return
     */
     public PayBackDto huanqiuhujuPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request,CardEntity cardEntity) throws Exception {
         PayBackDto payBackDto = new PayBackDto();
         JSONObject dto = new JSONObject();
         String orderId = IdGen.randomBase62(32);
         RateEntity rateEntity = new RateEntity();
         rateEntity.setUserLevel(userEntity.getLevel());
         rateEntity.setPayMethod("quick");
         rateEntity.setPayChannel(ComCode.PAYCHANNEL_HUANQIUHUIJU);
         rateEntity = userService.getRateByLevel(rateEntity);

         dto.put("transcode","300");// 交易码
         dto.put("version","0100"); // 版本号
         dto.put("ordersn", MakeOrderNum.makeOrderNum()); // 流水号 每次交易都唯一
         dto.put("merchno",ComCode.HUANQIUHUIJU_MERCHANT_ID); // 商户号
         dto.put("dsorderid", orderId); // 订单号 唯一
         dto.put("txnAmt",request.getAmount()); // 交易金额
         dto.put("txnRate",Double.valueOf(rateEntity.getRate())*100);// 费率

         dto.put("siglePrice",rateEntity.getSiglePrice() ); // 单笔价格
         dto.put("merchno",ComCode.HUANQIUHUIJU_MERCHANT_ID); // 商户号
         dto.put("realName",userEntity.getUserDetail().getRealName()); // 真实姓名
         dto.put("idCardNo",userEntity.getUserDetail().getIdCard()); // 身份证号
         dto.put("bankCardNo",cardEntity.getCardNo());// 银行卡号
         dto.put("bankCode",cardEntity.getBelongBank()); // 银行代码
         dto.put("bankName",cardEntity.getBankName()); // 消费卡银行名称
         dto.put("phone",cardEntity.getCardMobile()); // 手机号
         dto.put("cvn2",request.getCvn2());
         dto.put("expireDate",request.getExpireDate());
         dto.put("notifyUrl", Global.getConfig("project.access.url")+"/api/pay/notifyHuanqiuhuijuPay");
         dto.put("settleBankCode",userEntity.getUserDetail().getCard().getBelongBank()); // 结算银行代码
         dto.put("settleCardNo",userEntity.getUserDetail().getCard().getCardNo()); // 结算银行卡
         dto.put("settlePhone",userEntity.getUserDetail().getCard().getCardMobile()); // 结算手机号
         dto.put("settleCardBankName",userEntity.getUserDetail().getCard().getBankName()); // 结算卡银行名称
         System.out.println(dto.toJSONString());
         JSONObject jsonObject = huanqiuhuijuService.huanqiuhuijuPay(dto);

         if("0000".equals(jsonObject.get("returncode"))){
             payBackDto.setIsUrl("0");
             payBackDto.setPayChannel(ComCode.PAYCHANNEL_HUANQIUHUIJU);
             this.notifyPay(orderEntity);
             return payBackDto;
         }else{
             orderEntity.setPayStatus("4");
             payDao.updateOrderStatus(orderEntity);
             BenefitEntity benefitEntity = new BenefitEntity();
             benefitEntity.setOrderCode(orderEntity.getPayCode());
             benefitEntity.setDelFlag("1");
             payDao.deleteBenefit(benefitEntity);
             throw new MyException(jsonObject.getString("errtext"));
         }

     }


    /**
     * 支付宝支付
     * @param request
     * @return
     * @throws AlipayApiException
     */
    @Transactional(readOnly = false)
     public PayBackDto aliPay(JuHeZhongPayRequest request) throws AlipayApiException {
         // 1. 根据入参获取用户详情信息，包括支付卡片信息
         UserEntity userEntity = userService.getUserInfo(new Request(request.getSubMerchantCode()));
         userEntity = userService.getUserDetailInfo(userEntity);

         // 2. 创建支付订单信息，并保存
         String code = IdGen.randomBase62(64);
         String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
         String payCode = IdGen.randomBase62(64);
         DecimalFormat df = new DecimalFormat("######0.00");
         List<Dict> list = DictUtils.getDictList("level_"+request.getLevel());
         String amount = "398";
         if(list != null && list.size()>0){
            amount = list.get(0).getValue();
         }

         // 创建订单保存
         if("D".equals(request.getLevel())){
             request.setSubject("升级成白银会员");
         }else if("C".equals(request.getLevel())){
             request.setSubject("升级成黄金会员");
         }else if("B".equals(request.getLevel())){
             request.setSubject("升级成钻石会员");
         }
         OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode,request.getPayMethod(), "ali", "1",amount , request.getLevel() + ":" + request.getSubject(), "","0", request.getCardCode());
         payDao.saveOrderInfo(orderEntity);

         if("B".equals(request.getLevel())){
             UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
             upgradeUserEntity.setUserCode(request.getSubMerchantCode());
             upgradeUserEntity.setLevel(request.getLevel());
             upgradeUserEntity.setOrderCode(payCode);
             upgradeUserEntity.setStatus("0");
             upgradeUserEntity.setAfterMobile(request.getAfterMobile());
             userService.addUpgradeUser(upgradeUserEntity);
         }


         // 支付宝支付返回对应支付信息
         JSONObject dto = new JSONObject();
         dto.put("payCode",payCode);
         dto.put("subject",request.getSubject());
         dto.put("amount",amount);
         dto.put("body",new HashMap<>());

         String body = alipayService.aliPay(dto);
         PayBackDto payBackDto = new PayBackDto();
         payBackDto.setBody(body);
         return payBackDto;
     }


    /**
     * 回调
     * @param orderEntity
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public OrderEntity notifyPay(OrderEntity orderEntity) throws Exception {
        QuickDto dto = new QuickDto();
        dto.setOrderId(orderEntity.getPayCode());
        dto.setMerchantId(ComCode.MERCHANT_ID);
        dto.setMerchantKey(ComCode.MERCHANT_KEY);
        dto.setTimestamp(System.currentTimeMillis());

        orderEntity = payDao.getOrder(orderEntity);
        JSONObject jsonObject = null;
        if(ComCode.PAYCHANNEL_HL3.equals(orderEntity.getPayChannel())){
            dto.setMerchantId(ComCode.INTEGRAL_MERCHANT_ID);
            dto.setMerchantKey(ComCode.INTEGRAL_MERCHANT_KEY);
            jsonObject = juHeZhongPayIntegralService.query(dto);
        }else if(ComCode.PAYCHANNEL_HL1.equals(orderEntity.getPayChannel())){
            jsonObject = juHeZhongPayService.query(dto);
        }else if(ComCode.PAYCHANNEL_HL2.equals(orderEntity.getPayChannel())){
            dto.setMerchantId(ComCode.JFEN_MERCHANT_ID);
            dto.setMerchantKey(ComCode.JFEN_MERCHANT_KEY);
            jsonObject = juHeZhongPayService.query(dto);
        }else if(ComCode.PAYCHANNEL_HUANQIUHUIJU.equals(orderEntity.getPayChannel())){
            orderEntity.setPayStatus("2");
            payDao.updateOrderStatus(orderEntity);
            return orderEntity;
        }

        System.out.println("查询订单返回结果："+jsonObject.toJSONString());
        // 支付成功
        if("0000".equals(jsonObject.get("code"))){

            orderEntity.setPayStatus("2");

            payDao.updateOrderStatus(orderEntity);
//            BenefitEntity benefitEntity = new BenefitEntity();
//            benefitEntity.setOrderCode(orderEntity.getPayCode());
//            benefitEntity.setBenefitStatus("1");
//            payDao.updateBenefit(benefitEntity);
        }else{ // 支付失败
            orderEntity.setPayStatus("4");
            payDao.updateOrderStatus(orderEntity);
            BenefitEntity benefitEntity = new BenefitEntity();
            benefitEntity.setOrderCode(orderEntity.getPayCode());
            benefitEntity.setDelFlag("1");
            payDao.deleteBenefit(benefitEntity);
        }
        orderEntity = payDao.getOrder(orderEntity);
        return orderEntity;
    }

    /**
     * 回调
     * @param orderEntity
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public OrderEntity aliPayNotifyPay(OrderEntity orderEntity,String code) throws Exception {

        if("TRADE_SUCCESS".equals(code)) {

            orderEntity.setPayStatus("2");
            payDao.updateOrderStatus(orderEntity);
            orderEntity = payDao.getOrder(orderEntity);

            UserEntity userEntity = new UserEntity();
            userEntity.setCode(orderEntity.getUserCode());

            if(orderEntity.getSubject() != null && !"".equals(orderEntity.getSubject())){
                userEntity.setLevel(orderEntity.getSubject().substring(0,1));

                if("B".equals(userEntity.getLevel())){
                    UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
                    upgradeUserEntity.setUserCode(orderEntity.getUserCode());
                    upgradeUserEntity.setLevel(userEntity.getLevel());
                    upgradeUserEntity.setStatus("1");
                    upgradeUserEntity.setOrderCode(orderEntity.getPayCode());
                    userService.updateUpgradeUser(upgradeUserEntity);
                }else{
                    userService.updateUserLevelByCode(userEntity);
                }
            }


        }else{
            orderEntity.setPayStatus("4");
            payDao.updateOrderStatus(orderEntity);
            orderEntity = payDao.getOrder(orderEntity);

            if(orderEntity.getSubject() != null && !"".equals(orderEntity.getSubject()) && "A".equals(orderEntity.getSubject().substring(0,1))){
                UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
                upgradeUserEntity.setUserCode(orderEntity.getUserCode());
                upgradeUserEntity.setLevel(orderEntity.getSubject().substring(0,1));
                upgradeUserEntity.setOrderCode(orderEntity.getPayCode());
                upgradeUserEntity.setStatus("3");
                userService.updateUpgradeUser(upgradeUserEntity);
            }
        }
        return orderEntity;
    }


    public OrderEntity getOrder(OrderEntity orderEntity){
        return payDao.getOrder(orderEntity);
    }

    public OrderEntity getOrder(String payNo){
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setPayNo(payNo);
        return payDao.getOrder(orderEntity);
    }

    @Transactional(readOnly = false)
    public void updateOrderTiming(){
//        System.out.println("。。。。。。。定时任务。updateOrderTiming开始。。。。");
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setEndTime(DateUtils.getYesterday(DateUtils.getYesterday("yyyy-MM-dd HH:mm:ss")));
        List<OrderEntity> list = payDao.getOrderListTimeing(orderEntity);
        for(OrderEntity order:list){
            order.setPayStatus("3");
            payDao.updateOrderStatus(order);
            BenefitEntity benefitEntity = new BenefitEntity();
            benefitEntity.setOrderCode(order.getPayCode());
            payDao.deleteBenefit(benefitEntity);
        }
//        System.out.println("。。。。。。。定时任务。updateOrderTiming结束。。。。");
    }

    @Transactional(readOnly = false)
    public void updateOrders(){
//        System.out.println("。。。。。。。定时任务。updateOrders开始。。。。");
        try {
            OrderEntity orderEntity = new OrderEntity();
            orderEntity.setStartTime(DateUtils.getYesterday(DateUtils.getYesterday("yyyy-MM-dd HH:mm:ss")));
            orderEntity.setEndTime(DateUtils.formatDate(DateUtils.addHours(new Date(),-12),"yyyy-MM-dd HH:mm:ss"));
            List<OrderEntity> list = payDao.getOrderListTimeing(orderEntity);
            for(OrderEntity order:list){
                QuickDto dto = new QuickDto();
                dto.setOrderId(order.getPayCode());

                dto.setTimestamp(System.currentTimeMillis());
                JSONObject jsonObject = null;
                if(ComCode.PAYCHANNEL_HL3.equals(order.getPayChannel())){
                    dto.setMerchantId(ComCode.MERCHANT_ID);
                    dto.setMerchantKey(ComCode.MERCHANT_KEY);

                    jsonObject = juHeZhongPayIntegralService.query(dto);

                }else if(ComCode.PAYCHANNEL_HL1.equals(order.getPayChannel())){
                    jsonObject = juHeZhongPayService.query(dto);
                }
                if(jsonObject!=null){
//                    System.out.println("查询订单返回结果："+jsonObject.toJSONString());
                    // 支付成功
                    if("0000".equals(jsonObject.get("code"))){
                        System.out.println("查询订单返回结果："+jsonObject.toJSONString());
                        order.setPayStatus("2");
                        payDao.updateOrderStatus(order);
                    }else{ // 支付失败
                        order.setPayStatus("4");
                        payDao.updateOrderStatus(order);
                        BenefitEntity benefitEntity = new BenefitEntity();
                        benefitEntity.setOrderCode(order.getPayCode());
                        benefitEntity.setDelFlag("1");
                        payDao.deleteBenefit(benefitEntity);
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        System.out.println("。。。。。。。定时任务。updateOrders结束。。。。");
    }
}
