package com.tzld.piaoquan.recommend.server.service.rank.strategy;


import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import com.tzld.piaoquan.recommend.server.model.Video;
import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
import com.tzld.piaoquan.recommend.server.service.rank.RankResult;
import com.tzld.piaoquan.recommend.server.service.rank.RankService;
import com.tzld.piaoquan.recommend.server.service.rank.extractor.RankExtractorFeature;
import com.tzld.piaoquan.recommend.server.service.rank.processor.RankProcessorDensity;
import com.tzld.piaoquan.recommend.server.service.rank.processor.RankProcessorTagFilter;
import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
import com.tzld.piaoquan.recommend.server.util.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangbo
 * @desc 地域召回融合
 */
@Service
@Slf4j
public class RankStrategy4RegionMerge extends RankService {

    public void duplicate(Set<Long> setVideo, List<Video> videos){
        Iterator<Video> iterator = videos.iterator();
        while(iterator.hasNext()){
            Video v = iterator.next();
            if (setVideo.contains(v.getVideoId())){
                iterator.remove();
            }else{
                setVideo.add(v.getVideoId());
            }
        }
    }
    @Override
    public List<Video> mergeAndRankRovRecall(RankParam param) {
        //-------------------地域内部融合+去重复-------------------
        List<Video> rovRecallRank = new ArrayList<>();
        List<Video> v1 = extractAndSort(param, RegionRealtimeRecallStrategyV1.PUSH_FORM);
        List<Video> v2 = extractAndSort(param, RegionRealtimeRecallStrategyV2.PUSH_FORM);
        List<Video> v3 = extractAndSort(param, RegionRealtimeRecallStrategyV3.PUSH_FORM);
        List<Video> v4 = extractAndSort(param, RegionRealtimeRecallStrategyV4.PUSH_FORM);
        Set<Long> setVideo = new HashSet<>();
        this.duplicate(setVideo, v1);
        this.duplicate(setVideo, v2);
        this.duplicate(setVideo, v3);
        this.duplicate(setVideo, v4);
        //-------------------地域 sim returnv2 融合+去重复-------------------
        List<Video> v5 = extractAndSort(param, SimHotVideoRecallStrategy.PUSH_FORM);
        List<Video> v6 = extractAndSort(param, ReturnVideoRecallStrategy.PUSH_FORM);
        this.duplicate(setVideo, v5);
        this.duplicate(setVideo, v6);

//        rovRecallRank.addAll(v1);
//        rovRecallRank.addAll(v2);
//        rovRecallRank.addAll(v3);
//        rovRecallRank.addAll(v4);
//        rovRecallRank.addAll(v5);
//        rovRecallRank.addAll(v6);

        rovRecallRank.addAll(v1.subList(0, Math.min(20, v1.size())));
        rovRecallRank.addAll(v2.subList(0, Math.min(15, v2.size())));
        rovRecallRank.addAll(v3.subList(0, Math.min(10, v3.size())));
        rovRecallRank.addAll(v4.subList(0, Math.min(5, v4.size())));
        rovRecallRank.addAll(v5.subList(0, Math.min(10, v5.size())));
        rovRecallRank.addAll(v6.subList(0, Math.min(10, v6.size())));

        //-------------------排-------------------
        //-------------------序-------------------
        //-------------------逻-------------------
        //-------------------辑-------------------
        List<String> videoIdKeys = rovRecallRank.stream()
                .map(t -> param.getRankKeyPrefix() + t.getVideoId())
                .collect(Collectors.toList());
        List<String> videoScores = this.redisTemplate.opsForValue().multiGet(videoIdKeys);
        if (CollectionUtils.isNotEmpty(videoScores)
                && videoScores.size() == rovRecallRank.size()) {
            for (int i = 0; i < videoScores.size(); i++) {
                rovRecallRank.get(i).setSortScore(NumberUtils.toDouble(videoScores.get(i), 0.0));
            }
            Collections.sort(rovRecallRank, Comparator.comparingDouble(o -> -o.getSortScore()));
        }
        return rovRecallRank;
    }

}
