package com.ytpm.middle.monitor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ytpm.agent.view.AgentAppView;
import com.ytpm.feign.AppFeign;
import com.ytpm.middle.dao.ApkMapper;
import com.ytpm.middle.util.FeignClientInvoker;
import com.ytpm.middle.util.RedisUtil;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ytpm.middle.view.AppRankingListVO;
import com.ytpm.middle.view.DashboardRankingListVO;
import com.ytpm.middle.view.UserRankingListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Component;

import javax.annotation.Resource;

/**
 * redis 监听器
 */
@Slf4j
@Component
@RefreshScope
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
 

    @Resource
    RedisUtil redisUtil ;
    @Resource
    ApkMapper apkMapper;
    @Autowired
    private FeignClientInvoker feignInvoker;
    @Value("${ranking.expire}")
    private long rankingExpire;
    @Value("${ranking.limit}")
    private int rankingLimit;
    private static final String RANKING_KEY = "yt_ranking";
 
    /**
     * Creates new {@link } for {@code __keyevent@*__:expired} messages.
     *
     * @param listenerContainer must not be {@literal null}.
     */
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
 
    /**
     * 监听redis过期的 key 进行处理
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String key = String.valueOf(message);
        System.err.println("发现过期的key："+key);
        if("yt_ranking3".equals(key)){
             getRankingAnCache(3);
        }
        if("yt_ranking2".equals(key)){
            getRankingAnCache(2);
        }
        if("yt_ranking1".equals(key)){
            getRankingAnCache(1);
        }
    }

    /**
     * 查询排行榜并缓存
     */
    private void getRankingAnCache(Integer sortBy) {
        List<AgentAppView> views = apkMapper.queryAll();
        List<String> serveList = views.stream().map(AgentAppView::getServiceName).distinct().collect(Collectors.toList());
        DashboardRankingListVO rankingVO = new DashboardRankingListVO();
        List<AppRankingListVO> appRankingList = new ArrayList<>();
        List<UserRankingListVO> userRankingList = new ArrayList<>();
        for (String serve : serveList) {
            Object o = feignInvoker.invoke(serve,"queryRankingList",sortBy,rankingLimit);
            DashboardRankingListVO vo = JSONObject.parseObject(JSON.toJSONString(o), DashboardRankingListVO.class);
            appRankingList.addAll(vo.getAppRankingList());
            userRankingList.addAll(vo.getUserRankingList());
        }
        //设置应用名称
        Map<String, String> collect = views.stream().collect(Collectors.toMap(AgentAppView::getAppId, AgentAppView::getAppName));
        for (AppRankingListVO vo : appRankingList) {
            vo.setAppName(collect.get(vo.getAppId()));
        }
        rankingVO.setUserRankingList(userRankingList.stream().sorted(Comparator.comparing(UserRankingListVO::getTotalIncome)
                .reversed()).limit(5).collect(Collectors.toList()));
        rankingVO.setAppRankingList(appRankingList.stream().sorted(Comparator.comparing(AppRankingListVO::getTotalRevenue)
                .reversed()).limit(5).collect(Collectors.toList()));
        redisUtil.setTimeOutMinutesStr(RANKING_KEY+sortBy, JSON.toJSONString(rankingVO),rankingExpire);
    }
}