package com.tzld.piaoquan.recommend.server.service.funnel;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 漏斗 阶段 1-3 单条记录（per pushFrom × videoId）。
 * - 阶段 1 召回: index / score
 * - 阶段 2 过滤: filteredIn / indexNewAfterFilter / filterReasons
 * - 阶段 3 截断: select / truncate
 */
@Data
@NoArgsConstructor
public class RecallVideoEntry {
    private long videoId;
    /**
     * 召回分数。来源 3 类：
     * 1) 大部分 strategy 在 filter 前已有真实 score → 直接传 scoresMap
     * 2) cate 加权 / 位置反推类 → strategy 在 filter 前预算 score (位置反推用 ids.size()-i,
     *    cate 加权用 cateScore*videoScore 同 vid 取 max)。filter 通过的 vid 由
     *    RecallService.syncScoresToFunnel 用 Video.rovScore 覆盖为业务最终值。
     * 3) AppFallback / DouHotFlowPool 类纯列表/随机分召回，score 恒为 0 是正常的。
     */
    private double score;
    private int index;                  // 召回原始位置 (0-based)

    private boolean filteredIn;
    private int indexNewAfterFilter = -1;
    private List<String> filterReasons;  // filteredIn=false 时被哪些 filter 干掉

    /**
     * 阶段 3 截断标记：
     * - SELF  = 该 vid 在该路 top-recallNum 名次内 + 被该路实际贡献给合并列表
     * - OTHER = 在该路 top-recallNum 名次内但被前面 pushFrom 抢走
     * - null  = 未参与截断或在 top-N 之外
     */
    private SelectKind select;
    /** 该路 recallNum 配额 (truncate) */
    private int truncate;

    public RecallVideoEntry(long videoId, double score, int index) {
        this.videoId = videoId;
        this.score = score;
        this.index = index;
    }
}
