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

import com.tzld.piaoquan.recommend.server.model.Tab;
import com.tzld.piaoquan.recommend.server.model.Video;
import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component
public class PersonalizationTabRovnRecallStrategy implements RecallStrategy {

    @Autowired
    private FilterService filterService;
    @Autowired
    @Qualifier("redisTemplate")
    public RedisTemplate<String, String> redisTemplate;

    public static final String PUSH_FROM = "personalized_tab_rovn_recall";

    private static final String redisKeyFormat = "personalized_tab_rovn_recall:%s";

    @Override
    public List<Video> recall(RecallParam param) {
        List<Video> result = new ArrayList<>();

        Tab tab = param.getTab();
        if (Objects.isNull(tab) || StringUtils.isBlank(tab.getKey())) {
            return result;
        }

        String key = String.format(redisKeyFormat, tab.getKey());
        String value = redisTemplate.opsForValue().get(key);
        if (StringUtils.isBlank(value)) {
            return result;
        }
        List<String[]> collect = Arrays.stream(value.split("\t"))
                .map(i -> i.split(","))
                .collect(Collectors.toList());
        if (collect.size() != 2) {
            return result;
        }
        String[] vids = collect.get(0);
        String[] scores = collect.get(1);
        if (vids.length != scores.length) {
            return result;
        }

        Map<Long, Double> vidAndScoreMap = new HashMap<>();
        for (int i = 0; i < vids.length; i++) {
            vidAndScoreMap.put(Long.parseLong(vids[i]), Double.parseDouble(scores[i]));
        }

        FilterParam filterParam = FilterParamFactory.create(param, new ArrayList<>(vidAndScoreMap.keySet()), pushFrom(), vidAndScoreMap);
        FilterResult filterResult = filterService.filter(filterParam);
        if (Objects.isNull(filterResult) || CollectionUtils.isEmpty(filterResult.getVideoIds())){
            return result;
        }
        for (Long videoId : filterResult.getVideoIds()) {
            Video video = new Video();
            video.setVideoId(videoId);
            video.setRovScore(vidAndScoreMap.get(videoId));
            video.setPushFrom(pushFrom());

            result.add(video);
        }

        return result;
    }

    @Override
    public String pushFrom() {
        return PUSH_FROM;
    }
}
