package com.tanpu.community.service;

import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.ThemeAnalysDO;
import com.tanpu.community.api.beans.resp.PythonResponse;
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.util.ConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

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

@Slf4j
@Service
public class RecommendService {

    @Value("${recommend.python.enable}")
    public String enablePython;


    @Value("${recommend.python.url}")
    public String pythonUrl;
    @Value("${recommend.ratio.hot}")
    public Integer hotRatio;
    @Value("${recommend.ratio.new}")
    public Integer newRatio;
    @Value("${recommend.ratio.python}")
    public Integer pythonRatio;


    @Autowired
    private RankService rankService;

    @Autowired
    private ThemeService themeService;

    @Autowired
    private VisitSummaryService visitSummaryService;

    // 最新
    private List<ThemeAnalysDO> recentThemeList = new ArrayList<>();
    // 推荐
    private Map<String, List<String>> recommondList = new HashMap<>();
    // 用户已经看过的
    private Map<String, Set<String>> returnedIdsMap = new HashMap<>();

    public List<String> getRecommendThemes(String lastId, Integer pageSize, String userId) {
        //最热话题,剔除当前用户的主题
        List<String> hotThemeIds = rankService.getHotestThemes().stream()
                .filter(o -> !userId.equals(o.getAuthorId()))
                .map(ThemeAnalysDO::getThemeId)
                .collect(Collectors.toList());

        //最新话题,剔除当前用户的主题
        List<String> newThemeIds = this.getRecentThemeList().stream()
                .filter(o -> !userId.equals(o.getAuthorId()))
                .map(ThemeAnalysDO::getThemeId)
                .collect(Collectors.toList());

        //推荐话题
        List<String> recThemeIds = getPythonRecommendList(userId);

        // 混合 如果重新搜索,则刷新返回id
        Set<String> returnedIds = (StringUtils.isEmpty(lastId)) || !returnedIdsMap.containsKey(userId)
                || returnedIdsMap.get(userId) == null ?
                new HashSet<>() : returnedIdsMap.get(userId);
        List<String> result = new ArrayList<>();
        getResultList(hotThemeIds, 0, newThemeIds, 0, recThemeIds, 0, returnedIds, result, pageSize, userId);
        result = result.stream().limit(pageSize).collect(Collectors.toList());
        //记录已返回主题id
        if (StringUtils.isEmpty(lastId)) {
            returnedIdsMap.put(userId, new HashSet<>(result));
        } else {
            HashSet<String> newSet = new HashSet<>();
            newSet.addAll(returnedIdsMap.get(userId));
            newSet.addAll(result);
            returnedIdsMap.put(userId, newSet);
        }
        return result;
    }

    public List<ThemeAnalysDO> getRecentThemeList() {
        if (recentThemeList.size() == 0) {
            refreshNewestThemes();
        }
        return recentThemeList;
    }

    //从数据库查询最新主题
    public void refreshNewestThemes() {
        List<ThemeEntity> themeEntities = themeService.queryLatestThemes(100);
        this.recentThemeList = ConvertUtil.themeEntityToAnalysDOs(themeEntities);
    }

    //查询python计算推荐列表
    public List<String> getPythonRecommendList(String userId) {
        if (recommondList.containsKey(userId)) {
            return recommondList.get(userId);
        } else {
            return refreshPythonRecommendList(userId);
        }
    }


    //HTTP查询python推荐主题
    public List<String> refreshPythonRecommendList(String userId) {
        if (!"true".equals(enablePython)) {
            return Collections.emptyList();
        }
        RestTemplate restTemplate = new RestTemplate();
        HashMap<String, String> param = new HashMap<>();
        param.put("user_id", userId);
        try {
            String response = restTemplate.getForObject(pythonUrl, String.class, param);
            PythonResponse pythonResponse = JsonUtil.toBean(response, PythonResponse.class);
            recommondList.put(userId, pythonResponse.getAttributes());
            return pythonResponse.getAttributes();
        } catch (Exception e) {
            log.error("调用python失败");
            return Collections.emptyList();
        }


    }

    private List<String> mergeList(List<String> hotThemeIds, List<String> newThemeIds, List<String> recThemeIds) {
        ArrayList<String> result = new ArrayList<>();
        Integer hotIdx = 0;
        Integer newIdx = 0;
        Integer recIdx = 0;
        while (hotThemeIds.size() > hotIdx || newThemeIds.size() > newIdx || recThemeIds.size() > recIdx) {
            int hotTimes = hotRatio;
            int newTimes = newRatio;
            int recTimes = pythonRatio;
            String id;
            while (hotTimes > 0 && hotThemeIds.size() > hotIdx) {
                id = hotThemeIds.get(hotIdx);
                result.add(id);
                hotIdx++;
                hotTimes--;
            }
            while (newTimes > 0 && newThemeIds.size() > newIdx) {
                id = newThemeIds.get(newIdx);
                result.add(id);
                newIdx++;
                newTimes--;
            }
            while (recTimes > 0 && recThemeIds.size() > recIdx) {
                id = recThemeIds.get(recIdx);
                result.add(id);
                recIdx++;
                recTimes--;
            }

        }
        return result;
    }

    private void getResultList(List<String> hotThemeIds, Integer hotTag, List<String> newThemeIds, Integer newTag, List<String> recThemeIds, Integer recTag, Set<String> returnedIds, List<String> result, Integer pageSize, String userId) {

        if (hotThemeIds.size() <= hotTag && newThemeIds.size() <= newTag && recThemeIds.size() <= recTag) {
            //所有列表已循环结束,返回
            return;
        }

        while (result.size() < pageSize * 1.5) {
            int hotTimes = hotRatio;
            int newTimes = newRatio;
            int recTimes = pythonRatio;
            String id;
            while (hotTimes > 0 && hotThemeIds.size() > hotTag) {
                id = hotThemeIds.get(hotTag);
                if (!returnedIds.contains(id)) {
                    result.add(id);
                    returnedIds.add(id);
                }
                hotTag++;
                hotTimes--;
            }
            while (newTimes > 0 && newThemeIds.size() > newTag) {
                id = newThemeIds.get(newTag);
                if (!returnedIds.contains(id)) {
                    result.add(id);
                    returnedIds.add(id);
                }
                newTag++;
                newTimes--;
            }
            while (recTimes > 0 && recThemeIds.size() > recTag) {
                id = recThemeIds.get(recTag);
                if (!returnedIds.contains(id)) {
                    result.add(id);
                    returnedIds.add(id);
                }
                recTag++;
                recTimes--;
            }

        }
        //去重已看过(查看正文)
        result = visitSummaryService.filterUserNotVisited(userId, result);

        if (result.size() < pageSize) {
            getResultList(hotThemeIds, hotTag, newThemeIds, newTag, recThemeIds, recTag, returnedIds, result, pageSize, userId);
        }
    }


}