package com.ytpm.question.monitor;

import cn.hutool.core.util.StrUtil;
import com.ytpm.agent.enums.UserStatusEnum;
import com.ytpm.app.model.YtDyzUser;
import com.ytpm.feign.RiskFeign;
import com.ytpm.question.dao.AppUserMapper;
import com.ytpm.risk.enums.BannedTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * redis 监听器
 */
@Component
@RefreshScope
@Slf4j(topic = "RedisKeyExpire")
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    @Resource
    private AppUserMapper appUserMapper;
    @Resource
    private RiskFeign riskFeign;

    @Value("${spring.application.name:}")
    private String applicationName;

    private static final String FLAG_LOCK = "lock";
    private static final String FLAG_UNLOCK = "unlock";

    /**
     *
     * @param listenerContainer must not be {@literal null}.
     */
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 监听redis过期的 key 进行处理
     */
    @Override
    public void onMessage(@NonNull Message message, byte[] pattern) {
        String key = String.valueOf(message);
        // 全局监听
        if (key.startsWith("lock_") || key.startsWith("unlock_")) {
            String[] arr = key.split("_");
            if (arr.length < 2) {
                return;
            }
            handleUserLock(key, arr[1], arr[0]);
        }
        // 仅限自身服务的监听
        String serviceKey = StrUtil.replace(applicationName, "-service", "");
        if (key.startsWith(serviceKey)) {
            String[] arr = key.split("_");
            if (arr.length < 3) {
                return;
            }
            handleUserLock(key, arr[2], arr[1]);
        }
    }

    private void handleUserLock(String key, String userId, String flag) {
        YtDyzUser dyzUser = appUserMapper.selectPrimaryKey(userId);
        if (Objects.nonNull(dyzUser)) {
            log.info("App-Service 发现预定风控用户：{}", key);
            // 用户锁定
            if (FLAG_LOCK.equals(flag)) {
                lockUser(dyzUser, UserStatusEnum.RISK.getCode());
            }
            // 用户解锁
            if (FLAG_UNLOCK.equals(flag)) {
                unLockUser(dyzUser);
            }
        }
    }

    /**
     * 锁定用户
     */
    private void lockUser(YtDyzUser dyzUser, Integer userStatus) {
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(dyzUser.getUserId());
        newUser.setUserStatus(userStatus);
        newUser.setRiskReason(BannedTypeEnum.CHANNEL.getDesc() + "禁止登录");
        appUserMapper.updateUser(newUser);
    }

    /**
     * 解锁用户
     */
    private void unLockUser(YtDyzUser dyzUser) {
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(dyzUser.getUserId());
        newUser.setUserStatus(UserStatusEnum.NORMAL.getCode());
        appUserMapper.updateUser(newUser);
        riskFeign.addBlockingRecord(dyzUser.getUserId());
    }

}