package com.thinkgem.jeesite.modules.user.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.common.utils.MD5;
import com.thinkgem.jeesite.modules.commonError.MyException;
import com.thinkgem.jeesite.modules.message.MessageUtils;
import com.thinkgem.jeesite.modules.pay.entity.RateEntity;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.MerchantDto;
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.user.bean.IdentityCodeRequest;
import com.thinkgem.jeesite.modules.user.bean.UserRequest;
import com.thinkgem.jeesite.modules.user.dao.UserApiDao;
import com.thinkgem.jeesite.modules.user.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.Rate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 前端用户相关
 */
@Service
@Lazy(false)
@Transactional
public class UserApiService {
    /** log */
    private static Logger logger = LoggerFactory.getLogger(UserApiService.class);

    @Autowired
    private UserApiDao userDao;
    @Autowired
    private JuHeZhongPayService juHeZhongPayService;

    @Autowired
    private JuHeZhongPayIntegralService juHeZhongPayIntegralService;

    @Autowired
    private JuHeZhongPayJFenService juHeZhongPayJFenService;

    public UserEntity getUserInfo(Request request) {
        UserEntity user = userDao.getUserInfo(request);
        // 以下两行代码应Android要求，增加空detail和card
        user.setUserDetail(new UserDetailEntity());
        user.getUserDetail().setCard(new CardEntity());
        return user;
    }

