package cn.wisenergy.service.app.impl;

import cn.wisenergy.common.constant.RedisConsts;
import cn.wisenergy.common.utils.*;
import cn.wisenergy.mapper.*;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.vo.UserLoginVo;
import cn.wisenergy.model.vo.UserRegisterVo;
import cn.wisenergy.service.Manager.LoginManager;
import cn.wisenergy.service.app.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


/**
 * @author 86187
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private LoginManager loginManager;

    @Autowired
    private TeamUserInfoMapper teamUserInfoMapper;

    private static final String INVITE_CODE = "1";

    @Override
    public R<Boolean> userRegister(UserRegisterVo userVo) {
        log.info("shop-mall[]LoginServiceImpl[]userRegister[]input.param.userVo:" + userVo);
        if (null == userVo || StringUtils.isBlank(userVo.getUserId()) || StringUtils.isBlank(userVo.getSms())) {
            return R.error("入参不能为空!");
        }

        //判断phone是否符合输入类型
        if (!userVo.getUserId().matches(Constants.RegConstant.PHONE_REGSTR)) {
            return R.error("手机号码格式不正确!");
        }

        //1、检验验证码是否正确
        String key = StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX, Constants.RedisKey.SMS_PRIFIX, userVo.getUserId(), 0 + "");
        String redisCode = redisUtils.getValue(key);
        if (StringUtils.isBlank(redisCode) || !userVo.getSms().equals(redisCode)) {
            return R.error("验证码错误!");
        }

        //2、检验手机号是否已经被注册
        boolean bool = checkPhone(userVo.getUserId());
        if (bool) {
            return R.error("该用户已存在，请直接登录!");
        }

        //3、初始化用户信息
        User user = new User();
        user.setUserId(userVo.getUserId());
        user.setHeadImage(Constants.Common.HEAD_POTRAIT);
        user.setUserLevel(0);
        String inviteCode = ShareCodeUtil.idToCode(Long.parseLong(userVo.getUserId()));
        user.setInviteCode(inviteCode);

        //4、判断邀请人邀请码是否存在 否：直接初始化用户信息 存：计算当前用户的直推上级 +1
        if (StringUtils.isBlank(userVo.getBeInvitedCode())) {
            user.setBeInvitedCode("1");
            List<TeamUserInfo> list = new ArrayList<>();
            //初始化用户信息
            boolean initUser = loginManager.initUserInfo(user, list);
            if (!initUser) {
                return R.ok(1, false);
            }
        } else {
            //判断推荐人邀请码信息是否正确
            User userCode = usersMapper.queryByInviteCode(userVo.getBeInvitedCode());
            if (null == userCode) {
                return R.error("邀请码填写无效,邀请人不存在,请重新填写!");
            }
            user.setBeInvitedCode(userVo.getBeInvitedCode());

            //4、根据推荐人邀请码，获取用户的上级列表
            List<TeamUserInfo> list = getTeamUserList(userVo.getBeInvitedCode());

            //初始化用户信息
            boolean initBool = loginManager.initUserInfo(user, list);
            if (!initBool) {
                return R.ok(1, false);
            }
        }
        redisUtils.delete(key);
        return R.ok(0, true);
    }

    /**
     * 检查用户手机号是否已注册
     *
     * @param userId 用户手机号
     * @return true or false
     */
    private Boolean checkPhone(String userId) {
        //根据userId，获取用户信息
        User user = usersMapper.getByUserId(userId);
        return null != user;
    }

    /**
     * 获取当前用户直销用户列表
     *
     * @param beInvitedCode 邀请人邀请码
     * @return 用户直销用户列表
     */
    private List<TeamUserInfo> getTeamUserList(String beInvitedCode) {
        List<TeamUserInfo> list = new ArrayList<>();
        while (!INVITE_CODE.equals(beInvitedCode)) {
            //根据邀请码查询上级用户的id
            User user = usersMapper.getByBeInvitedCode(beInvitedCode);
            //查询上级用户的团队信息表
            TeamUserInfo teamUserInfoByUserId = teamUserInfoMapper.getByUserId(user.getUserId());
            list.add(teamUserInfoByUserId);
            beInvitedCode = user.getInviteCode();
        }

        return list;
    }
}
