package cn.wisenergy.service.app.impl;

import cn.wisenergy.common.utils.*;
import cn.wisenergy.mapper.*;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.app.UsersDto;
import cn.wisenergy.model.vo.AerialDeliveryVo;
import cn.wisenergy.model.vo.UserPoolVo;
import cn.wisenergy.service.app.UserService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.util.CollectionUtils;
import org.yaml.snakeyaml.events.Event;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 86187
 * @ Description: 用户接口实现
 * @ Author     : 86187
 * @ Date       : 2021/1/6 16:11
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UsersMapper, User> implements UserService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private RecommendUserMapper recommendUserMapper;

    @Autowired
    private TeamUserInfoMapper teamUserInfoMapper;

    @Autowired
    private CultivatingPrizeInfoMapper cultivatingPrizeInfoMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private TeamPerformanceMapper teamPerformanceMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public User getById(String userId) {
        return usersMapper.getByUserId(userId);
    }

    /**
     * 获取登录用户
     * @param token
     */
    @Override
    public UsersDto getLoginUser(String token) {
        UsersDto usersDto = null;
        String key = RedisKeyUtils.formatKeyWithPrefix(Constants.Redis.PREFIX_TOKEN,token);
        String value = redisUtils.getValue(key);
        if(!StringUtils.isBlank(value)){
            usersDto = JSONObject.parseObject(value, UsersDto.class);
            log.info("获取到用户登录信息users:{}", value);
        }
        return usersDto;
    }

    @Override
    public R<Integer> getById1(String userId) {

        return R.ok(usersMapper.ByUserId(userId));
    }

    @Override
    public User getUserById(Long id) {
        return this.usersMapper.getUserById(id);
    }

    @Override
    public User getByUserId(String userId) {

        return usersMapper.getByUserId(userId);
    }


    @Override
    public User queryUsersByPhone(String userId) {
        Map<String, Object> map = new HashMap<String, Object>();
        //查询数据库，看看是否存在该用户
        User ByuserId = usersMapper.getByUserId(userId);

        return ByuserId;
    }

    @Override
    public User queryUsersByOpenId(String id) {
        return null;
    }

    @Override
    public Map userByZx(String userId, String beInvitedCode) {
        //查询数据库，看看是否存在该用户
        User byUserId = usersMapper.getByUserId(userId);
        if (null != byUserId) {
            R.error(0, "该用户已存在！请直接登录！");
            Map map = new HashMap();
            map.put("code", 0);
            map.put("msg", "该用户已存在！请直接登录！");
            return map;
        }

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-ddhh:mm:ss");
            Timestamp date =  java.sql.Timestamp.valueOf("2012-12-1201:12:11");
            System.out.println(date);
        } catch (Exception e) {
            e.printStackTrace();
        }

        /**
         * 判断用户推荐人的邀请码是否为空，空的话填写1   || "" == beInvitedCode
         */
        if ("".equals(beInvitedCode)  || null==beInvitedCode) {


            //插入用户手机号与推荐人邀请码user_id,invite_code,be_invited_code,user_level,create_time,update_time
            String inviteCode="0";
            beInvitedCode = "1";
            int userLevel=0;
            String headImage= Constants.Common.HEAD_POTRAIT;
            usersMapper.insertbyint(userId, inviteCode,beInvitedCode,userLevel,headImage);
            registUserMoudleInit(userId);
        } else {
            //用户的被邀请码，查询到推荐人用户，根据推荐人用户的邀请码查询/修改
            User user = usersMapper.getByBeInvitedCode(beInvitedCode);

//        邀请人的被邀请码
            String byqm = user.getBeInvitedCode();
//        通过被邀请码，比对本人邀请码查询本人id

            String idb = String.valueOf(usersMapper.beInvitedCode1(beInvitedCode));
            //判断是否存在被邀请人的用户
            if(null==usersMapper.beInvitedCode1(beInvitedCode)){
                Map map = new HashMap();
                R.error(1, "邀请码填写无效！邀请人不存在，请重新填写！");
                map.put("code:", 1);
                map.put("msg:", "邀请码填写无效！邀请人不存在，请重新填写！");
                return map;
            }
            int idbc=Integer.valueOf(idb);
            int ida = user.getId();
            //判断被邀请用户的创建时间是否比推荐人的用户时间晚
            if (idbc > ida) {
                Map map = new HashMap();
                R.error(1, "注册失败！邀请码无效,请重新填写！");
                map.put("code:", 1);
                map.put("msg:", "注册失败！邀请码无效,请重新填写！");
                return map;
            }

            if (null == beInvitedCode || "" == beInvitedCode) {
                beInvitedCode = String.valueOf(1);
            }
        }

        //根据插入的用户手机号，查询用户唯一ID
        long yqm = usersMapper.getuserIdById(userId);
        //用户唯一ID调用生成6位邀请码
        String inviteCode = ShareCodeUtil.idToCode(yqm);
        Integer userLevel = 0;
        //根据用户手机号，更新用户信息
