package com.playlet.web.service.app.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.playlet.common.constant.PlayletConstants;
import com.playlet.common.constant.RedisConstants;
import com.playlet.system.domain.PlayletUser;
import com.playlet.system.domain.PlayletUserLogin;
import com.playlet.system.service.IPlayletUserLoginService;
import com.playlet.system.service.IPlayletUserService;
import com.playlet.web.req.PlayUserReq;
import com.playlet.web.service.app.PlayletUserAppService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PlayletUserAppServiceImpl implements PlayletUserAppService {

    private final IPlayletUserService iPlayletUserService;

    private final StringRedisTemplate stringRedisTemplate;

    private final IPlayletUserLoginService iPlayletUserLoginService;


    @Override
    public PlayletUser addPlayletUser(PlayletUser playletUser) throws Exception{
        String alreadyCode = stringRedisTemplate.opsForValue().get(RedisConstants.SMS_CODE_PREFIX + playletUser.getPhone());
        if(StringUtils.isEmpty(alreadyCode)){
            throw new Exception("验证码已过期!");
        }
        if(!alreadyCode.equals(playletUser.getCode())){
            throw new Exception("短信验证码错误!");
        }
        playletUser.setCreateBy(PlayletConstants.DEFAULT_CREATE);
        playletUser.setCreateTime(new Date());
        iPlayletUserService.save(playletUser);
        playletUser.setCode("PLAYLET_" + playletUser.getId());
        iPlayletUserService.updateById(playletUser);
        return playletUser;
    }

    @Override
    public PlayletUser getByOpenId(String openid, String parentId) {
        PlayletUser playletUser = iPlayletUserService.lambdaQuery().eq(PlayletUser::getOpenId, openid).one();
        if(ObjectUtil.isNull(playletUser)){
            playletUser = new PlayletUser();
            playletUser.setOpenId(openid);
            playletUser.setCreateBy(PlayletConstants.DEFAULT_CREATE);
            playletUser.setCreateTime(new Date());
            if(parentId != null){
                playletUser.setParentId(parentId);
            }
            iPlayletUserService.save(playletUser);
            playletUser.setCode("PLAYLET_" + playletUser.getId());
            iPlayletUserService.updateById(playletUser);
        }
        return playletUser;
    }

    @Override
    public PlayletUser onlyLoginByOpenid(String openid) {
        PlayletUser user = iPlayletUserService.lambdaQuery().eq(PlayletUser::getOpenId, openid).one();
        if(user != null){
            this.addLoginRecord(user.getId());
        }
        return user;
    }

    @Override
    public PlayletUser getByPhone(PlayUserReq playUserReq) throws Exception{
        String alreadyCode = stringRedisTemplate.opsForValue().get(RedisConstants.SMS_CODE_PREFIX + playUserReq.getPhone());
        if(StringUtils.isEmpty(alreadyCode)){
            throw new Exception("验证码已过期!");
        }
        if(!alreadyCode.equals(playUserReq.getCode())){
            throw new Exception("短信验证码错误!");
        }
        PlayletUser user = iPlayletUserService.lambdaQuery()
                .eq(PlayletUser::getPhone, playUserReq.getPhone()).one();
        this.addLoginRecord(user.getId());
        return user;
    }

    @Override
    public PlayletUser getByPassword(PlayUserReq playUserReq) throws Exception {
        PlayletUser playletUser = iPlayletUserService.lambdaQuery()
                .eq(PlayletUser::getPhone, playUserReq.getPhone())
                .eq(PlayletUser::getPassword, playUserReq.getPassword()).one();
        if(playletUser == null){
            throw new Exception("账号或密码错误!");
        }else {
            this.addLoginRecord(playletUser.getId());
            return playletUser;
        }
    }

    @Override
    public void updatePlayletUser(PlayletUser playletUser) {
        iPlayletUserService.updateById(playletUser);
    }

    @Override
    public void updatePasswordByCode(PlayUserReq playUserReq) throws Exception{
        String alreadyCode = stringRedisTemplate.opsForValue().get(RedisConstants.SMS_CODE_PREFIX + playUserReq.getPhone());
        if(StringUtils.isEmpty(alreadyCode)){
            throw new Exception("验证码已过期!");
        }
        if(!alreadyCode.equals(playUserReq.getCode())){
            throw new Exception("短信验证码错误!");
        }
        PlayletUser user = iPlayletUserService.lambdaQuery()
                .eq(PlayletUser::getPhone, playUserReq.getPhone()).one();
        if(user == null){
            throw new Exception("用户尚未注册!");
        }else {
            user.setPassword(playUserReq.getPassword());
            iPlayletUserService.updateById(user);
        }

    }

    @Override
    public PageInfo<PlayletUser> getPlayletUserPage(PlayletUser playletUser, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<PlayletUser> list = iPlayletUserService.selectPlayletUserList(playletUser);
        return PageInfo.of(list);
    }

    @Override
    public void addLoginRecord(Long userId) {
        String nowDate = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        Date begin = DateUtil.parse(nowDate+" 00:00:00", DatePattern.NORM_DATETIME_PATTERN);
        Date end = DateUtil.parse(nowDate+" 23:59:59", DatePattern.NORM_DATETIME_PATTERN);
        long count = iPlayletUserLoginService.lambdaQuery()
                .eq(PlayletUserLogin::getUserId, userId)
                .between(PlayletUserLogin::getLoginTime, begin, end)
                .count();
        if(count == 0){
            PlayletUserLogin login = new PlayletUserLogin();
            login.setUserId(userId);
            login.setLoginTime(new Date());
            login.setCreateTime(new Date());
            login.setCreateBy("system");
            iPlayletUserLoginService.save(login);
        }
    }
}
