package com.mmc.iuav.user.auth;

import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.mmc.iuav.auth.JwtConstant;
import com.mmc.iuav.auth.JwtUtil;
import com.mmc.iuav.user.dao.RoleDao;
import com.mmc.iuav.user.entity.RoleInfoDO;
import com.mmc.iuav.user.enums.UserTypeEnums;
import com.mmc.iuav.user.model.dto.LoginSuccessDTO;
import com.mmc.iuav.user.model.vo.*;
import com.mmc.iuav.user.service.CompanyService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: zj
 * @Date: 2023/8/14 16:48
 */
@Component
public class AuthHandler {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public AppUserSucVO addAppLoginCache(UserAccountVO userAccountVO) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(JwtConstant.USER_ACCOUNT_ID, userAccountVO.getId());
        map.put(JwtConstant.TOKEN_TYPE, JwtConstant.IUAV_TOKEN);
        String token = JwtUtil.createJwt(map);
        LoginSuccessDTO loginSuccessDTO = LoginSuccessDTO.builder().token(token).openId(userAccountVO.getOpenId()).userAccountId(userAccountVO.getId()).uid(userAccountVO.getId() + "")
                .userName(userAccountVO.getUserName()).nickName(userAccountVO.getNickName()).phoneNum(userAccountVO.getPhoneNum()).portType(UserTypeEnums.APP.getType()).build();
        stringRedisTemplate.setValueSerializer(RedisSerializer.json());
        stringRedisTemplate.opsForValue().set(
                token, new Gson().toJson(loginSuccessDTO),
                JwtConstant.EXPIRATION, TimeUnit.MILLISECONDS);

        AppUserSucVO appUserSucVO = AppUserSucVO.builder().token(token).uid(userAccountVO.getUid()).phoneNum(userAccountVO.getPhoneNum())
                .nickName(userAccountVO.getNickName()).userAccountId(userAccountVO.getId()).portType(UserTypeEnums.APP.getType()).build();
        return appUserSucVO;
    }
    public WebUserSucVO addWebLoginCache(UserAccountVO userAccountVO) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(JwtConstant.USER_ACCOUNT_ID, userAccountVO.getId());
        map.put(JwtConstant.TOKEN_TYPE, JwtConstant.IUAV_TOKEN);
        String token = JwtUtil.createJwt(map);
        LoginSuccessDTO loginSuccessDTO = LoginSuccessDTO.builder().token(token).userAccountId(userAccountVO.getId())
                .phoneNum(userAccountVO.getPhoneNum()).portType(UserTypeEnums.APP.getType()).build();
        stringRedisTemplate.setValueSerializer(RedisSerializer.json());
        stringRedisTemplate.opsForValue().set(
                token, new Gson().toJson(loginSuccessDTO),
                JwtConstant.EXPIRATION, TimeUnit.MILLISECONDS);
        WebUserSucVO webUserSucVO = WebUserSucVO.builder().token(token).phoneNum(userAccountVO.getPhoneNum())
                .nickName(userAccountVO.getNickName()).userAccountId(userAccountVO.getId()).build();
        return webUserSucVO;
    }

    public LoginSuccessDTO addPcLoginCache(BackUserAccountVO user) {
        // 查询单位信息
        CompanyInfoVO companyInfoVO = companyService.getCompanyInfoByAppLoginUserId(user.getId());
        companyInfoVO.setLeader(1);
        // 角色信息
        RoleInfoDO roleInfoDO = roleDao.getRoleInfoByUserId(user.getId());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(JwtConstant.USER_ACCOUNT_ID, user.getId());
        map.put(JwtConstant.TOKEN_TYPE, JwtConstant.M_TOKEN);
        String token = JwtUtil.createJwt(map);
        LoginSuccessDTO loginSuccessDTO = LoginSuccessDTO.builder().token(token).userAccountId(user.getId()).accountNo(user.getAccountNo()).uid(user.getId() + "")
                .userName(user.getUserName()).nickName(user.getUserName()).phoneNum(user.getPhoneNum()).portType(UserTypeEnums.PC.getType())
                .companyInfoVO(companyInfoVO == null ? null : companyInfoVO)
                .roleInfo(roleInfoDO.buildRoleInfoDTO()).build();
        stringRedisTemplate.setValueSerializer(RedisSerializer.json());
        stringRedisTemplate.opsForValue().set(
                token, new Gson().toJson(loginSuccessDTO),
                JwtConstant.EXPIRATION, TimeUnit.MILLISECONDS);
        // 标记
        stringRedisTemplate.opsForValue().set(
                UserTypeEnums.PC.getTypeCode() + "_TOKEN_" + user.getId(), token,
                JwtConstant.EXPIRATION, TimeUnit.MILLISECONDS);
        return loginSuccessDTO;
    }

    /**
     * @param userAccountId
     * @description 删除小程序用户token
     * redis key :APP_TOKEN_{ID}
     */
    public void removeAppLoginCache(Integer userAccountId) {
        String appUserToken = stringRedisTemplate.opsForValue().get(UserTypeEnums.APP.getTypeCode() + "_TOKEN_" + userAccountId);
        if (!StringUtils.isBlank(appUserToken)) {
            stringRedisTemplate.delete(appUserToken);
            stringRedisTemplate.delete(UserTypeEnums.APP.getTypeCode() + "_TOKEN_" + userAccountId);
        }
    }

    /**
     * @param backUserAccountId
     * @description 删除PC用户token
     * redis key :PC_TOKEN_{ID}
     */
    public void removePcLoginCache(Integer backUserAccountId) {
        String pcUserToken = stringRedisTemplate.opsForValue().get(UserTypeEnums.PC.getTypeCode() + "_TOKEN_" + backUserAccountId);
        if (!StringUtils.isBlank(pcUserToken)) {
            stringRedisTemplate.delete(pcUserToken);
            stringRedisTemplate.delete(UserTypeEnums.PC.getTypeCode() + "_TOKEN_" + backUserAccountId);
        }
    }
}