//        usersMapper.edit1(userLevel,inviteCode,userId);
        User byUserId1 = usersMapper.getByUserId(userId);
        byUserId1.setInviteCode(inviteCode);
        byUserId1.setUserLevel(0);

        usersMapper.updateById(byUserId1);

        String BYQM = String.valueOf(usersMapper.BYQMById(userId));

        if ("1".equals(BYQM)) {
            Map map = new HashMap();
            map.put("code", 0);
            map.put("msg", "注册成功！");
            return map;
        }

        //根据当前推荐人的邀请码查询 上级用户id
        String userIdByIntive = usersMapper.getUserByIntiveCode(beInvitedCode);
        if (null == userIdByIntive){
            R.error(1,"用户推荐人邀请码不存在，请填写正确的邀请码");
        }else{
            //上级用户的直推信息 普通用户数量+1
            RecommendUser recommendUserMapperByUserId = recommendUserMapper.getByUserId(userIdByIntive);
            Integer normalUserNum = recommendUserMapperByUserId.getNormalUserNum();
            recommendUserMapperByUserId.setNormalUserNum(normalUserNum+1);
            recommendUserMapper.updateById(recommendUserMapperByUserId);
        }

        //递归向上修改团队用户信息表
        teamUserInfo(beInvitedCode);
        Map map = new HashMap();
        R.ok("直推表普通用户数量+1成功！", 0);
        map.put("code:", 0);
        map.put("msg:", "直推表普通用户数量+1成功");
        return map;
    }

    @Override
    public Integer getUserIdById(String userId) {
        return null;
    }


    @Override
    public R<AerialDeliveryVo> queryAerialDelivery() {
        log.info("shop-mall[]UserServiceImpl[]queryAerialDelivery[]input.method");
        //获取本月新注册用户
        Map<String, Object> map = new HashMap<>(4);
        map.put("createTime", new Date());
        List<User> list = usersMapper.getList(map);
        if (CollectionUtils.isEmpty(list)) {
            return R.ok(new AerialDeliveryVo());
        }

        AerialDeliveryVo aerialDeliveryVo = new AerialDeliveryVo();
        List<UserPoolVo> userPoolVoList = new ArrayList<>();
        for (User user : list) {
            UserPoolVo userPoolVo = new UserPoolVo();
            userPoolVo.setUserId(user.getUserId());
            userPoolVo.setHeadImage(user.getHeadImage());
            userPoolVo.setIntoTime(user.getCreateTime());
            userPoolVoList.add(userPoolVo);
        }
        aerialDeliveryVo.setTotal(list.size());
        aerialDeliveryVo.setUserPoolVos(userPoolVoList);
        return R.ok(aerialDeliveryVo);
    }


    @Override
    public R<Boolean> setHeadImage(String userId, String headImage) {
        log.info("shop-mall[]UserServiceImpl[]setHeadImage[]input.param.userId,headImage:" + userId, headImage);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(headImage)) {
            return R.error("入参不能为空!");
        }

        //获取用户信息
        User user = usersMapper.getByUserId(userId);
        if (null == user) {
            return R.error("用户信息不存在!");
        }

        //添加头像
        user.setHeadImage(headImage);
        int count = usersMapper.edit(user);
        if (count == 0) {
            return R.error("设置头像失败!");
        }
        return R.ok(0, true);
    }

    @Override
    public R<Boolean> fillInInviteCode(String userId, String inviteCode) {
        log.info("shop-mall[]UserServiceImpl[]fillInInviteCode[]input.param.userId,inviteCode:" + userId, inviteCode);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(inviteCode)) {
            return R.error("入参不能为空!");
        }

        //1、获取用户信息
        User user = usersMapper.getByUserId(userId);
        if (null == user) {
            return R.error("用户信息不存在!");
        }

        //2、根据邀请码，获取邀请人信息
        User userCode = usersMapper.queryByInviteCode(inviteCode);
        if (null == userCode) {
            return R.error("邀请人信息不存在!");
        }

        //3、判断邀请人的注册时间是否大于当前用户
        if (user.getCreateTime().getTime() < userCode.getCreateTime().getTime()) {
            return R.error("请填写注册时间早于自己的用户邀请码!");
        }

        //4、设置用户被邀请码
        user.setBeInvitedCode(inviteCode);
        int count = usersMapper.edit(user);
        if (count == 0) {
            return R.ok(1, false);
        }
        return R.ok(0, true);
    }

    //团队用户数据维护
    public void teamUserInfo(String beInvitedCode) {
        //根据邀请码查询上级用户的id
        String teamUserId = usersMapper.getUserByIntiveCode(beInvitedCode);
        //查询上级用户的团队信息表
        TeamUserInfo teamUserInfoByUserId = teamUserInfoMapper.getByUserId(teamUserId);
        //上级用户团队信息普通用户数量+1
        Integer normalUserNum = teamUserInfoByUserId.getNormalUserNum();
        teamUserInfoByUserId.setNormalUserNum(normalUserNum + 1);
        teamUserInfoMapper.updateById(teamUserInfoByUserId);
        //根据上级用户id查询上级用户的邀请码
        User teamUser = usersMapper.getByUserId(teamUserId);
        String teamUserBeInvitedCode = teamUser.getBeInvitedCode();
        //递归实现上级所有的用户普通数量 + 1
        //若团队用户的被邀请码为 1 时 则没有上级用户用户
        if ("1".equals(teamUserBeInvitedCode)){
            teamUserInfo(teamUserBeInvitedCode);
        }else {
            return;
        }
    }
    /**
     * 用户登出
     * @param token
     * @return
     */
    @Override
    public int logout(String token) {
        int succ = 0;
        String key = RedisKeyUtils.formatKeyWithPrefix(token);
        redisUtils.delete(key);
        if(redisUtils.getValue(key) == null){
            succ = 1;
        }
        return succ;
    }

    /**
     * 注册时用户初始化
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public Boolean registUserMoudleInit(String userId){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String data = sdf.format(new Date());

        try {
            //直推用户表维护
            RecommendUser recommendUser = new RecommendUser();
            recommendUser.setUserId(userId);
            recommendUser.setNormalUserNum(0);
            recommendUser.setSeedlingNum(0);
            recommendUser.setBronzeTreeNum(0);
            recommendUser.setSilverTreeNum(0);
            recommendUser.setGoldTreeNum(0);
            recommendUser.setFarmerNum(0);
            recommendUser.setForestStartNum(0);
            recommendUser.setPartnerNum(0);
            recommendUser.setMonthyCount(new BigDecimal(0));
            recommendUser.setHistoryCount(new BigDecimal(0));
            recommendUserMapper.add(recommendUser);

            //团队用户表数据维护
            TeamUserInfo teamUserInfo = new TeamUserInfo();
            teamUserInfo.setUserId(userId);
            teamUserInfo.setNormalUserNum(0);
            teamUserInfo.setSeedlingNum(0);
            teamUserInfo.setBronzeTreeNum(0);
            teamUserInfo.setSilverTreeNum(0);
            teamUserInfo.setGoldTreeNum(0);
            teamUserInfo.setFarmerNum(0);
            teamUserInfo.setForestStartNum(0);
            teamUserInfo.setPartnerNum(0);
            teamUserInfoMapper.add(teamUserInfo);

            //培育奖记录数据维护
            CultivatingPrizeInfo cultivatingPrizeInfo = new CultivatingPrizeInfo();
            cultivatingPrizeInfo.setUserId(userId);
            cultivatingPrizeInfo.setSeedling(0);
            cultivatingPrizeInfo.setBronzeTree(0);
            cultivatingPrizeInfo.setSilverTree(0);
            cultivatingPrizeInfo.setGoldTree(0);
            cultivatingPrizeInfo.setFarmer(0);
            cultivatingPrizeInfo.setForestStart(0);
            cultivatingPrizeInfo.setPartner(0);
            cultivatingPrizeInfoMapper.add(cultivatingPrizeInfo);

            //账户表记录数据维护
            AccountInfo accountInfo = new AccountInfo();
            accountInfo.setUserId(userId);
            accountInfo.setUserLevel(0);
            accountInfo.setYearMonth(data);
            accountInfo.setExtractMoney(new BigDecimal(0));
            accountInfo.setEarningsMonth(new BigDecimal(0));
            accountInfo.setFrozenMoney(new BigDecimal(0));
            accountInfo.setEarningsTotal(new BigDecimal(0));
            accountMapper.add(accountInfo);

            //团队业绩表数据维护
            TeamPerformance teamPerformance = new TeamPerformance();
            teamPerformance.setUserId(userId);
            teamPerformance.setUserLevel(0);
            teamPerformance.setYearMonth(data);
            teamPerformance.setMonthTeamPerformance(new BigDecimal(0));
            teamPerformanceMapper.add(teamPerformance);
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
