package cn.com.ty.lift.ud.userInfo.service.impl;

import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.model.PushMessage;
import cn.com.ty.lift.common.model.PushUserInfo;
import cn.com.ty.lift.ud.applyExpert.mapper.ApplyExpertMapper;
import cn.com.ty.lift.ud.applyExpert.mapper.entity.ApplyExpert;
import cn.com.ty.lift.ud.appmenu.mapper.entity.Appmenu;
import cn.com.ty.lift.ud.appmenu.service.IAppuserMenuService;
import cn.com.ty.lift.ud.common.RandomizingID;
import cn.com.ty.lift.ud.company.service.ICompanyService;
import cn.com.ty.lift.ud.dataBank.mapper.entity.LiftBrandEntity;
import cn.com.ty.lift.ud.dataBank.mapper.entity.LiftCertificateEntity;
import cn.com.ty.lift.ud.dataBank.service.ILiftBrandService;
import cn.com.ty.lift.ud.dataBank.service.ILiftCertificateService;
import cn.com.ty.lift.ud.expertComment.mapper.entity.ExpertCommentEntity;
import cn.com.ty.lift.ud.expertComment.mapper.entity.ScoreInfo;
import cn.com.ty.lift.ud.expertComment.service.IExpertCommentService;
import cn.com.ty.lift.ud.expertPunish.mapper.entity.ExpertsPunishment;
import cn.com.ty.lift.ud.expertPunish.service.IExpertsPunishmentService;
import cn.com.ty.lift.ud.maintenanceCompany.mapper.entity.MaintenanceCompanyEntity;
import cn.com.ty.lift.ud.maintenanceCompany.service.IMaintenanceCompanyService;
import cn.com.ty.lift.ud.operation.mapper.entity.OtherSettingEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.UserLevelRuleEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.UserRebateRuleEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.VipFeeSettingEntity;
import cn.com.ty.lift.ud.operation.service.IOtherSettingService;
import cn.com.ty.lift.ud.operation.service.IUserLevelRuleService;
import cn.com.ty.lift.ud.operation.service.IUserRebateRuleService;
import cn.com.ty.lift.ud.operation.service.IVipFeeSettingService;
import cn.com.ty.lift.ud.payment.mapper.UserBillMapper;
import cn.com.ty.lift.ud.payment.mapper.entity.UserBillEntity;
import cn.com.ty.lift.ud.payment.service.IUserBillService;
import cn.com.ty.lift.ud.userAccount.mapper.entity.UserAccount;
import cn.com.ty.lift.ud.userAccount.service.IUserAccountService;
import cn.com.ty.lift.ud.userCoupon.mapper.entity.UserCoupon;
import cn.com.ty.lift.ud.userCoupon.service.IUserCouponService;
import cn.com.ty.lift.ud.userInfo.controller.query.UserInfoQuery;
import cn.com.ty.lift.ud.userInfo.mapper.UserInfoMapper;
import cn.com.ty.lift.ud.userInfo.mapper.entity.*;
import cn.com.ty.lift.ud.userInfo.service.IUserInfoService;
import cn.com.ty.lift.ud.userRebate.mapper.entity.UserRebateEntity;
import cn.com.ty.lift.ud.userRebate.service.IUserRebateService;
import cn.com.ty.lift.ud.utils.BaiduDistance;
import cn.com.ty.lift.ud.utils.PasswordUtils;
import cn.com.ty.lift.ud.utils.PingYinUtil;
import cn.com.ty.lift.ud.utils.QrCodeUtil;
import cn.com.xwy.boot.web.dto.RestResponse;
import cn.com.xwy.util.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户表 -ServiceImpl
 *
 * @author Xson
 * @date 2020-05-09
 */
