package com.ytpm.question.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ytpm.agent.enums.UserStatusEnum;
import com.ytpm.app.model.YtDyzLoginRecord;
import com.ytpm.app.model.YtDyzPowerRecord;
import com.ytpm.app.model.YtDyzUser;
import com.ytpm.app.param.WxLoginParam;
import com.ytpm.app.view.WxLoginResult;
import com.ytpm.app.view.WxUserInfo;
import com.ytpm.constant.StrConstant;
import com.ytpm.handle.CustomerException;
import com.ytpm.question.dao.AppUserMapper;
import com.ytpm.question.dao.LoginRecordMapper;
import com.ytpm.question.dao.QuestionMapper;
import com.ytpm.question.redis.RedisService;
import com.ytpm.question.service.AppUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

@Service
@RefreshScope
public class AppUserServiceImpl implements AppUserService {

    @Resource
    private AppUserMapper appUserMapper;
    @Resource
    private LoginRecordMapper loginRecordMapper;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private RedisService redisService;
    @Value("${risk.config.banned.tips}")
    private String tips;

    /**
     * openid查询用户信息
     */
    @Override
    public YtDyzUser selectByOpenid(String openid, Long ditchId) {
        return appUserMapper.getYtAppUser(openid, ditchId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public YtDyzUser crudForNewTrans(WxLoginParam param, WxUserInfo wxUserInfo, WxLoginResult loginResult) {
        //处理用户注册或登录更新信息
        YtDyzUser old = appUserMapper.getYtAppUser(loginResult.getOpenid(), param.getDitchId());
        // 获取游客登陆信息
        if (Objects.isNull(old)) {
            old = appUserMapper.getByDeviceAndDitch(param.getDeviceId(), param.getDitchId());
            if (Objects.nonNull(old)) {
                old.setWxOpenId(wxUserInfo.getOpenid());
                old.setNickName(wxUserInfo.getNickname());
                old.setHeadImg(wxUserInfo.getHeadimgurl());
                YtDyzUser newUser = new YtDyzUser();
                newUser.setUserId(old.getUserId());
                newUser.setWxOpenId(wxUserInfo.getOpenid());
                newUser.setNickName(wxUserInfo.getNickname());
                newUser.setHeadImg(wxUserInfo.getHeadimgurl());
                appUserMapper.updateUser(newUser);
            }
        }
        if (Objects.isNull(old)) {
            old = new YtDyzUser();
            registryUser(param, wxUserInfo, loginResult, old);
        } else {
            deadWithUserCrud(old, wxUserInfo, param);
        }
        //设置最后一次答题问题ID、今日答题数、历史答题数
        setExtInfo(old, wxUserInfo.getHeadimgurl());
        // 添加用户登录记录
        addLoginRecord(param, old.getUserId());
        return old;
    }

    @Override
    public void addPower(String userId) {
        appUserMapper.addOnePower(userId);
        YtDyzPowerRecord record = new YtDyzPowerRecord();
        record.setUserId(userId);
        record.setRecordId(IdUtil.fastSimpleUUID());
        record.setAddTime(new Date());
        record.setType(2);
        record.setRemark("增加体力");
        appUserMapper.addPowerRecord(record);
    }

    /**
     * 设置扩展信息
     */
    private void setExtInfo(YtDyzUser old, String headimgurl) {
        old.setHeadImg(headimgurl);
        old.setLastQuestionId(questionMapper.getLastQuestionId(old.getUserId()));
        old.setTodayAnswerCount(questionMapper.getAnswerCount(old.getUserId(), 1));
        old.setHistoryAnswerCount(questionMapper.getAnswerCount(old.getUserId(), 2));
        old.setAnswerRecordList(questionMapper.getAnswerRecords(old.getUserId()));
        old.setLoginRecordList(loginRecordMapper.getLoginRecords(old.getUserId()));
    }

    /**
     * 增加用户登录记录
     */
    private void addLoginRecord(WxLoginParam param, String userId) {
        YtDyzLoginRecord loginRecord = new YtDyzLoginRecord();
        loginRecord.setRecordId(IdUtil.fastSimpleUUID());
        loginRecord.setUserId(userId);
        loginRecord.setLoginTime(new Date());
        loginRecord.setDeviceBrand(param.getBrand());
        loginRecord.setDeviceModel(param.getModel());
        loginRecord.setLoginIp(param.getLoginIp());
        loginRecord.setOperator(param.getIpOperator());
        loginRecord.setIpAddr(param.getIpLocation());
        loginRecord.setPhoneJson(param.getPhoneJson());
        loginRecordMapper.insertOne(loginRecord);
    }

    private String getTipsMsg() {
        String[] split = tips.split(",");
        return split[RandomUtil.randomInt(split.length)];
    }

    /**
     * 处理用户数据
     */
    private void deadWithUserCrud(YtDyzUser old, WxUserInfo wxUserInfo, WxLoginParam param) {
        //处于风控状态的用户不允许登录
        if (!old.getUserStatus().equals(UserStatusEnum.NORMAL.getCode())) {
            throw new CustomerException(getTipsMsg());
        }
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(old.getUserId());
        newUser.setNickName(wxUserInfo.getNickname());
        newUser.setHeadImg(wxUserInfo.getHeadimgurl());
        newUser.setLastLoginTime(new Date());
        newUser.setLastLoginIp(param.getLoginIp());
        newUser.setPhone(param.getPhone());
        newUser.setPhoneJson(param.getPhoneJson());
        newUser.setDeviceId(param.getDeviceId());
        YtDyzLoginRecord wxLoginRecord = loginRecordMapper.getLastLoginRecord(old.getUserId(), 0);
        YtDyzLoginRecord visitorLoginRecord = loginRecordMapper.getLastLoginRecord(old.getUserId(), 1);
        if (wxLoginRecord == null && visitorLoginRecord == null
                || wxLoginRecord != null && wxLoginRecord.getLoginTime() != null
                && DateUtil.compare(wxLoginRecord.getLoginTime(), newUser.getLastLoginTime(), "yyyy-MM-dd") < 0) {
            newUser.setLoginDays(old.getLoginDays() + 1);
        }
        appUserMapper.updateUser(newUser);
    }


    /**
     * 注册用户
     */
    private void registryUser(WxLoginParam param, WxUserInfo wxUserInfo, WxLoginResult loginResult, YtDyzUser old) {
        old.setUserId(redisService.getAppUserId());
        old.setPhone(param.getPhone());
        old.setDeviceId(param.getDeviceId());
        old.setNickName(wxUserInfo.getNickname());
        old.setLastLoginTime(new Date());
        old.setRegistryTime(new Date());
        old.setLastLoginIp(param.getLoginIp());
        old.setLoginDays(1);
        old.setPower(0);
        old.setTotalVideo(0);
        old.setTotalIncome(BigDecimal.ZERO);
        old.setRedPacketAmount(BigDecimal.ZERO);
        old.setRedPacketBalance(BigDecimal.ZERO);
        old.setPointsBalance(BigDecimal.ZERO);
        old.setPointsTotal(BigDecimal.ZERO);
        old.setWithdrawTotal(BigDecimal.ZERO);
        old.setDitchId(param.getDitchId());
        old.setSignDays(0);
        old.setAppId(param.getAppId());
        old.setUserStatus(UserStatusEnum.NORMAL.getCode());
        old.setWxOpenId(loginResult.getOpenid());
        old.setHeadImg(wxUserInfo.getHeadimgurl());
        old.setPhoneJson(param.getPhoneJson());
        //根据设备ID获取平台ID 获取不到再生成平台ID
        String platformId = appUserMapper.getByDeviceId(param.getDeviceId(), wxUserInfo.getOpenid());
        old.setPlatformId(StrUtil.isBlank(platformId) ?
                (StrConstant.PLATFORM_ID_PREFIX + IdUtil.getSnowflakeNextIdStr()) : platformId);
        appUserMapper.addOne(old);
    }
}
