package com.tzld.piaoquan.recommend.server.common.base;

import com.google.common.collect.Maps;
import com.tzld.piaoquan.recommend.feature.domain.video.base.ItemFeature;
import com.tzld.piaoquan.recommend.server.framework.candidiate.CandidateInfo;
import com.tzld.piaoquan.recommend.server.model.Video;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Data
public class RankItem implements Comparable<RankItem> {

    // featureMap中保存所有的特征
    public Map<String, String> featureMap = new HashMap<>();
    public Map<String, String> norFeatureMap = new HashMap<>();
    // 所有特征，包括视频、用户等等
    public Map<String, String> allFeatureMap = new HashMap<>();
    public Map<String, Double> featureMapDouble = new HashMap<>();
    public String id;
    public Map<String, Double> scoresMap = new HashMap<>();
    public Map<String, String> itemBasicFeature = new HashMap<>();
    public Map<String, Map<String, Double>> itemRealTimeFeature = new HashMap<>();
    public Map<String, Map<String, Double>> itemRealTimeRootFeature = new HashMap<>();
    public long videoId;
    private double score; // 记录最终的score
    private Video video;
    private double scoreRos; // 记录ros的score
    private double scoreStr; // 记录str的score
    private double scoreRov; // 记录rov的score
    private double vovScore; // 记录vov的score

    // 记录Item侧用到的特征
    private ItemFeature itemFeature;

    // 记录召回信息
    private String queue;
    private CandidateInfo candidateInfo;
    private List<CandidateInfo> candidateInfoList = new ArrayList<>(); // 兼容多个召回key命中

    // merge信息
    private List<String> mergeQueuePath = new ArrayList<>();
    private List<String> mergeDecisionLabels = new ArrayList<>();

    // 多样性过滤因子
    // 排序因子
    private Map<String, Double> rankItemCategories = Maps.newHashMap();
    private Map<String, Double> rankItemSubCategories = Maps.newHashMap();
    private Map<String, Double> rankItemUserTags = Maps.newHashMap();
    private Map<String, Double> rankItemTitleTags = Maps.newHashMap();


    // 排序侧信息
    private Map<String, Double> rankerScore = Maps.newHashMap();
    private Map<String, Integer> rankerIndex = Maps.newHashMap();

    public RankItem() {

    }


    public RankItem(Video video) {
        this.id = String.valueOf(video.getVideoId());
        this.videoId = video.getVideoId();
        this.score = 0.0;
        this.scoreRos = 0.0;
        this.scoreStr = 0.0;
        this.video = video;
    }

    public RankItem(Long videoId) {
        this.id = videoId.toString();
        this.videoId = videoId;
        this.score = 0.0;
    }

    public RankItem(RankItem other) {
        this.id = other.id;
        this.videoId = other.videoId;
        this.score = other.score;
        this.scoreRos = other.scoreRos;
        this.scoreStr = other.scoreStr;
        this.video = other.video;

        // merge queue
        this.queue = other.queue;
        if (other.getMergeQueuePath() != null)
            this.mergeQueuePath.addAll(other.getMergeQueuePath());
        if (other.getMergeDecisionLabels() != null)
            this.mergeDecisionLabels.addAll(other.getMergeDecisionLabels());


        // candidateinfo
        this.candidateInfo = other.getCandidateInfo() != null ? other.getCandidateInfo().deepcopy() : null;
        if (other.getCandidateInfoList() != null) {
            for (CandidateInfo tmpCandidateInfo : other.getCandidateInfoList()) {
                this.candidateInfoList.add(tmpCandidateInfo.deepcopy());
            }
        }


    }


    @Override
    public int compareTo(RankItem o) {
        if (o == null) {
            return -1;
        }
        if (score > o.score) {
            return -1;
        } else if (score < o.score) {
            return 1;
        } else {
            return 0;
        }
    }

    public RankItem deepcopy() {
        return new RankItem(this);
    }


    public void addToCandidateInfoList(CandidateInfo candidateInfo) {
        this.candidateInfoList.add(candidateInfo);
    }


    public void addMergeQueuePath(String mergeQueueName) {
        this.mergeQueuePath.add(mergeQueueName);
    }

    public void addMergeDecisionLabel(String label) {
        this.mergeDecisionLabels.add(label);
    }

    public void putRankerScore(String rankerName, Double rankerScore) {
        this.rankerScore.put(rankerName, rankerScore);
    }

    public String getLastMergeQueueName() {
        int pathSize = this.mergeQueuePath.size();
        if (pathSize > 0) {
            return this.mergeQueuePath.get(pathSize - 1);
        } else {
            return getCandidateInfo().getCandidateQueueName();
        }
    }


}
