package com.dk.mdm.infrastructure.util;

import com.alibaba.fastjson.JSONObject;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.model.vo.core.StaffEntity;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.util.oauth.AESSecurityUtil;
import com.dk.common.util.oauth.JwtUtil;
import com.dk.mdm.infrastructure.convert.mst.StaffConvert;
import com.dk.mdm.mapper.mst.StaffMapper;
import com.dk.common.model.response.mst.StaffResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @desc   : AuthUtils
 * @author : 洪旭东
 * @date   : 2022-06-07 16:13
 */
@Component("MdmAuthUtils")
@Slf4j
public class AuthUtils {

    @Value("${aes-key}")
    private String AESKey;

    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private StaffConvert staffConvert;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     * @desc   : 查询当前用户
     * @author : 洪旭东
     * @date   : 2022-06-07 16:19
     */
    public StaffEntity getStaff(){
        return getStaff(httpServletRequest.getHeader("Authorization"));
    }
    /**
     * @date_time 2021-12-23 09:25
     * @author H_x_d
     * @description 通过token获取用户信息,如果redis中失效，重新查询
     * @return com.dongke.auth.pojo.User
     */
    public StaffEntity getStaff(String token){
        if (token==null) {
            return null;
        }
        try {
            String[] tokens = token.split(" ");
            String decrypt = AESSecurityUtil.decrypt(AESKey, tokens[1]);
            String userId = JwtUtil.getUserId(decrypt);
            log.info("staffId=>{}",userId);
            String appCode = JwtUtil.getAppCode(decrypt);
            log.info("appCode=>{}",appCode);
            String cpId = JwtUtil.getCpId(decrypt);
            log.info("cpId=>{}",cpId);
            String cpCode = JwtUtil.getCpCode(decrypt);
            log.info("cpCode=>{}",cpCode);
            String key = Constant.RedisConstant.REDIS_USER_LOGIN.getName() + '_' + userId + '_' + appCode;
            String json = stringRedisTemplate.opsForValue().get(key);
            if (json==null){
                return null;
            }else{
                StaffEntity staffEntity = JSONObject.parseObject(JSONObject.toJSONString(JSONObject.parseObject(json)), StaffEntity.class);
                staffEntity.setAppCode(appCode);
                staffEntity.setCpCode(cpCode);
                staffEntity.setCpId(Integer.parseInt(cpId) );
                return staffEntity;
            }
        } catch (Exception e) {
            log.error(e.toString(),e);
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(),"解析accessToken失败");
        }
    }
    /**
     * @desc   : 清除redis用户信息
     * @author : 周兴
     * @date   : 2023/1/6 15:46
     */
    public void cleanStaff(){
        String appCode = JwtUtil.getAppCode(httpServletRequest);
        cleanStaff(Constant.RedisConstant.REDIS_STAFF.getName() + appCode + Constant.StringConstant.SYSTEM_MAGIN_LINE.getName() + getStaff().getStaffId());
    }
    /**
     * @desc   : 清除redis用户信息
     * @author : 周兴
     * @date   : 2023/1/6 15:46
     */
    public void cleanStaff(Long userId){
        String appCode = JwtUtil.getAppCode(httpServletRequest);
        stringRedisTemplate.delete(Constant.RedisConstant.REDIS_STAFF.getName() + appCode + Constant.StringConstant.SYSTEM_MAGIN_LINE.getName() + userId);
    }
    /**
     * @desc   : 清除redis用户信息
     * @author : 周兴
     * @date   : 2023/1/6 15:46
     */
    public void cleanStaff(String key){
        stringRedisTemplate.delete(key);
    }
    /**
     * @desc   : 清除登录用户信息
     * @author : 周兴
     * @date   : 2023/1/5 13:08
     */
    public void cleanLoginStaff(){
        StaffEntity staffEntity = getStaff();
        cleanLoginStaff(Constant.RedisConstant.REDIS_LOGIN.getName() + Constant.StringConstant.SYSTEM_MAGIN_LINE.getName() + staffEntity.getStaffCode());
    }
    /**
     * @desc   : 清除缓存
     * @author : 周兴
     * @date   : 2023/1/5 13:09
     */
    public void cleanLoginStaff(String key){
        stringRedisTemplate.delete(key);
    }
    /**
     * @date_time 2021-12-23 09:22
     * @author H_x_d
     * @description 保存用户信息 + 权限ID 到Redis
     * @return User
     */
    public StaffEntity saveStaff(String staffId, String cpCode, String appCode){
        StaffResponse staff = staffMapper.selectById(staffId);
        StaffEntity staffEntity = staffConvert.convertToEntity(staff);
        if (staffEntity!=null) {
            staffEntity.setAppCode(appCode);
            staffEntity.setCpCode(cpCode);
            saveStaff(staffEntity);
        }
        return staffEntity;
    }
    /**
     * @desc   : 保存员工
     * @author : 周兴
     * @date   : 2023/1/6 15:18
     */
    public StaffEntity saveStaff(StaffEntity staff){
        if(staff != null ){
            String userId = staff.getWxUserId();
            String appCode = staff.getAppCode();
            String key = Constant.RedisConstant.REDIS_USER_LOGIN.getName() + '_' + userId + '_' + appCode;
            String mapStr = stringRedisTemplate.opsForValue().get(key);
            Map<String,Object> userMap = JSONObject.parseObject(mapStr);
            if (userMap != null) {
                userMap.put("staffId",staff.getStaffId());
                userMap.put("staffCode",staff.getStaffCode());
                userMap.put("cpId",staff.getCpId());
                userMap.put("cpCode",staff.getCpCode());
                userMap.put("orgId",staff.getOrgId());
                userMap.put("opUpdateTime",LocalDateTime.now());
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(userMap));
            }
        }
        return staff;
    }
}
