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

import com.alibaba.fastjson.JSONObject;
import com.thinkgem.jeesite.common.baseBean.Request;
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.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.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.JuHeZhongPayService;
import com.thinkgem.jeesite.modules.user.bean.JuHeZhongPayRequest;
import com.thinkgem.jeesite.modules.user.bean.UserRequest;
import com.thinkgem.jeesite.modules.user.entity.CardEntity;
import com.thinkgem.jeesite.modules.user.entity.UserEntity;
import com.thinkgem.jeesite.modules.user.service.UserApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
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
@Transactional(readOnly = true)
public class PayApiService {
    @Autowired
    private PayApiDao payDao;
    @Autowired
    private UserApiService userService;
    @Autowired
    private JuHeZhongPayService juHeZhongPayService;

    @Autowired
    private JuHeZhongPayIntegralService juHeZhongPayIntegralService;

    @Transactional(readOnly = false)
    public PayBackDto quickPay(JuHeZhongPayRequest request) throws MyException, Exception {
        // 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()));
        OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, 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())));
            payDao.saveBenefitInfo(benefitEntity);
        }
        // 4. JuHeZhong支付
        PayBackDto payBackDto = new PayBackDto();
        // 获取支付卡号
        CardEntity cardEntityPay = userService.getCardInfo(request);
        if("quick_no_integral".equals(request.getPayChannel())){
            payBackDto = quickPayJuHeZhongPay(userEntity, orderEntity, request,cardEntityPay);
        }else if("quick_integral".equals(request.getPayChannel())){
            if(!"C".equals(cardEntityPay.getCardType())){
                payBackDto.setMessage("只能用信用卡支付");
            }else if(cardEntityPay.getSupportPayChannel()==null || !cardEntityPay.getSupportPayChannel().contains("quick_integral,")){
                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_no_integral");
        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 {

        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("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);
        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;
    }

    /**
     * 回调
     * @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());

        JSONObject jsonObject = juHeZhongPayService.query(dto);
        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 if("0001".equals(jsonObject.get("code"))){ // 支付失败
            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;
    }


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


    @Scheduled(cron = "*/30 * * * * ?")
    @Transactional(readOnly = false)
    public void updateOrderTiming(){
        System.out.println("定时任务。。。。。");
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setCreated(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);
        }
    }
}