    @Transactional(readOnly = false)
    public String getIdentifyCode(IdentityCodeRequest request) throws IOException, NoSuchAlgorithmException {
        // 生成验证码
//        String identifyCode = IdGen.randomBase62(6).toUpperCase();
//        换成六位数字
        String identifyCode = IdGen.randomIntId();

        StringBuilder sb = new StringBuilder();
        // 发送验证码  1注册 2验证码登录 3忘记密码/修改密码 4实名认证 5添加储蓄卡 6添加信用卡
        if("1".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else if("2".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else if("3".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else if("4".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else if("5".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else if("6".equals(request.getFunction()) ){ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }else{ // 注册
            sb.append("验证码：");
            sb.append(identifyCode);
        }
        MessageUtils.sendMessage(request.getMobile(),"28",sb.toString());

        // 验证码入库
        IdentityCodeEntity identityCodeEntity = new IdentityCodeEntity(IdGen.randomBase62(64), request.getFunction(), request.getMobile(), identifyCode);
        userDao.saveIdentifyCode(identityCodeEntity);
        // 返回验证码
        return identifyCode;
    }

    public IdentityCodeEntity getIdentifyCode(UserRequest request) {
        return userDao.getIdentifyCode(request);
    }


    public boolean checkIdentifyCodeExpired(IdentityCodeEntity identityCodeEntity) throws ParseException {
        Date now = new Date();
        Date created = ComCode.YYYYMMDD_HHMMSS.parse(identityCodeEntity.getCreated());
        // 验证码半小时内有效
        if ((now.getTime() - created.getTime()) < (30 * ComCode.seconds * ComCode.mills)) {
            return true;
        }
        return false;
    }

    public UserEntity checkRecommend(UserRequest request) {
        return userDao.checkRecommend(request);
    }

    public UserEntity checkMobile(UserRequest request) {
        return userDao.checkMobile(request);
    }

    public UserEntity checkMobile(String mobile) {
        UserRequest request = new UserRequest();
        request.setMobile(mobile);
        return userDao.checkMobile(request);
    }

    @Transactional(readOnly = false)
    public UserEntity signUp(UserRequest request) throws MyException {
        // 保存用户信息
        String code = IdGen.randomBase62(64);
        UserEntity recommend = userDao.checkRecommend(request);
        if(recommend==null && userDao.checkNoUser() >0){
            throw new MyException("推荐人手机号码不存在");
        }
        UserEntity userEntity = new UserEntity(code, "", request.getMobile(), MD5.sign(request.getNewPassword(), ComCode.signCode, "utf-8"), request.getRecommendedMobile(), recommend==null?"0"+",":recommend.getRecommendedPath() + recommend.getId() + ",", recommend.getBelongTo());
        userDao.signUp(userEntity);
        UserEntity user = userDao.getUserInfo(new Request(code));
        // 以下两行代码应Android要求，增加空detail和card
        user.setUserDetail(new UserDetailEntity());
        user.getUserDetail().setCard(new CardEntity());
        return user;
    }

    @Transactional(readOnly = false)
    public void resetPassword(UserRequest request) {
        // 根据手机号查询用户信息，因为Controller层判断过用户信息，因此此处一定可以查到用户信息
        UserEntity userEntity = userDao.checkMobile(request);
        userEntity.setPassword(MD5.sign(request.getNewPassword(), ComCode.signCode, "utf-8"));
        // 重置密码
        userDao.resetPassword(userEntity);
    }

    public UserEntity getUserInfoByPassword(UserRequest request) {
        request.setPassword(MD5.sign(request.getPassword(), ComCode.signCode, "utf-8"));
        return userDao.getUserInfoByPassword(request);
    }

    public UserEntity getUserInfoByIdentifyCode(UserRequest request) {
        // Controller层判断过验证码信息，因此直接根据手机号查询用户信息即可
        return userDao.checkMobile(request);
    }

    public UserEntity getUserDetailInfo(UserEntity userEntity) {
        // 根据用户code获取用户详情
        UserDetailEntity userDetailEntity = userDao.getUserDetailByCode(userEntity);
        // 获取用户结算卡信息
        if (userDetailEntity != null) {
            userEntity.setUserDetail(userDetailEntity);
            CardEntity cardEntity = userDao.getCardInfoByCode(userEntity);
            userEntity.getUserDetail().setCard(cardEntity==null?new CardEntity():cardEntity);
        } else {
            userDetailEntity = new UserDetailEntity();
            userEntity.setUserDetail(userDetailEntity);
            userEntity.getUserDetail().setCard(new CardEntity());
        }
        return userEntity;
    }

    public List<CardEntity> getCardsInfo(UserRequest request) {
        List<CardEntity> list = userDao.getCardsInfo(request);
        for (CardEntity entity : list) {
            entity.setCardSrc(Global.getConfig("sys.pre.url") + entity.getCardSrc());
            if (StringUtils.isNotBlank(entity.getBankShort())) {
                entity.setBankUrl(Global.getConfig("logo.bank.url") + entity.getBankShort());
            }
        }
        return list;
    }

    public CardEntity getCardInfo(Request request) {
        CardEntity entity = userDao.getCardInfo(request);
        entity.setCardSrc(Global.getConfig("sys.pre.url") + entity.getCardSrc());
        if (StringUtils.isNotBlank(entity.getBankShort())) {
            entity.setBankUrl(Global.getConfig("logo.bank.url") + entity.getBankShort());
        }
        return entity;
    }

    public CardEntity getCardInfoSwpaccid(Request request) {
        CardEntity entity = userDao.getCardInfoSwpaccid(request);

        return entity;
    }

    @Transactional(readOnly = false)
    public void removeCards(UserRequest request) {
        userDao.removeCards(request);
    }

    @Transactional(readOnly = false)
    public void addNewCard(UserRequest request) throws MyException, Exception {
        //校验银行卡的卡号
        String checkCardNum = checkCardNum(request.getCardNo());
        if(StringUtils.isBlank(checkCardNum)){
            logger.debug("输入银行卡号有误");
            throw new MyException("输入银行卡号有误");
        }
        CardEntity cardEntity1 = userDao.getCardEntity(request);
        if(cardEntity1 != null){
            throw new MyException("不能重复添加卡片");
        }
        //        CC信用卡，DC储蓄卡
        String cardType = checkCardNum.equals("CC")?"C":"D";
        if (!request.getCardType().equals(cardType)){
            logger.debug("银行卡类别不正确");
            throw new MyException("银行卡类别不正确");
        }
        String code = IdGen.randomBase62(64);
        String type = "1"; // 默认将卡片添加为对私
        String status = "1"; // 新增卡片审核状态均为审核
        String subMerchantId = "";//registJuHeZhongPay(request, type);
        String cardSrc = "";
        if(request.getCardSrc()!= null){
            cardSrc = request.getCardSrc().replace(Global.getConfig("sys.pre.url"), "");
        }
        CardEntity cardEntity = new CardEntity(code, request.getSubMerchantCode(), request.getCardType(), request.getCardNo(),request.getExpireDate(),request.getCvn2(), request.getCardMobile(), request.getBelongBank(), request.getCardBank(), request.getProvince()+request.getCity(), "N", subMerchantId, cardSrc, type, status, request.getProvince(), request.getCity());
        userDao.addNewCard(cardEntity);
    }

    @Transactional(readOnly = false)
    public void addFeedback(UserRequest request) {
        String code = IdGen.randomBase62(64);
        FeedbackEntity feedbackEntity = new FeedbackEntity(code, request.getSubMerchantCode(), request.getFeedback());
        userDao.addFeedback(feedbackEntity);
    }

    public AboutUsEntity getAboutUsInfo(UserRequest request) {
        return userDao.getAboutUsInfo(request);
    }

    // 实名认证
    @Transactional(readOnly = false)
    public void certification(UserRequest request) throws MyException, Exception {
        logger.debug("进入实名认证service");
//        校验银行卡的卡号是否正确
        String checkCardNum = checkCardNum(request.getCardNo());
        if(StringUtils.isBlank(checkCardNum)){
            throw new MyException("输入银行卡号有误！");
        }
//        CC信用卡，DC储蓄卡
        String cardType = checkCardNum.equals("CC")?"C":"D";
        // 更新用户详情
        UserDetailEntity userDetailEntity = new UserDetailEntity(IdGen.randomBase62(64), request.getSubMerchantCode(), request.getRealName(), request.getIdCard(), request.getProvince()+request.getCity(), "", "", "", "");
        if (userDao.getUserDetailByCode(new UserEntity(request.getSubMerchantCode())) == null) {
            userDao.saveUserDetail(userDetailEntity);
            logger.debug("存完userdetail信息");
        } else {
            userDao.updateUserDetail(userDetailEntity);
            logger.debug("修改完userdetail信息");
        }
        // 为用户卡注册subMerchantId
        String type = "1"; // 默认将卡片添加为对私
        String status = "1"; // 新增卡片审核状态均为审核,因取消了后台审核功能
        String subMerchantId = null;//registJuHeZhongPay(request, type);




        // 更新银行卡详情
        CardEntity cardStatusEntity = new CardEntity(request.getSubMerchantCode(), "N");
        userDao.updateCardStatus(cardStatusEntity);
        logger.debug("修改完银行卡信息");
        CardEntity cardEntity = new CardEntity(IdGen.randomBase62(64), request.getSubMerchantCode(), cardType, request.getCardNo(), request.getExpireDate(), request.getCvn2(),request.getCardMobile(), request.getBelongBank(), request.getCardBank(), request.getCardPlace(), "Y", subMerchantId, "", type, status, request.getProvince(), request.getCity());
        CardEntity cardInfo = userDao.getCardEntity(request);
        if(cardInfo == null){
            userDao.addNewCard(cardEntity);
        }else{
            userDao.updateCard(cardEntity);
        }
//原有代码推荐好友逻辑修改，放到定时任务中
//
//        // 查询与实名用户相同推荐人的信息
//        UserEntity queryUserRecommendEntity = new UserEntity(request.getSubMerchantCode());
//        List<UserEntity> countRecommend = userDao.getUserInfoBySameRecommend(queryUserRecommendEntity);
//        // 与实名用户的推荐人，推荐了4名及以上人员实名
//        if (countRecommend.size() >= 4) {
//            String[] recommendPath = countRecommend.get(0).getRecommendedPath().split(",");
//
//
//            UserEntity recommendedUser = userDao.getUserInfoById(recommendPath[recommendPath.length - 1]);
//                // 实名用户的推荐人等级由E（青铜）升为D（白银）
//            if (recommendedUser.getLevel().equals("E")){
//                recommendedUser.setLevel("D");
//                userDao.updateUserLevel(recommendedUser);
//            }
//
//            RateEntity rateEntityParam = new RateEntity();
//            rateEntityParam.setUserLevel("D");
//            List<RateEntity> list = userDao.getRateListByLevel(rateEntityParam);
//            for(RateEntity rateEntity:list){
//                if(ComCode.PAYCHANNEL_HL3.equals(rateEntity.getPayChannel())){
//                   String subMchId = this.quickPayHandleJuhezhong(request,"","D");
//                   UserSubMchId userSubMchId = new UserSubMchId();
//                   userSubMchId.setSubmchid(subMchId);
//                   userSubMchId.setUserCode(recommendedUser.getCode());
//                   userSubMchId.setPayChannel(rateEntity.getPayChannel());
//
//                   int row = this.updateUserSubmchid(userSubMchId);
//                   if(row == 0){
//                       this.addUserSubmchid(userSubMchId);
//                   }
//                }else if(ComCode.PAYCHANNEL_HL2.equals(rateEntity.getPayChannel())){
//                    UserSubMchId userSubMchId = new UserSubMchId();
//                    userSubMchId.setUserCode(recommendedUser.getCode());
//                    userSubMchId.setPayChannel(rateEntity.getPayChannel());
//
//                    UserSubMchId userSubMchIdQuery = userDao.getUserSubmchid(userSubMchId);
//
//                    // 如果推荐人的 quick_jfen 通道下的 subMchId 是空 则该通道下先注册
//                    if(userSubMchIdQuery == null){
//                        recommendedUser = this.getUserDetailInfo(recommendedUser);
//                        JSONObject dto = new JSONObject();
//
//                        String orderId = MakeOrderNum.makeOrderNum();
//
//                        dto.put("orderId", MakeOrderNum.makeOrderNum());
//
//                        dto.put("serviceType",1);
//                        dto.put("subMerchantName",recommendedUser.getUserDetail().getRealName()+orderId);
//                        dto.put("subMerchantType","PERSON");
//                        dto.put("businessLicense",recommendedUser.getUserDetail().getRealName()+orderId);
//                        dto.put("legalPersonName",recommendedUser.getUserDetail().getRealName());
//                        dto.put("legalPersonID",recommendedUser.getUserDetail().getIdCard());
//                        dto.put("subMerchantPersonName",recommendedUser.getUserDetail().getRealName());
//                        dto.put("subMerchantPersonPhone",recommendedUser.getMobile());
//                        dto.put("bankType","TOPRIVATE");
//
//                        dto.put("accountName",recommendedUser.getUserDetail().getRealName());
//                        dto.put("accountNo",recommendedUser.getUserDetail().getCard().getCardNo());
//                        dto.put("bankName",recommendedUser.getUserDetail().getCard().getBankName());
//                        dto.put("bankProv",recommendedUser.getUserDetail().getCard().getProvince());
//                        dto.put("bankCity",recommendedUser.getUserDetail().getCard().getCity());
//                        dto.put("bankBranch",recommendedUser.getUserDetail().getCard().getCardPlace());
//                        dto.put("bankCode",recommendedUser.getUserDetail().getCard().getBelongBank());
//
//                        dto.put("timestamp",System.currentTimeMillis());
//
//                        JSONObject jsonObject =  juHeZhongPayJFenService.merchantIn(dto);
//                        if (!"0000".equals(jsonObject.getString("code"))) {
//                            throw new MyException(jsonObject.getString("msg"));
//                        }
//                        String subMchId = jsonObject.getString("subMchId");
//                        userSubMchIdQuery = new UserSubMchId();
//                        userSubMchIdQuery.setUserCode(recommendedUser.getCode());
//                        userSubMchIdQuery.setPayChannel(rateEntity.getPayChannel());
//                        userSubMchIdQuery.setSubmchid(subMchId);
//                        rateEntity.setServiceType("0");// 添加费率
//                        this.addUserSubmchid(userSubMchIdQuery);
//                        this.merchantFeelJFen(subMchId,rateEntity);
//                    }else{
//                        // 修改费率
//                        rateEntity.setServiceType("0");
//                        this.merchantFeelJFen(userSubMchId.getSubmchid(),rateEntity);
//                    }
//
//                }else if(ComCode.PAYCHANNEL_HL3.equals(rateEntity.getPayChannel())){
//
//                }
//            }
//
//        }

        /* 实名认证用户 商户入网 和 添加对应的费率  开始*/
        UserEntity userEntityRequest = this.getUserInfo(request);

        UserSubMchId userSubMchIdRequest = new UserSubMchId();
        userSubMchIdRequest.setUserCode(request.getSubMerchantCode());

        // ComCode.PAYCHANNEL_HL3 商户入网
//        关闭HL3通道
//        String inregralSubMchId = this.quickPayHandleJuhezhong(request,"",userEntityRequest.getLevel());
//        userSubMchIdRequest.setPayChannel(ComCode.PAYCHANNEL_HL3);
//        userSubMchIdRequest.setSubmchid(inregralSubMchId);
//        this.addUserSubmchid(userSubMchIdRequest);


        // JFen 商户入网 + 添加费率
        String JFenSubMchId = this.merchantInJFenJuhezhong(request);
//        String JFenSubMchId = "B105377143";
        // 更新用户状态
        UserEntity userEntity = new UserEntity();
        userEntity.setCode(request.getSubMerchantCode());
        userEntity.setStatus("2");//根据第三方接口返回信息更改用户状态
        userDao.updateUserInfo(userEntity);
        logger.debug("更新用户信息完成");
        userSubMchIdRequest.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchIdRequest.setSubmchid(JFenSubMchId);
        this.addUserSubmchid(userSubMchIdRequest);
        logger.debug("添加用户submchid完成");
        //添加费率部分暂时关闭，HL2通道不稳定
//        RateEntity rate = new RateEntity();
//        rate.setUserLevel(userEntityRequest.getLevel());
//        rate.setPayChannel(ComCode.PAYCHANNEL_HL2);
//        rate.setPayMethod("quick");//全部写死是quick
//        RateEntity rateEntity = this.getRateByLevel(rate);
//        rateEntity.setServiceType("0");
//        Thread.sleep(2000);
//        // 添加费率
//        this.merchantFeelJFen(JFenSubMchId,rateEntity);


        /* 实名认证用户 商户入网 和 添加对应的费率  结束*/

    }

    public List<ProvinceCityEntity> getProvinceCity(UserRequest request) {
        if ("P".equals(request.getType())) {
            return userDao.getProvince(request);
        }
        if ("C".equals(request.getType())) {
            return userDao.getCity(request);
        }
        return new ArrayList<ProvinceCityEntity>();
    }

    public List<BelongBankEntity> getBelongBank(UserRequest request) {
        return userDao.getBelongBank(request);
    }

    // 改变结算卡
    @Transactional(readOnly = false)
    public void changeDebit(UserRequest request) throws MyException, Exception {
        // 将该用户的所有卡类型置为非结算卡
        userDao.updateCardNoDebit(request);
        // 设置结算卡
        userDao.updateCardDebit(request);
        // 获取结算卡信息
//        CardEntity cardEntity = userDao.getDebitCard(new CardEntity(request.getDebitCardCode()));
        // 修改用户的结算卡
//        updateSettleJuHeZhongPay(cardEntity);
    }
    /*
     * 以下为类内使用方法
     */

    /**
     * 注册JuHeZhong支付用户 无积分
     *
     * @param request
     * @param type
     * @return
     * @throws MyException
     * @throws Exception
     */
    public String registJuHeZhongPay(UserRequest request, String type) throws MyException, Exception {
        UserEntity userEntity = userDao.getUserInfo(request);
        if (userEntity == null) {
            throw new MyException("用户信息为空");
        }
        UserDetailEntity userDetailEntity = userDao.getUserDetailByCode(userEntity);
        RateEntity rateEntityParam = new RateEntity(userEntity.getLevel(), "quick","");
        RateEntity rateEntity = userDao.getRateByLevel(rateEntityParam);
        if (rateEntity == null) {
            throw new MyException("费率等级信息为空");
        }
        // 为用户卡注册subMerchantId
        MerchantDto dto = new MerchantDto();
        dto.setMerchantId(ComCode.MERCHANT_ID);
        dto.setOrderId(IdGen.uuid());//不会产生交易订单
        dto.setIdType("01"); // 根据文档说明，证件类型固定为01
        dto.setAccName(userDetailEntity.getRealName());
        dto.setAccType(Integer.parseInt(type));//1 对私  2对公
        dto.setAccNo(request.getCardNo());
        dto.setAccProvince(request.getProvince());
        dto.setAccCity(request.getCity());
        dto.setBankCode(request.getBelongBank());
        dto.setMobile(request.getCardMobile());
        dto.setIdNo(userDetailEntity.getIdCard());
        dto.setSettleRate(new BigDecimal(rateEntity.getRate()));
        dto.setExtraRate(new BigDecimal(ComCode.EXTRA_RATE));
        dto.setTimestamp(System.currentTimeMillis());
        dto.setMerchantKey(ComCode.MERCHANT_KEY);
        JSONObject jsonObject = juHeZhongPayService.register(dto);
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));
        }
        return jsonObject.getString("subMchId");
    }

    // 积分 商户入网
    public String quickPayHandleJuhezhong(UserRequest request, String type,String level) throws MyException, Exception {
        BelongBankEntity belongBankEntity = userDao.getBelongBankEntity(request);

//        UserDetailEntity userDetailEntity = userDao.getUserDetailByCode(userEntity);
        RateEntity rateEntityParam = new RateEntity(level, "quick",ComCode.PAYCHANNEL_HL3);
        RateEntity rateEntity = userDao.getRateByLevel(rateEntityParam);
        if (rateEntity == null) {
            throw new MyException("费率等级信息为空");
        }
        JSONObject dto = new JSONObject();

        String orderId = MakeOrderNum.makeOrderNum();
        dto.put("orderId", orderId);//标识请求唯一（非订单号）
        dto.put("serviceType", 1);//服务类型
        dto.put("merchantId", ComCode.INTEGRAL_MERCHANT_ID);//商户号
        dto.put("subMerchantName",request.getRealName()+orderId );//对公的就按照营业执照的注册名称进行商户名的报备进件，个体户的需要突出省，市，区一级营业范围，如：“XX市+XX区+法人名称+营业范围”--例“北京市朝阳区洪新阳饭店”而且一个身份证不要重复入很多个做银联二维码交易的商户  原则上一个身份证下只有一个做银联二维码交易的户，23:00—7:00，这段时间，银联二维码可以交易，不结算

        dto.put("accName", request.getRealName());//开户名称
        dto.put("accNo", request.getCardNo());//开户账号
        dto.put("accType",1); //1=个人账户     0=企业账户1=个人账户

        dto.put("bankName", belongBankEntity.getBankName());//开户银行名（支行全称）
        dto.put("bankCode", request.getBelongBank());//联行号
        dto.put("mobile",request.getMobile());
        dto.put("idNo",request.getIdCard());//身份证号

        dto.put("settleType",rateEntity.getRateType());//费率类型 795934
        dto.put("address",request.getCardPlace());//地址
        dto.put("merchantKey", ComCode.INTEGRAL_MERCHANT_KEY);//商户key
        dto.put("timestamp", System.currentTimeMillis());//时间戳

        JSONObject jsonObject = juHeZhongPayIntegralService.quickPayHandle(dto);
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));
        }
        return jsonObject.getString("subMchId");
    }



    // JFen 商户入网
    public String merchantInJFenJuhezhong(UserRequest request) throws MyException, Exception {
        logger.debug("开始商户入网");
        UserEntity userEntity = userDao.getUserInfo(request);
        BelongBankEntity belongBankEntity = userDao.getBelongBankEntity(request);
        if (userEntity == null) {
            throw new MyException("用户信息为空");
        }
//        UserDetailEntity userDetailEntity = userDao.getUserDetailByCode(userEntity);
        RateEntity rateEntityParam = new RateEntity(userEntity.getLevel(), "quick",ComCode.PAYCHANNEL_HL3);
        RateEntity rateEntity = userDao.getRateByLevel(rateEntityParam);
        if (rateEntity == null) {
            throw new MyException("费率等级信息为空");
        }
        JSONObject dto = new JSONObject();

        String orderId = MakeOrderNum.makeOrderNum();

        dto.put("orderId", MakeOrderNum.makeOrderNum());

        dto.put("serviceType",1);
        dto.put("subMerchantName",request.getRealName()+orderId);
        dto.put("subMerchantType","PERSON");
        dto.put("businessLicense",request.getRealName()+orderId);
        dto.put("legalPersonName",request.getRealName());
        dto.put("legalPersonID",request.getIdCard());
        dto.put("subMerchantPersonName",request.getRealName());
        dto.put("subMerchantPersonPhone",userEntity.getMobile());
        dto.put("bankType","TOPRIVATE");

        dto.put("accountName",request.getRealName());
        dto.put("accountNo",request.getCardNo());
        dto.put("bankName",belongBankEntity.getBankName());
        dto.put("bankProv",request.getProvince());
        dto.put("bankCity",request.getCity());
        dto.put("bankBranch",request.getProvince()+request.getCity());
        dto.put("bankCode",request.getBelongBank());

        dto.put("timestamp",System.currentTimeMillis());

        JSONObject jsonObject =  juHeZhongPayJFenService.merchantIn(dto);
        if (!"0000".equals(jsonObject.getString("code"))) {
            logger.debug("商户入网失败，jsonObject: {} "+jsonObject);
            throw new MyException(jsonObject.getString("msg"));
        }
        logger.debug("商户入网完成");
        return jsonObject.getString("subMchId");
    }



    public void submitPayTest(String subMchId) throws Exception {
        JSONObject dto = new JSONObject();

        dto.put("serviceType", 4);// 服务类型
        dto.put("merchantId",ComCode.INTEGRAL_MERCHANT_ID);//商户号
        dto.put("orderId", IdGen.randomBase62(64));//订单号
        dto.put("subMchId", subMchId);//由系统分配的商户号
        dto.put("merchantKey", ComCode.INTEGRAL_MERCHANT_KEY);//商户key
        dto.put("timestamp", System.currentTimeMillis());//时间戳
        JSONObject jsonObject = juHeZhongPayIntegralService.quickPayHandle(dto);
        System.out.println(jsonObject.toJSONString());
        if(!"0000".equals(jsonObject.get("code"))){
            throw new MyException();
        }

    }
    /**
     * JuHeZhong支付用户费率
     * @param rateEntity
     * @return
     * @throws MyException
     * @throws Exception
     */
    public void merchantFeelJFen(String subMchId, RateEntity rateEntity) throws MyException, Exception {
        logger.debug("进入增加或修改支付用户费率开始");
        // 修改费率
        JSONObject dto = new JSONObject();
        dto.put("subMchId",subMchId);
        dto.put("paymentType","QUICKPAY");
        dto.put("d0Fee",rateEntity.getRate());
        dto.put("d1Fee",rateEntity.getRate());
        JSONObject jsonObject = null;
        if("1".equals(rateEntity.getServiceType())){
            jsonObject = juHeZhongPayJFenService.merchantModifyFeel(dto);
        }else {
            logger.debug("进入到增加费率");
            jsonObject = juHeZhongPayJFenService.merchantAddFeel(dto);
        }

        if (!"0000".equals(jsonObject.getString("code"))) {
            logger.debug("增加或修改用户费率失败, jsonObject: {}",jsonObject);
            throw new MyException(jsonObject.getString("msg"));
        }
        logger.debug("增加或修改用户费率结束");
    }

    /**
     * 修改JuHeZhong支付用户费率
     *
     * @param cardEntity
     * @param rateEntity
     * @return
     * @throws MyException
     * @throws Exception
     */
    public void updateRateJuHeZhongPay(CardEntity cardEntity, RateEntity rateEntity) throws MyException, Exception {
        // 修改费率
        MerchantDto dto = new MerchantDto();
        dto.setMerchantId(ComCode.MERCHANT_ID);
        dto.setSubMchId(cardEntity.getSubMerchantId());
        dto.setOrderId(IdGen.uuid());//不会产生交易订单
        dto.setSettleRate(new BigDecimal(rateEntity.getRate()));
        dto.setExtraRate(new BigDecimal(ComCode.EXTRA_RATE));
        dto.setTimestamp(System.currentTimeMillis());
        dto.setMerchantKey(ComCode.MERCHANT_KEY);
        JSONObject jsonObject = juHeZhongPayService.updateRate(dto);
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));
        }
    }

    /**
     * 修改JuHeZhong支付用户结算信息
     *
     * @param cardEntity
     * @return
     * @throws MyException
     * @throws Exception
     */
    public void updateSettleJuHeZhongPay(CardEntity cardEntity) throws Exception {
        // 修改费率
        MerchantDto dto = new MerchantDto();
        dto.setMerchantId(ComCode.MERCHANT_ID);
        dto.setSubMchId(cardEntity.getSubMerchantId());
        dto.setOrderId(IdGen.uuid());//不会产生交易订单
        dto.setAccType(Integer.parseInt(cardEntity.getType()));//1 对私 2对公
        dto.setAccNo(cardEntity.getCardNo());
        dto.setAccProvince(cardEntity.getProvince());
        dto.setAccCity(cardEntity.getCity());
        dto.setBankCode(cardEntity.getBelongBank());
        dto.setMobile(cardEntity.getCardMobile());
        dto.setTimestamp(System.currentTimeMillis());
        dto.setMerchantKey(ComCode.MERCHANT_KEY);
        JSONObject jsonObject = juHeZhongPayService.updateSettle(dto);
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));
        }
    }


    public RateEntity getRateByLevel(RateEntity rateEntityParam){
        return userDao.getRateByLevel(rateEntityParam);
    }

    public CardEntity getDebitCardByUserCode(UserRequest request){
        return userDao.getDebitCardByUserCode(request);
    }

    public CardEntity getDebitCardByUserCode(String  code){
        UserRequest request = new UserRequest();
        request.setSubMerchantCode(code);
        return userDao.getDebitCardByUserCode(request);
    }


    @Transactional(readOnly = false)
    public void updateUser(UserRequest request){
        if(StringUtils.isNotBlank(request.getAvatar())){
            request.setAvatar(StringUtils.replace(request.getAvatar(),Global.getConfig("image.save.url"),""));
        }
        userDao.updateUser(request);
    }

    public List<RateEntity> getRateListByLevel(RateEntity rateEntityParam){
	    List < RateEntity > rateListByLevel = userDao.getRateListByLevel ( rateEntityParam );
	    for ( RateEntity rateEntity : rateListByLevel ) {
		    String singlePrice = " + 0元";
		    if ( StringUtils.isNotBlank ( rateEntity.getSiglePrice ( ) ) ) {
			    singlePrice = " + " + rateEntity.getSiglePrice ( ) + "元";
		    }
		    if ( StringUtils.isNotBlank ( rateEntity.getRate ( ) ) ) {
			    DecimalFormat decimalFormat = new DecimalFormat ( "##0.00" );
			    rateEntity.setRate ( decimalFormat.format ( Float.parseFloat ( rateEntity.getRate ( ) ) * 100 ) + "%" + singlePrice );
		    } else {
			    rateEntity.setRate ( "0.00%" + singlePrice );
		    }
	    }
	    return rateListByLevel;
    }

    public Level getLevelByUserLevel(UserRequest request){
        return userDao.getLevelByUserLevel(request);
    }

    public void addUserSubmchid(UserSubMchId userSubMchId){
        userDao.addUserSubmchid(userSubMchId);
    }

    public UserSubMchId getUserSubmchid(UserSubMchId userSubMchId){
        return userDao.getUserSubmchid(userSubMchId);
    }


    public int updateUserSubmchid(UserSubMchId userSubMchId){
       return userDao.updateUserSubmchid(userSubMchId);
    }

    public BelongBankEntity getBelongBankEntity(String belongBank){
        UserRequest request = new UserRequest();
        request.setBelongBank(belongBank);
        return userDao.getBelongBankEntity(request);
    }

    public CardEntity getCardByCardNo(String cardNo){
        CardEntity cardEntity = new CardEntity();
        cardEntity.setCardNo(cardNo);
        return userDao.getCardByCardNo(cardEntity);
    }

    public int addSwpaccid(CardSwpaccidEntity entity){
        return userDao.addSwpaccid(entity);
    }

    public CardSwpaccidEntity getSwpaccid(CardSwpaccidEntity cardSwpaccidEntity){
        return userDao.getSwpaccid(cardSwpaccidEntity);
    }

    public UserDetailEntity getUserDetailByCode(String userCode){
        UserEntity userEntity = new UserEntity();
        userEntity.setCode(userCode);
        return userDao.getUserDetailByCode(userEntity);
    }

    public List<BelongBankEntity> getBelongBankByPayChannel(String payChannel){

        UserRequest request = new UserRequest();
        request.setPayChannel(payChannel);

        return userDao.getBelongBankByPayChannel(request);
    }

    public CardEntity getCardInfoByCode(UserEntity userEntity) {
        return userDao.getCardInfoByCode(userEntity);

    }

    public void updateUserLevelByCode(UserEntity recommendedUser){
        userDao.updateUserLevelByCode(recommendedUser);
    }

    // 添加 待升级王者的用户记录表
    public Integer addUpgradeUser(UpgradeUserEntity upgradeUserEntity){
        upgradeUserEntity.setCreated(DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        upgradeUserEntity.setCreatedUser("sys");
        upgradeUserEntity.setModified(DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        upgradeUserEntity.setModifiedUser("sys");

        return userDao.addUpgradeUser(upgradeUserEntity);
    }

    // 更新 待升级王者的用户记录表
    public Integer updateUpgradeUser(UpgradeUserEntity upgradeUserEntity){
        upgradeUserEntity.setModified(DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        upgradeUserEntity.setModifiedUser("sys");

        return userDao.updateUpgradeUser(upgradeUserEntity);
    }

    //获取邀请的好友列表
    public List<UserEntity> getMyInviting(UserRequest request) {
//        List<UserEntity> list = userDao.getMyInviting(request);
        return userDao.getMyInviting(request);
    }

    //获取已激活数量
    public Integer getActiveNum(UserRequest request){
        return userDao.getActiveUserNum(request);
    }

    //定时任务
    public void updateUserLevel(){
        logger.debug("修改用户等级的定时任务开始执行");
//        满足条件：
//              1，青铜用户；2，推荐人数大于2个；3，每个被推荐人交易金额大于1万
        //获得符合前两个条件的推荐人
        List<UserEntity> list = userDao.getUserLevelIsE();
        for(UserEntity entity : list){
            Integer matchNum = userDao.getMatchNum(entity.getMobile());
            logger.debug("用户mobile: {} ,符合条件的数量: {}",entity.getMobile(),matchNum);
            if(matchNum > 2){
//                修改等级，青铜（E）到白银（D）
                entity.setLevel("D");
                userDao.updateUserLevelByCode(entity);
//                HL2通道不稳定，暂时关闭
//                关系到HL2通道，修改费率
//                try {
//                    timeUpdateRateHL2(entity);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    logger.debug("定时修改费率出错！");
//                }
            }
        }

        logger.debug("修改用户等级的定时任务执行结束");
    }

    //增加或者修改HL2通道费率
    public void timeUpdateRateHL2(UserEntity entity) throws Exception {
              UserSubMchId userSubMchId = new UserSubMchId();
                    userSubMchId.setUserCode(entity.getCode());
                    userSubMchId.setPayChannel("quick_jfen");

                    UserSubMchId userSubMchIdQuery = userDao.getUserSubmchid(userSubMchId);
                    RateEntity rate = new RateEntity();
                    rate.setUserLevel(entity.getLevel());
                    rate.setPayChannel("quick_jfen");
                    rate.setPayMethod("quick");
                    RateEntity rateEntity = userDao.getRateByLevel(rate);
            // 如果推荐人的 quick_jfen 通道下的 subMchId 是空 则该通道下先注册，存在则修改费率
                    if(userSubMchIdQuery == null){
                        entity = this.getUserDetailInfo(entity);
                        JSONObject dto = new JSONObject();

                        String orderId = MakeOrderNum.makeOrderNum();
                        dto.put("orderId", MakeOrderNum.makeOrderNum());
                        dto.put("serviceType",1);
                        dto.put("subMerchantName",entity.getUserDetail().getRealName()+orderId);
                        dto.put("subMerchantType","PERSON");
                        dto.put("businessLicense",entity.getUserDetail().getRealName()+orderId);
                        dto.put("legalPersonName",entity.getUserDetail().getRealName());
                        dto.put("legalPersonID",entity.getUserDetail().getIdCard());
                        dto.put("subMerchantPersonName",entity.getUserDetail().getRealName());
                        dto.put("subMerchantPersonPhone",entity.getMobile());
                        dto.put("bankType","TOPRIVATE");

                        dto.put("accountName",entity.getUserDetail().getRealName());
                        dto.put("accountNo",entity.getUserDetail().getCard().getCardNo());
                        dto.put("bankName",entity.getUserDetail().getCard().getBankName());
                        dto.put("bankProv",entity.getUserDetail().getCard().getProvince());
                        dto.put("bankCity",entity.getUserDetail().getCard().getCity());
                        dto.put("bankBranch",entity.getUserDetail().getCard().getCardPlace());
                        dto.put("bankCode",entity.getUserDetail().getCard().getBelongBank());

                        dto.put("timestamp",System.currentTimeMillis());

                        JSONObject jsonObject =  juHeZhongPayJFenService.merchantIn(dto);
                        if (!"0000".equals(jsonObject.getString("code"))) {
                            throw new MyException(jsonObject.getString("msg"));
                        }
                        
                        String subMchId = jsonObject.getString("subMchId");
                        userSubMchIdQuery = new UserSubMchId();
                        userSubMchIdQuery.setUserCode(entity.getCode());
                        userSubMchIdQuery.setPayChannel(rateEntity.getPayChannel());
                        userSubMchIdQuery.setSubmchid(subMchId);
                        rateEntity.setServiceType("0");// 添加费率
                        this.addUserSubmchid(userSubMchIdQuery);
                        this.merchantFeelJFen(subMchId,rateEntity);
                    }else{
                        // 修改费率
                        rateEntity.setServiceType("1");
                        this.merchantFeelJFen(userSubMchIdQuery.getSubmchid(),rateEntity);
                    }
    }

    //获取银行卡类型，非空则银行卡正确，返回银行卡类型
    private String checkCardNum(String cardNum){
        String cardDetail = getCardDetailByAli(cardNum);
        JSONObject parse = (JSONObject) JSONObject.parse(cardDetail);
        if(parse.get("validated").equals(true)){
            return parse.get("cardType").toString();
        }
        logger.debug("银行卡校验失败： {}",parse.get("messages"));
        return "";

    }

    public static String getCardDetailByAli(String cardNo) {
        String urls = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=%s&cardBinCheck=true";
        String url = String.format(urls, cardNo);
        StringBuilder sb = new StringBuilder();
        try {
            URL urlObject = new URL(url);
            URLConnection uc = urlObject.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
            String inputLine = null;
            while ( (inputLine = in.readLine()) != null) {
                sb.append(inputLine);
            }
            in.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public List<LevelDetail> getLevelDetail(){
        List<LevelDetail> levels = userDao.getLevelDetail();
        return levels;
    }

    public LevelDetail getLevelDetailByLevel(UserRequest request) {
        return userDao.getLevelDetailByLevel(request);
    }
}
