package com.app.service.guardian;

import com.app.constant.RedisKeyConstant;
import com.app.dto.account.operation.WXMPLoginDto;
import com.app.dto.wx.WxCode2SessionDto;
import com.app.dto.wx.WxUserInfoDto;
import com.app.entity.guardian.Guardian;
import com.app.mapper.guardian.GuardianMapper;
import com.app.service.guardian.dto.WxmpLoginDto;
import com.app.service.wx.WXService;
import com.app.util.HttpUtil;
import com.app.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 功能描述：家长端登录
 *
 * @Author 梁展鹏
 * @Date 2021/1/19 10:13
 */
@Service
public class GuardianLoginService {

    @Autowired
    private GuardianMapper mapper;

    @Autowired
    private GuardianService guardianService;

    @Autowired
    private GuardianChildService guardianChildService;

    @Autowired
    private WXService wxService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HttpUtil httpUtil;

    /**
     * 功能描述：微信小程序用户登陆
     * 官方文档：https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
     *
     * @param WXMPLoginDto
     * @return
     */
    @Transactional
    public WxmpLoginDto wxMpLogin(HttpServletRequest request, WXMPLoginDto WXMPLoginDto) {
        WxCode2SessionDto wxCode2SessionDto = wxService.jscode2session(WXMPLoginDto.getCode());
        if (!Optional.ofNullable(wxCode2SessionDto).isPresent()) {
            throw new RuntimeException("");
        }
        if (StringUtils.isEmpty(wxCode2SessionDto.getSessionKey()) || StringUtils.isEmpty(wxCode2SessionDto.getOpenId())) {
            throw new RuntimeException("");
        }

        /* 判断[微信用户账号]是否初始化 */
        Guardian _guardian;
        Optional<Guardian> optional = guardianService.findByOpenId(wxCode2SessionDto.getOpenId());
        if (!optional.isPresent()) {
            _guardian = new Guardian();
            _guardian.setOpenId(wxCode2SessionDto.getOpenId());
            mapper.insert(_guardian);
        }

        /* 每次登录更新[Guardian]信息, 解密获取[微信用户账号]信息 */
        _guardian = optional.get();
        WxUserInfoDto wxUserInfoDto = wxService.getUserInfo(wxCode2SessionDto.getSessionKey(), WXMPLoginDto.getEncryptedData(), WXMPLoginDto.getIv());
        _guardian.setNickname(wxUserInfoDto.getNickName());
        _guardian.setAvatarUrl(wxUserInfoDto.getAvatarUrl());
        _guardian.setGender(wxUserInfoDto.getGender());
        if (!StringUtils.isEmpty(wxUserInfoDto.getUnionId())) {
            _guardian.setUnionId(wxUserInfoDto.getUnionId());
        }
        mapper.updateById(_guardian);

        /* 生成登录票据并缓存至Redis */
        String token = JwtUtil.createTokenByGuardian(_guardian.getId());
        stringRedisTemplate.opsForValue().set(RedisKeyConstant.JWT_WXMP_SESSION(JwtUtil.getJwtIdByToken(token)), token, JwtUtil.TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);

        /* 构造方法返回参数 */
        WxmpLoginDto dto = new WxmpLoginDto();
        dto.setToken(token);
        if (guardianChildService.findByGuardianId(_guardian.getId()).size() > 0) {
            dto.setState(WxmpLoginDto.StateEnum.SUCCESS).setMessage(WxmpLoginDto.StateEnum.SUCCESS.getName());
        } else {
            dto.setState(WxmpLoginDto.StateEnum.TO_BE_ADDED).setMessage(WxmpLoginDto.StateEnum.TO_BE_ADDED.getName());
        }
        return dto;
    }

}