@Service
@Transactional
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfoEntity> implements IUserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private IUserAccountService iUserAccountService;

    @Autowired
    private IUserLevelRuleService iUserLevelRuleService;

    @Autowired
    private ICompanyService iCompanyService;

    @Autowired
    private IExpertCommentService iExpertCommentService;

    @Autowired
    private IOtherSettingService iOtherSettingService;

    @Autowired
    private UserBillMapper userBillMapper;

    @Autowired
    private ILiftCertificateService iLiftCertificateService;

    @Autowired
    private IMaintenanceCompanyService iMaintenanceCompanyService;

    @Autowired
    private IUserCouponService iUserCouponService;

    @Autowired
    private ILiftBrandService iLiftBrandService;

    @Autowired
    private IUserRebateRuleService iUserRebateRuleService;

    @Autowired
    private IExpertsPunishmentService iExpertsPunishmentService;

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    private @Autowired
    IAppuserMenuService appUserMenuService;
    
    @Autowired
    private ApplyExpertMapper applyExpertMapper;

    @Override
    public UserInfoEntity getByUserId(Long id) {
        UserInfoEntity userInfo = userInfoMapper.getUserInfo(id);
        ApplyExpert byUserId = applyExpertMapper.getByUserId(id);
        StringBuilder proficiencyBrandName = new StringBuilder("");
        if (null != userInfo) {
            // 显示擅长品牌中文名称
            String proficiencyBrand = userInfo.getProficiencyBrand();
            if (StringUtils.isNotBlank(proficiencyBrand)) {
                String[] stringsArray = proficiencyBrand.split(",");
                for (int k = 0; k < stringsArray.length; k++) {
                    LiftBrandEntity entity = iLiftBrandService.getById(Integer.parseInt(stringsArray[k]));
                    if (null != entity) {
                        String name = entity.getName();
                        proficiencyBrandName = proficiencyBrandName.append(name + ",");
                    }
                }
            }
            userInfo.setProficiencyBrandName(proficiencyBrandName.toString());
            // 如果是专家，显示专家
            UserAccount oneById = iUserAccountService.getOneById(id);
            if (null != oneById && oneById.getExpertFlag() == 1) {
                // 只要是专家，身份就显示为专家
                userInfo.setRoleName("专家");
                userInfo.setUserLevelName("专家");
            }
            if(byUserId != null) {
                userInfo.setAddress(byUserId.getResidentPlace());
                userInfo.setWorkDate(byUserId.getWorkDate());
                userInfo.setIntroduction(byUserId.getName()+"，专业："+byUserId.getProfessional()+"，"+userInfo.getProficiency());
                userInfo.setExperience(byUserId.getWorkExperience());
            }
            
            ScoreInfo scoreInfo = iExpertCommentService.getScoreByExpertId(userInfo.getUserId());
            if(null != scoreInfo){
                //计算平均分，向上取整
                int averageScore = (int)Math.ceil((double)scoreInfo.getTotalScore()/scoreInfo.getNum());
                userInfo.setAverageScore(averageScore);
            }else{
                userInfo.setAverageScore(0);
            }
            
            List<ExpertCommentEntity> commentByUserId = iExpertCommentService.getCommentByUserId(userInfo.getUserId());
            if(commentByUserId != null) {
                userInfo.setHaveComment(1);
            }else {
                userInfo.setHaveComment(0);
            }
        }

        return userInfo;
    }

    @Autowired
    private IVipFeeSettingService vipFeeSettingService;

    @Autowired
    private IUserRebateService iUserRebateService;

    @Autowired
    private IUserBillService iUserBillService;

    /**
     * 获取个人信息
     *
     * @param id
     */
    @Override
    public RestResponse getUserInfo(Long id) {
        // 查询账户信息 user_account
        UserAccount userAccount = iUserAccountService.getOneById(id);
        // 查询用户信息 user_info
        UserInfoEntity userInfoEntity = userInfoMapper.getByUserId(id);
        if (userAccount == null || userInfoEntity == null) {
            return RestResponse.fail("用户信息不存在");
        }
        // 查询公司信息
        MaintenanceCompanyEntity mcEntity =
            iMaintenanceCompanyService.getById(userInfoEntity.getMaintenanceCompanyId());
        // 查询操作证信息
        LiftCertificateEntity liftCertificateEntity = iLiftCertificateService.getByOwnerId(userInfoEntity.getUserId());
        // 组装
        DetailUserInfoVo detailUserInfoVo = new DetailUserInfoVo();
        detailUserInfoVo.setAvatarUrl(userInfoEntity.getAvatarUrl());
        detailUserInfoVo.setMobile(userInfoEntity.getMobile());
        detailUserInfoVo.setName(userInfoEntity.getName());
        detailUserInfoVo.setRealName(userInfoEntity.getRealName());
        detailUserInfoVo.setProficiencyBrand(userInfoEntity.getProficiencyBrand());
        detailUserInfoVo.setSignature(userInfoEntity.getSignature());
        detailUserInfoVo.setUserId(userInfoEntity.getUserId());
        // 操作证信息
        if (null != liftCertificateEntity) {
            detailUserInfoVo.setStatuz(liftCertificateEntity.getStatuz());
        }
        // 公司信息
        if (null != mcEntity) {
            detailUserInfoVo.setCompanyName(mcEntity.getName());
        }
        return RestResponse.success(detailUserInfoVo, "查询成功");

    }

    /**
     * 附近的人
     *
     * @param userInfoDto
     * @return
     */
    @Override
    public RestResponse getNearUser(UserInfoDto userInfoDto) {
        double nearPeopleArea = 100;
        List<UserInfoVo> userList = new ArrayList<>();
        // 查询其他设置里面的 附近的人范围设置
        RestResponse latestVersion = iOtherSettingService.getLatestVersion();
        OtherSettingEntity data = (OtherSettingEntity)latestVersion.getData();
        if (null != data && data.getNearPeopleArea() != null) {
            nearPeopleArea = data.getNearPeopleArea();
        }

        // 更新用户坐标到数据库中
        if (null != userInfoDto.getUserId()) {
            UserInfoEntity updateEntity = new UserInfoEntity();
            updateEntity.setLat(userInfoDto.getLat());
            updateEntity.setLon(userInfoDto.getLon());
            userInfoMapper.update(updateEntity, new QueryWrapper<UserInfoEntity>().eq("user_id", userInfoDto.getUserId()));
        }

        // 查询附近的人
        List<UserInfoVo> nearUserList = userInfoMapper.getNearUser(userInfoDto);
        if (ListUtil.isNotEmpty(nearUserList)) {
            // 去掉范围之外的人和自己
            for (UserInfoVo userInfoVo : nearUserList) {
                if (userInfoVo.getDistance() != null && userInfoVo.getDistance() < nearPeopleArea * 1000
                    && !userInfoVo.getUserId().equals(userInfoDto.getUserId())) {
                    userList.add(userInfoVo);
                }
            }
            return RestResponse.success(userList, "获取附近的人成功");
        } else {
            return RestResponse.fail(null, "暂无数据");
        }
    }

    @Override
    public RestResponse listExpert(UserInfoQuery query) {
        IPage page = query.page();
        List<UserInfoEntity> list = userInfoMapper.selectByQuery(query.condition(), query);
        //计算评论平均分
        if(ListUtil.isNotEmpty(list)){
            for(UserInfoEntity user : list){
                ScoreInfo scoreInfo = iExpertCommentService.getScoreByExpertId(user.getUserId());
                if(null != scoreInfo){
                    //计算平均分，向上取整
                    int averageScore = (int)Math.ceil((double)scoreInfo.getTotalScore()/scoreInfo.getNum());
                    user.setAverageScore(averageScore);
                }else{
                    user.setAverageScore(0);
                }

            }
        }
        //计算距离
        if (query.getLat() != null && query.getLng() != null) {
            for (UserInfoEntity le : list) {
                //计算与专家的距离
                double getShortDistance = BaiduDistance.GetShortDistance(query.getLng(),query.getLat(), le.getLon(), le.getLat());
                le.setDistance(getShortDistance);
            }
            List<UserInfoEntity> collect = list.stream().sorted(Comparator.comparing(UserInfoEntity::getDistance)).collect(Collectors.toList());
            page.setRecords(collect);
        }else {
            page.setRecords(list);
        }
        int total = userInfoMapper.countByQuery(query.condition());
        page.setTotal(total);
        return RestResponse.success(page, "Queried successfully");
    }

    @Override
    public RestResponse addExpert(UserInfoEntity userInfoEntity) {
        List<UserInfoEntity> byMobile = userInfoMapper.getByMobile(userInfoEntity.getMobile());
        if (!byMobile.isEmpty()) {
            return RestResponse.success(null, "手机号重复");
        }

        UserAccount userAccount = new UserAccount();
        userAccount.setAccount(userInfoEntity.getMobile());
        userAccount.setSalt(PasswordUtils.randomCode());
        userAccount.setPassword(PasswordUtils.generatePassword("123456", userAccount.getSalt()));
        userAccount.setMobile(userInfoEntity.getMobile());
        userAccount.setStatus(1);
        userAccount.setExpertFlag(1);
        userAccount.setType(3);
        userAccount.setCreateDate(new Date());
        iUserAccountService.save(userAccount);
        
        userInfoEntity.setShowWhichName(1);
        userInfoEntity.setUserId(userAccount.getUserId());
        userInfoEntity.setPlatformInvitedFlag(1);
        userInfoEntity.setUserLevel(4L);
        userInfoEntity.setUserLevelName("专家");
        userInfoEntity.setExpertLevel(1);
        userInfoEntity.setStatuz(1);
        int code = (int)(((Math.random() * 9) + 1) * 100000);
        String qrCodeurl = null;
        try {
            qrCodeurl = QrCodeUtil.getQrCode(userAccount.getUserId(), "/wode/vip");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        userInfoEntity.setRequestCode(code);
        userInfoEntity.setQrCodeUrl(qrCodeurl);

        userInfoMapper.insert(userInfoEntity);
        return RestResponse.success(null, "保存专家信息成功");
    }

    /**
     * 新增用户
     *
     * @param userRequest
     * @return
     */
    @Override
    public RestResponse addUser(UserRequest userRequest) {
        List<UserInfoEntity> byMobile = userInfoMapper.getByMobile(userRequest.getMobile());
        if (!byMobile.isEmpty()) {
            return RestResponse.success(null, "手机号重复");
        }
        // 设置用户账户表信息
        String password = userRequest.getPassword();
        UserAccount userAccount = new UserAccount();
        userAccount.setMobile(userRequest.getMobile());
        // 设置账号(小梯号)
        userAccount.setAccount(userRequest.getAccount());
        // 设置用户类型
        userAccount.setType(ApiConstants.UserConstants.TYPE_USER);
        // 设置用户微信openId
        userAccount.setWechatOpenId(userRequest.getWeChatOpenId());
        userAccount.setStatus(1);
        userAccount.setExpertFlag(0);
        userAccount.setType(3);
        userAccount.setDeleteFlag(0);

        // 设置用户表信息
        UserInfoEntity userInfo = new UserInfoEntity();
        userInfo.setMobile(userRequest.getMobile());
        userInfo.setName(userRequest.getName());

        // 前端传递MD5加密密码，然后进行密码加密
        // 1.生成16位随机码
        String salt = PasswordUtils.randomCode();
        // 2.对密码进行加盐处理，并对加盐的密码进行哈希加密
        password = PasswordUtils.generatePassword(password, salt);
        userAccount.setSalt(salt);
        userAccount.setPassword(password);

        // 保存用户账户
        boolean insertAccountFlag = iUserAccountService.save(userAccount);
        // 保存用户信息
        userInfo.setUserId(userAccount.getUserId());
        userInfo.setDeleteFlag(0);
        userInfo.setShowWhichName(1);
        userInfo.setVipFlag(1);
        int insertInfoFlag = userInfoMapper.insert(userInfo);
        if (!insertAccountFlag || insertInfoFlag == 0) {
            return null;
        }
        return RestResponse.success(userAccount, "新增用户成功");
    }

    /**
     * 冻结用户
     *
     * @param ids
     * @return
     */
    @Override
    public RestResponse deleteUser(List<Long> ids) {
        for (Long id : ids) {
            UserInfoEntity entity = userInfoMapper.getByUserId(id);
            if (null != entity) {
                // 删除 user_account 账户信息
                iUserAccountService.deleteAccount(entity.getUserId());
                // 删除 user_info 用户信息
                userInfoMapper.deleteUserInfo(id);
            } else {
                return RestResponse.fail("当前用户不存在:" + id);
            }

        }
        return RestResponse.success(null, "冻结用户成功");

    }

    /**
     * 修改用户信息
     *
     * @param userInfoEntity
     * @return
     */
    @Override
    public RestResponse updateUser(UserInfoEntity userInfoEntity) {
        // 修改 user_info 用户信息
        Integer integer = userInfoMapper.updateUserInfo(userInfoEntity);
        if (integer == 1) {
            return RestResponse.success(null, "修改成功");
        } else {
            return RestResponse.fail("修改失败");
        }
    }

    /**
     * 用户列表
     *
     * @param query
     * @return
     */
    @Override
    public RestResponse listUser(UserInfoQuery query) {
        IPage page = query.page();
        List<UserInfoEntity> list = userInfoMapper.selectUserList(query.condition(), query);
        if (ListUtil.isNotEmpty(list)) {
            for (UserInfoEntity userInfoEntity : list) {
                UserAccount oneById = iUserAccountService.getOneById(userInfoEntity.getUserId());
                if (null != oneById && oneById.getExpertFlag() == 1) {
                    // 只要是专家，身份就显示为专家
                    userInfoEntity.setRoleName("专家");
                }
            }
        }
        int total = userInfoMapper.countUserList(query.condition());
        page.setRecords(list);
        page.setTotal(total);
        return RestResponse.success(page, "查询成功");

    }

    /**
     * 修改专家总积分
     *
     * @param nowTotalScore
     *            总积分
     */
    @Override
    public void addExpertScore(Integer nowTotalScore, Long expertId, Integer expertLevel) {
        userInfoMapper.addExpertScore(nowTotalScore, expertId, expertLevel);
    }

    /**
     * 后台升级为会员
     *
     * @param urEntity
     * @return
     */
    @Override
    public RestResponse toVip(UserVipDto urEntity) {
        if (null == urEntity.getUserLevelId()) {
            return RestResponse.fail("vip角色ID不能为空");
        }
        VipFeeSettingEntity entity =
            vipFeeSettingService.getByPeriodAndLevel(urEntity.getPeriod(), urEntity.getUserLevelId());
        if (null == entity) {
            return RestResponse.fail("当前有效期的会员类型不存在，请添加");
        }
        if (null == urEntity.getPeriod()) {
            return RestResponse.fail("有效期不能为空");
        }
        UserLevelRuleEntity personVip = iUserLevelRuleService.getById(urEntity.getUserLevelId());
        UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
        UserAccount userAccount = iUserAccountService.getOneById(urEntity.getUserId());
        if (null != personVip && null != userAccount) {
            // 后台升级为会员，生成邀请码和二维码
            Integer code = (int)(((Math.random() * 9) + 1) * 100000);
            LocalDateTime vipStartTime = LocalDateTime.now();
            LocalDateTime vipEndTime = LocalDateTime.now().plusMonths(urEntity.getPeriod());
            if (userAccount.getExpertFlag() == 1) {
                // 专家,如果是专家，user_level_name 显示专家，user_level 保存会员角色ID
                userInfoMapper.toVip(personVip.getId(), expert.getName(), code, vipStartTime, vipEndTime,
                    urEntity.getPeriod(), entity.getId(), urEntity.getUserId());
            } else {
                // 不是专家
                userInfoMapper.toVip(personVip.getId(), personVip.getName(), code, vipStartTime, vipEndTime,
                    urEntity.getPeriod(), entity.getId(), urEntity.getUserId());
            }
            // 后台生成二维码，流化后上传到阿里云服务器
            try {
                String qrCodeurl = QrCodeUtil.getQrCode(urEntity.getUserId(), "/wode/vip");
                // 二维码
                UserInfoEntity userInfo = new UserInfoEntity();
                userInfo.setUserId(urEntity.getUserId());
                userInfo.setQrCodeUrl(qrCodeurl);
                userInfoMapper.updateUserInfo(userInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return RestResponse.success(null, "升级成功");
        } else {
            return RestResponse.fail("会员角色等级设置有误，请检查");

        }

    }

    /**
     * 判断当前用户是否可以升级为vip
     *
     * @param userId
     *            userId
     * @return
     */
    @Override
    public RestResponse toWhichVip(Long userId) {
        // 查询个人信息，判断角色
        UserInfoEntity entity = userInfoMapper.getByUserId(userId);
        if (null != entity) {
            // 非vip
            if (null != entity.getVipFlag() && entity.getVipFlag() == 1) {
                List<UserLevelRuleEntity> vipUserList = iUserLevelRuleService.getVipUserLevel();
                return RestResponse.success(vipUserList, "查询成功");
            } else {
                // vip用户
                return RestResponse.success(null, "查询成功");
            }
        } else {
            return RestResponse.fail("当前用户不存在");
        }

    }

    /**
     * 后台取消会员
     *
     * @param userLevelDto
     * @return
     */
    @Override
    public RestResponse cancelVip(UserLevelDto userLevelDto) {
        if (null != userLevelDto.getUserId()) {
            if (null == userLevelDto.getMaintenanceCompanyId()) {
                // 个人vip用户，如果是专家，user_level_name 显示专家，user_level 保存 普通用户的角色ID ，变成个人普通用户
                UserLevelRuleEntity person = iUserLevelRuleService.getByCode("PERSON");
                cancel(userLevelDto, person);
                return RestResponse.success(null, "取消成功");
            } else {
                // 有企业的vip，如果是专家，user_level_name 显示专家，user_level 保存 普通用户的角色ID ，变成企业普通用户
                UserLevelRuleEntity company = iUserLevelRuleService.getByCode("COMPANY");
                cancel(userLevelDto, company);
                return RestResponse.success(null, "取消成功");
            }
        } else {
            return RestResponse.fail("缺少用户ID或者app角色ID");
        }
    }

    private void cancel(UserLevelDto userLevelDto, UserLevelRuleEntity entity) {
        UserAccount userAccount = iUserAccountService.getOneById(userLevelDto.getUserId());
        UserLevelRuleEntity expert = null;
        if (userAccount.getExpertFlag() == 1) {
            expert = iUserLevelRuleService.getByCode("EXPERT");
            // 专家
            if (null != expert) {
                userInfoMapper.cancelVip(userLevelDto.getUserId(), entity.getId(), LocalDateTime.now(), expert.getName());
            } else {
                log.info("专家角色不存在");
            }
        } else {
            // 不是专家
            if (null != entity) {
                userInfoMapper.cancelVip(userLevelDto.getUserId(), entity.getId(), LocalDateTime.now(), entity.getName());
            } else {
                log.info("普通角色不存在");
            }
        }
    }

    @Override
    public RestResponse queryAllExpert() {
        List<UserInfoEntity> queryAllExpert = userInfoMapper.queryAllExpert();
        return RestResponse.success(queryAllExpert, "保存专家信息成功");
    }

    /**
     * 专家惩罚
     * @param id
     * @param money
     * @return
     */
    @Override
    public RestResponse updateUserBalance(Long id, BigDecimal money) {
        //余额减少，冻结余额增加
        int updateUserBalance = userInfoMapper.updateExpertBalance(id, money);
        UserInfoEntity selectById = userInfoMapper.getByUserId(id);
        if (updateUserBalance > 0) {
            UserBillEntity ube = new UserBillEntity();
            ube.setUserId(id);
            ube.setTargetUserId(1L);
            ube.setBalance(selectById.getBalance());
            ube.setType(1);
            ube.setBusinessType(9);
            ube.setAmount(money);
            ube.setDescr("惩罚专家，余额减少");
            ube.setFlowNum(RandomizingID.getBillId());
            userBillMapper.insert(ube);
            return RestResponse.success(null, "惩罚成功");
        } else {
            return RestResponse.fail(null, "惩罚失败");
        }
    }

    @Override
    public RestResponse sendRedEnvelope(Long userId, Long redEncelopId) {
        UserCoupon uc = new UserCoupon();
        uc.setUserId(userId);
        uc.setCouponId(redEncelopId);
        uc.setUsedFlag(1);
        boolean save = iUserCouponService.save(uc);
        if (save) {
            return RestResponse.success(null, "发放成功");
        } else {
            return RestResponse.success(null, "发放失败");
        }

    }

    /**
     * 根据mobile获取userID
     *
     * @param mobile
     * @return
     */
    @Override
    public UserInfoEntity getUserByMobile(String mobile) {
        UserInfoEntity userByMobile = userInfoMapper.getUserByMobile(mobile);
        return userByMobile;
    }

    @Override
    public RestResponse batchSendRedEnvelope(List<String> userList, Long redEncelopId) {
        for (String id : userList) {
            UserCoupon uc = new UserCoupon();
            uc.setUserId(Long.parseLong(id));
            uc.setCouponId(redEncelopId);
            uc.setUsedFlag(1);
            iUserCouponService.save(uc);
        }
        return RestResponse.success(null, "发放成功");
    }

    /**
     * 解冻用户
     *
     * @param ids
     * @return
     */
    @Override
    public RestResponse noDeleteUser(List<Long> ids) {
        for (Long id : ids) {
            UserInfoEntity entity = userInfoMapper.getByUserId(id);
            if (null != entity) {
                // 解冻 user_account 账户信息
                iUserAccountService.noDeleteAccount(entity.getUserId());
                // 解冻 user_info 用户信息
                userInfoMapper.noDeleteUserInfo(id);
            } else {
                return RestResponse.fail("当前用户不存在:" + id);
            }

        }
        return RestResponse.success(null, "启用用户成功");
    }

    /**
     * app端升级为会员
     * 
     * @param urEntity
     * @return
     */
    @Override
    public RestResponse toVipApp(UserVipDto urEntity) {
        if (null == urEntity.getPeriod()) {
            return RestResponse.fail("有效期不能为空");
        }
        if (null == urEntity.getUserLevelId()) {
            return RestResponse.fail("vip角色ID不能为空");
        }
        VipFeeSettingEntity entity =
            vipFeeSettingService.getByPeriodAndLevel(urEntity.getPeriod(), urEntity.getUserLevelId());
        if (null == entity) {
            return RestResponse.fail("当前有效期的会员类型不存在，请添加");
        }
        UserInfoEntity userInfoEntity = userInfoMapper.getByUserId(urEntity.getUserId());
        if (null == userInfoEntity) {
            return RestResponse.fail("当前用户不存在");
        } else {
            BigDecimal fee = new BigDecimal("0");
            // 根据有效期和角色查询会费
            VipFeeSettingEntity period =
                vipFeeSettingService.getByPeriodAndLevel(urEntity.getPeriod(), urEntity.getUserLevelId());
            if (null != period) {
                fee = period.getPrice();
                if (null == fee) {
                    return RestResponse.fail("当前类型的会员会费为空，请在后台设置");
                } else {
                    UserLevelRuleEntity userLevelRole = iUserLevelRuleService.getById(urEntity.getUserLevelId());
                    if (null == userLevelRole) {
                        return RestResponse.fail("当前会员角色等级不存在，请检查");
                    }
                    // 升级为会员，同时生成唯一的6位数字邀请码,同时修改会员相关的三个字段
                    int code = (int)(((Math.random() * 9) + 1) * 100000);
                    LocalDateTime vipStartTime = LocalDateTime.now();
                    LocalDateTime vipEndTime = LocalDateTime.now().plusMonths(urEntity.getPeriod());
                    UserAccount userAccount = iUserAccountService.getOneById(urEntity.getUserId());
                    UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
                    if (null != userAccount && userAccount.getExpertFlag() == 1) {
                        // 专家,如果是专家，user_level_name 显示专家，user_level 保存会员角色ID
                        userInfoMapper.toVip(userLevelRole.getId(), expert.getName(), code, vipStartTime, vipEndTime,
                            urEntity.getPeriod(), entity.getId(), urEntity.getUserId());
                    } else {
                        // 不是专家
                        userInfoMapper.toVip(userLevelRole.getId(), userLevelRole.getName(), code, vipStartTime,
                            vipEndTime, urEntity.getPeriod(), entity.getId(), urEntity.getUserId());
                    }
                    // 如果是第一次成为会员，或者不是后台直接升级成会员的(是vip但是没有邀请码)
                    // user_rebate 中修改此人的会费信息,并且给他的上级返利
                    // 判断是否是第一次充值成为会员
                    UserBillEntity userBill = iUserBillService.getByUserIdAndBusinessType(urEntity.getUserId(), 1);
                    if (null == userBill && userInfoEntity.getRequestCode() == null) {
                        // 第一次成为会员
                        // 如果他有上级，上级的user_bill中加入流水信息，余额增加
                        UserRebateEntity upUser = iUserRebateService.getUpUser(urEntity.getUserId());
                        if (null != upUser) {
                            // 查不到上级信息就不给他红利
                            UserInfoEntity userInfo = userInfoMapper.getByUserId(upUser.getUserId());
                            if (null != userInfo) {
                                // 如果他有上级，给上级返利，并保存记录
                                BigDecimal vipFee = saveUpUserRebateInfo(userInfo, upUser, fee, urEntity);
                                // 如果他有上上级，上上级的user_bill中加入流水信息，余额增加
                                UserRebateEntity upUpUser = iUserRebateService.getUpUser(userInfo.getUserId());
                                if (null != upUpUser) {
                                    // 查不到上上级信息就不给他红利
                                    UserInfoEntity upUserInfo = userInfoMapper.getByUserId(upUpUser.getUserId());
                                    if (null != upUserInfo) {
                                        // 给上上级返利，并保存记录
                                        saveUpUpUserRebateInfo(upUserInfo, upUpUser, fee, urEntity, vipFee,
                                            userInfo.getUserId());
                                    }
                                }
                            }
                        }

                    }
                    // ----------------- 充值的人自己也要加上流水信息,余额不变
                    BigDecimal latestUserBalance = iUserBillService.getLatestBalance(urEntity.getUserId());
                    UserBillEntity uBillEntity = new UserBillEntity();
                    uBillEntity.setCreateTime(LocalDateTime.now());
                    uBillEntity.setUserId(urEntity.getUserId());
                    uBillEntity.setTargetUserId(1L);
                    uBillEntity.setAmount(fee);
                    uBillEntity.setType(1);
                    uBillEntity.setBusinessType(1);
                    uBillEntity.setBalance(latestUserBalance);
                    uBillEntity.setDescr("充值VIP会员");
                    iUserBillService.save(uBillEntity);
                    // 后台生成二维码，流化后上传到阿里云服务器
                    try {
                        String qrCodeurl = QrCodeUtil.getQrCode(urEntity.getUserId(), "/wode/vip");
                        // 二维码
                        UserInfoEntity userInfo = new UserInfoEntity();
                        userInfo.setUserId(urEntity.getUserId());
                        userInfo.setQrCodeUrl(qrCodeurl);
                        userInfoMapper.updateUserInfo(userInfo);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return RestResponse.success(null, "升级成功");

                }
            } else {
                return RestResponse.fail("请在后台设置会费信息");
            }

        }

    }

    /**
     * 给上级返利，并保存记录
     * 
     * @param userInfo
     * @param upUser
     * @param fee
     * @param urEntity
     */
    private BigDecimal saveUpUserRebateInfo(UserInfoEntity userInfo, UserRebateEntity upUser, BigDecimal fee,
        UserVipDto urEntity) {
        // 询上级获取的返利金额,上级为专家时，userLevel 对应的不是 user_level_rule 里面的专家主键ID
        // 同时为专家和vip时，返利比率以专家为准
        UserRebateRuleEntity userRebateInfo = null;
        if (userInfo.getUserLevel() != null) {
            UserAccount userAccount = iUserAccountService.getOneById(upUser.getUserId());
            if (userAccount.getExpertFlag() == 1) {
                // 是专家
                UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(expert.getId());
            } else {
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(userInfo.getUserLevel());
            }
            BigDecimal rebate1 = userRebateInfo.getRebate1();
            // 有上级，上级获得返利
            UserBillEntity billUpEntity = new UserBillEntity();
            billUpEntity.setCreateTime(LocalDateTime.now());
            billUpEntity.setUserId(upUser.getUserId());
            billUpEntity.setTargetUserId(upUser.getLowerUserId());
            billUpEntity.setAmount(fee.multiply(rebate1));
            billUpEntity.setType(2);
            billUpEntity.setBusinessType(11);
            billUpEntity.setDescr("一级下线返利");
            // 查询最近一次的余额
            BigDecimal latestBalance = iUserBillService.getLatestBalance(upUser.getUserId());
            billUpEntity.setBalance(latestBalance.add(fee.multiply(rebate1)));
            iUserBillService.save(billUpEntity);
            // 上一级的 user_info 余额增加
            UserInfoEntity uiEntity = new UserInfoEntity();
            uiEntity.setUserId(userInfo.getUserId());
            uiEntity.setBalance(latestBalance.add(fee.multiply(rebate1)));
            log.info("上级现在的余额是" + latestBalance.add(fee.multiply(rebate1)));
            userInfoMapper.updateUserInfo(uiEntity);
            // user_rebate 中修改此人的上级返利信息
            UserRebateEntity ubEntity = new UserRebateEntity();
            ubEntity.setVipFee(fee.multiply(rebate1));
            ubEntity.setLowerUserId(urEntity.getUserId());
            ubEntity.setUserId(upUser.getUserId());
            iUserRebateService.updateByTwoId(ubEntity);
            return fee.multiply(rebate1);
            // todo 给上级发送消息
        }

        return new BigDecimal("0");

    }

    /**
     * 给上上级返利，并保存记录
     * 
     * @param upUserInfo
     *            上上级用户信息
     * @param upUpUser
     *            上上级用户
     * @param fee
     * @param urEntity
     * @param upUserId
     *            上级ID
     */
    private void saveUpUpUserRebateInfo(UserInfoEntity upUserInfo, UserRebateEntity upUpUser, BigDecimal fee,
        UserVipDto urEntity, BigDecimal vipFee, Long upUserId) {
        // 询上级获取的返利金额,上级为专家时，userLevel 对应的不是 user_level_rule 里面的专家主键ID
        // 同时为专家和vip时，返利比率以专家为准
        UserRebateRuleEntity userRebateInfo = null;
        if (upUserInfo.getUserLevel() != null) {
            UserAccount userAccount = iUserAccountService.getOneById(upUpUser.getUserId());
            if (userAccount.getExpertFlag() == 1) {
                // 是专家
                UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(expert.getId());
            } else {
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(upUserInfo.getUserLevel());
            }
            BigDecimal rebate2 = userRebateInfo.getRebate2();
            // 有上上级，上级获得返利
            UserBillEntity billUpEntity = new UserBillEntity();
            billUpEntity.setCreateTime(LocalDateTime.now());
            billUpEntity.setUserId(upUpUser.getUserId());
            billUpEntity.setTargetUserId(upUpUser.getLowerUserId());
            billUpEntity.setAmount(fee.multiply(rebate2));
            billUpEntity.setType(2);
            billUpEntity.setBusinessType(11);
            billUpEntity.setDescr("二级下线返利");
            // 查询最近一次的余额
            BigDecimal latestBalance = iUserBillService.getLatestBalance(upUpUser.getUserId());
            billUpEntity.setBalance(latestBalance.add(fee.multiply(rebate2)));
            iUserBillService.save(billUpEntity);
            // 上上级的 user_info 余额增加
            UserInfoEntity uiEntity = new UserInfoEntity();
            uiEntity.setUserId(upUserInfo.getUserId());
            uiEntity.setBalance(latestBalance.add(fee.multiply(rebate2)));
            userInfoMapper.updateUserInfo(uiEntity);
            log.info("上上级现在的余额是" + latestBalance.add(fee.multiply(rebate2)));
            // user_rebate 中修改此人的上上级返利信息
            UserRebateEntity ubEntity = new UserRebateEntity();
            ubEntity.setVipFeeUp(fee.multiply(rebate2));
            ubEntity.setLowerUserId(urEntity.getUserId());
            ubEntity.setUserId(upUserId);
            ubEntity.setVipFee(vipFee);
            iUserRebateService.updateByTwoId(ubEntity);
            // todo 给上上级发送消息
        }

    }

    /**
     * 定时任务取消会员
     * 
     * @return
     */
    @Override
    public void cancelOverTimeVip() {
        List<UserInfoEntity> overdueVipList = userInfoMapper.getOverdueVip();
        if (ListUtil.isNotEmpty(overdueVipList)) {
            log.info("定时任务开始取消会员");
            for (UserInfoEntity userInfoEntity : overdueVipList) {
                if (userInfoEntity.getMaintenanceCompanyId() == null) {
                    // 个人用户
                    UserLevelRuleEntity person = iUserLevelRuleService.getByCode("PERSON");
                    cancelOverTime(userInfoEntity.getUserId(), person);
                } else {
                    // 企业用户
                    UserLevelRuleEntity company = iUserLevelRuleService.getByCode("COMPANY");
                    cancelOverTime(userInfoEntity.getUserId(), company);
                }
            }
            log.info("定时任务完成取消会员");
        } else {
            log.info("没有到期的会员");
        }
    }

    private void cancelOverTime(Long userId, UserLevelRuleEntity entity) {
        UserAccount userAccount = iUserAccountService.getOneById(userId);
        UserLevelRuleEntity expert = null;
        if (userAccount.getExpertFlag() == 1) {
            expert = iUserLevelRuleService.getByCode("EXPERT");
            // 专家
            if (null != expert) {
                userInfoMapper.cancelOverTimeVip(userId, entity.getId(), expert.getName());
            } else {
                log.info("专家角色不存在");
            }
        } else {
            // 不是专家
            if (null != entity) {
                userInfoMapper.cancelOverTimeVip(userId, entity.getId(), entity.getName());
            } else {
                log.info("普通角色不存在");
            }
        }
    }

    /**
     * 根据userId 查询会费信息
     * 
     * @return
     */
    @Override
    public VipFeeSettingEntity getVipByUserId(Long UserId) {
        return userInfoMapper.getVipByUserId(UserId);
    }

    /**
     * 根据userLevel 查询用户信息
     * 
     * @param userLevel
     * @return
     */
    @Override
    public List<UserInfoEntity> getByUserLevel(Long userLevel) {
        return userInfoMapper.getByUserLevel(userLevel);
    }

    /**
     * 修改所有的 UserLevelName
     * 
     * @param userLevelName
     * @param OldUserLevelName
     */
    @Override
    public void updateUserLevelName(String userLevelName, String OldUserLevelName) {
        userInfoMapper.updateUserLevelName(userLevelName, OldUserLevelName);
    }

    /**
     * 批量撤销专家处罚
     * @param ids
     * @return
     */
    @Override
    public RestResponse addUserBalance(List<Long> ids) {
        for(Long id : ids){
            //查询本次处罚信息
            ExpertsPunishment expertsPunishment = iExpertsPunishmentService.getById(id);

            //余额增加，冻结余额减少
            int updateUserBalance = userInfoMapper.addExpertBalance(expertsPunishment.getChargeId(),
                    expertsPunishment.getPunishAmount());
            UserInfoEntity selectById = userInfoMapper.getByUserId(expertsPunishment.getChargeId());
            if (updateUserBalance > 0) {
                //流水记录
                UserBillEntity ube = new UserBillEntity();
                ube.setUserId(expertsPunishment.getChargeId());
                ube.setTargetUserId(1L);
                ube.setBalance(selectById.getBalance());
                ube.setType(2);
                ube.setBusinessType(9);
                ube.setAmount(expertsPunishment.getPunishAmount());
                ube.setDescr("撤销专家惩罚，余额增加");
                ube.setFlowNum(RandomizingID.getBillId());
                userBillMapper.insert(ube);
                //修改专家惩罚记录信息状态
                ExpertsPunishment entity = new ExpertsPunishment();
                entity.setId(id);
                entity.setStatuz(1);
                iExpertsPunishmentService.saveOrUpdate(entity);
                // 添加消息
                PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(expertsPunishment.getChargeId().toString());
                PushMessage pushMessage = PushMessage.cancelPunishment(expertsPunishment.getPunishAmount().toString());
                pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
            } else {
                return RestResponse.fail(null, "撤销失败");
            }
        }
        return RestResponse.success(null, "撤销成功");

    }

    /**
     * 查询最新的用户信息和权限
     * @param userId
     * @return
     */
    @Override
    public RestResponse getNewInfo(Long userId) {
        UserInfoEntity userInfoEntity = userInfoMapper.getByUserId(userId);
        UserAccount userAccount = iUserAccountService.getOneById(userId);
        //菜单权限信息
        List<Appmenu> appMenuList = appUserMenuService.getAllMenuByLevelId(userInfoEntity.getUserLevel());
        NewUserInfoVo newUserInfoVo = new NewUserInfoVo();
        if( null != userInfoEntity){
            BeanUtils.copyProperties(userInfoEntity,newUserInfoVo);
        }
        if( null != userAccount){
            newUserInfoVo.setExpertFlag(userAccount.getExpertFlag());
        }
        newUserInfoVo.setAppMenus(appMenuList);
        return RestResponse.success(newUserInfoVo,"查询成功");
    }

    @Override
    public RestResponse rechargePayBalance(Long userId, BigDecimal money) {
        userInfoMapper.rechargePayBalance(userId, money);
        return RestResponse.success();
    }

    @Override
    public RestResponse getUserByCompanyId(Long companyId) {
        List<UserInfoEntity> userByCompanyId = userInfoMapper.getUserByCompanyId(companyId);
        return RestResponse.success(userByCompanyId,"查询成功");
    }

    @Override
    public RestResponse listGroupExpert(UserInfoQuery example) {
        List<UserInfoEntity> expertList = userInfoMapper.listGroupExpert();
        List<UserInfoEntity> invitedExpertList = userInfoMapper.listGroupHotExpert();

        LinkedHashMap<String, List<UserInfoEntity>> collect = new LinkedHashMap<>();
        collect.put("热门",invitedExpertList);
        for (int i = 65; i <= 90; i++) {
            char code = (char) i;
            collect.put(String.valueOf(code), new ArrayList<>());
        }
        expertList.stream().forEach(item -> {
            String fisrtCode = String.valueOf(PingYinUtil.getFirstSpell(item.getName()).toUpperCase().charAt(0));
            collect.get(fisrtCode).add(item);
        });
//        LinkedHashMap<Character, List<UserInfoEntity>> collect = expertList.stream().collect(Collectors.groupingBy(item -> {
//            return PingYinUtil.getFirstSpell(item.getName()).toUpperCase().charAt(0);
//        },LinkedHashMap::new, Collectors.toList()));

        return RestResponse.success(collect);
    }

    @Override
    public RestResponse getExpertRewardedCount(Long expert) {
        int expertRewardedCount = userInfoMapper.getExpertRewardedCount(expert);
        return RestResponse.success(expertRewardedCount);
    }

    @Override
    public RestResponse getRewardList(Long userId) {
        List<UserRewardListVo> userRewardList = userInfoMapper.getUserRewardList(userId);

        return RestResponse.success(userRewardList);
    }

    @Override
    public RestResponse saveVipID(UserInfoEntity entity) {
        UserInfoEntity userInfo = this.getOne(new QueryWrapper<UserInfoEntity>().eq("user_id", entity.getUserId()));
        if (StringUtils.isNotBlank(userInfo.getVipId())){
            return RestResponse.fail("vip id添加之后，不能进行修改哦！");
        }
        List<UserInfoEntity> existsVipids = this.list(new QueryWrapper<UserInfoEntity>().eq("vip_id", entity.getVipId()));
        if(existsVipids != null && !existsVipids.isEmpty()){
            return RestResponse.fail("vip id已存在，请使用其他幸运数字！");
        }

        boolean updateRtn = this.update(entity, new QueryWrapper<UserInfoEntity>().eq("user_id", entity.getUserId()));
        if (updateRtn){
            return RestResponse.success("vip id添加成功！");
        }
        return RestResponse.fail("vip id添加失败！");
    }
}
