package com.hlab.yanalyst.domain.channel; import com.hlab.yanalyst.web.dto.YoutubeSearchResultDto; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** 검색된 Shorts 목록 → 채널별 최고 배율 후보 집계·필터·정렬(순수 로직). */ public final class DiscoveryRanker { private DiscoveryRanker() {} public record Candidate(String channelId, String channelTitle, String thumbnailUrl, Long subscriberCount, String topVideoId, String topVideoTitle, Long topVideoViewCount, double ratio, String region) {} public static List rank(List items, long maxSubscribers, double minRatio, Set excludeChannelIds) { Map best = new LinkedHashMap<>(); for (YoutubeSearchResultDto it : items) { String ch = it.getChannelId(); Long subs = it.getSubscriberCount(); Long views = it.getViewCount(); if (ch == null || subs == null || subs <= 0 || views == null) continue; if (excludeChannelIds.contains(ch)) continue; if (subs > maxSubscribers) continue; double ratio = (double) views / subs; if (ratio < minRatio) continue; Candidate prev = best.get(ch); if (prev == null || ratio > prev.ratio()) { best.put(ch, new Candidate(ch, it.getChannelTitle(), it.getThumbnailUrl(), subs, it.getVideoId(), it.getTitle(), views, ratio, it.getChannelCountry())); } } List out = new ArrayList<>(best.values()); out.sort(Comparator.comparingDouble(Candidate::ratio).reversed()); return out; } }