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

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
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.RegionFilterService;
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.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sunxy
 */
@Slf4j
public abstract class AbstractNewContentVideoRecallStrategy implements RecallStrategy {

    @Resource
    protected RedisTemplate<String, String> redisTemplate;
    @Autowired
    private RegionFilterService filterService;

    @Value("${flow.pool.recent.top.video.daily.time.range:}")
    private String timeRangeJson;

//    @Autowired
//    protected RegionFilterService filterService;

    @Override
    public List<Video> recall(RecallParam param) {
//        boolean checkIfInTimeRange = checkIfInTimeRange();
//        if (!checkIfInTimeRange) {
//            return Collections.emptyList();
//        }
        String key = recallKey(param);
        if (StringUtils.isBlank(key)) {
            return Collections.emptyList();
        }
        Object result = redisTemplate.opsForValue().get(key);
        if (result == null) {
            return Collections.emptyList();
        }
        try {
            List<Long> videoIdList = JSONObject.parseArray(result.toString(), Long.class);
            Map<Long, Double> videoBigSmall = new HashMap<>(videoIdList.size());
            double score = 1000D;
            for (Long id : videoIdList){
                videoBigSmall.put(id, score--);
            }
            // 3 召回内部过滤
            FilterParam filterParam = FilterParamFactory.create(param, videoIdList);
            FilterResult filterResult = filterService.filter(filterParam);
            List<Video> videosResult = new ArrayList<>();
            if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
                filterResult.getVideoIds().forEach(vid -> {
                    Video video = new Video();
                    video.setVideoId(vid);
                    video.setAbCode(param.getAbCode());
                    video.setRovScore(videoBigSmall.getOrDefault(video.getVideoId(), 0.0D));
                    video.setPushFrom(pushFrom());
                    videosResult.add(video);
                });
            }
            videosResult.sort(Comparator.comparingDouble(o -> -o.getRovScore()));
            return videosResult;
        } catch (Exception e) {
            log.error("recall error, key={}, result={}", key, result, e);
        }
        return Collections.emptyList();
    }

    protected boolean checkIfInTimeRange() {
        if (StringUtils.isBlank(timeRangeJson)) {
            return false;
        }
        try {
            List<String> timeRangeStrList = JSONObject.parseArray(timeRangeJson, String.class);
            if (CollectionUtils.isEmpty(timeRangeStrList)) {
                return false;
            }
            for (String timeRangeStr : timeRangeStrList) {
                String[] timeRange = timeRangeStr.split("~");
                if (timeRange.length != 2) {
                    continue;
                }
                // 4:00~15:00
                String startTime = timeRange[0];
                String endTime = timeRange[1];
                String nowTime = DateFormatUtils.format(new Date(), "HH:mm");
                if (nowTime.compareTo(startTime) >= 0 && nowTime.compareTo(endTime) <= 0) {
                    return true;
                }
            }

        } catch (Exception e) {
            log.error("checkIfInTimeRange error, timeRangeJson={}", timeRangeJson, e);
        }
        return false;
    }

    protected abstract String recallKey(RecallParam param);
}
