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.IdGen;
import com.thinkgem.jeesite.common.utils.MD5;
import com.thinkgem.jeesite.modules.commonError.MyException;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.MerchantDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayService;
import com.thinkgem.jeesite.modules.pay.entity.RateEntity;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 前端用户相关
 */
@Service
@Transactional(readOnly = true)
public class UserApiService {

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

    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) {
        // 生成验证码
        String identifyCode = IdGen.randomBase62(6).toUpperCase();
        // TODO 发送验证码
        // 验证码入库
        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);
    }

    @Transactional(readOnly = false)
    public UserEntity signUp(UserRequest request) {
        // 保存用户信息
        String code = IdGen.randomBase62(64);
        UserEntity recommend = userDao.checkRecommend(request);
        UserEntity userEntity = new UserEntity(code, "", request.getMobile(), MD5.sign(request.getNewPassword(), ComCode.signCode, "utf-8"), request.getRecommendedMobile(), 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);
        } 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;
    }

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

    @Transactional(readOnly = false)
    public void addNewCard(UserRequest request) throws MyException, Exception {
        String code = IdGen.randomBase62(64);
        String type = "1"; // 默认将卡片添加为对私
        String status = "0"; // 新增卡片审核状态均为未审核
        String subMerchantId = registJuHeZhongPay(request, type);
        CardEntity cardEntity = new CardEntity(code, request.getSubMerchantCode(), request.getCardType(), request.getCardNo(), request.getCardMobile(), request.getBelongBank(), request.getCardBank(), request.getCardPlace(), "N", subMerchantId, request.getCardSrc().replace(Global.getConfig("sys.pre.url"), ""), 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 {
        // 更新用户详情
        UserDetailEntity userDetailEntity = new UserDetailEntity(IdGen.randomBase62(64), request.getSubMerchantCode(), request.getRealName(), request.getIdCard(), request.getIdCardPlace(), request.getIdCardFront().replace(Global.getConfig("sys.pre.url"), ""), request.getIdCardBack().replace(Global.getConfig("sys.pre.url"), ""), request.getIdCardHold().replace(Global.getConfig("sys.pre.url"), ""), request.getDebitCard().replace(Global.getConfig("sys.pre.url"), ""));
        if (userDao.getUserDetailByCode(new UserEntity(request.getSubMerchantCode())) == null) {
            userDao.saveUserDetail(userDetailEntity);
        } else {
            userDao.updateUserDetail(userDetailEntity);
        }
        // 为用户卡注册subMerchantId
        String type = "1"; // 默认将卡片添加为对私
        String status = "0"; // 新增卡片审核状态均为未审核
        String subMerchantId = registJuHeZhongPay(request, type);
        // 更新银行卡详情
        CardEntity cardStatusEntity = new CardEntity(request.getSubMerchantCode(), "N");
        userDao.updateCardStatus(cardStatusEntity);
        CardEntity cardEntity = new CardEntity(IdGen.randomBase62(64), request.getSubMerchantCode(), "D", request.getCardNo(), request.getCardMobile(), request.getBelongBank(), request.getCardBank(), request.getCardPlace(), "Y", subMerchantId, request.getCardSrc().replace(Global.getConfig("sys.pre.url"), ""), type, status, request.getProvince(), request.getCity());
        userDao.addNewCard(cardEntity);
        // 更新用户状态
        UserEntity userEntity = new UserEntity();
        userEntity.setCode(request.getSubMerchantCode());
        userEntity.setStatus("1");
        userDao.updateUserInfo(userEntity);
        // 查询与实名用户相同推荐人的信息
        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]);
            recommendedUser.setLevel("D");
            // 实名用户的推荐人等级由E（青铜）升为D（白银）
            userDao.updateUserLevel(recommendedUser);
            // 修改实名用户推荐人的银行卡费率
            RateEntity rateEntityParam = new RateEntity("D", "quick");
            RateEntity rateEntity = userDao.getRateByLevel(rateEntityParam);
            List<CardEntity> recommendCards = userDao.getRecommendCardsInfo(recommendedUser);
            for (CardEntity entity : recommendCards) {
                updateRateJuHeZhongPay(entity, 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");
    }

    /**
     * 修改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);
    }



    @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);
    }
}
