package com.ycwl.basic.service.pc.helper;

import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

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

/**
 * 搜索结果合并器
 * 负责合并多个人脸搜索结果
 *
 * @author longbinbin
 * @date 2025-01-31
 */
@Slf4j
@Component
public class SearchResultMerger {

    /**
     * 合并多个搜索结果(默认使用并集模式)
     *
     * @param searchResults 搜索结果列表
     * @return 合并后的结果
     */
    public SearchFaceRespVo merge(List<SearchFaceRespVo> searchResults) {
        return merge(searchResults, 0);
    }

    /**
     * 合并多个搜索结果
     *
     * @param searchResults 搜索结果列表
     * @param mergeMode     合并模式:0-并集,1-交集
     * @return 合并后的结果
     */
    public SearchFaceRespVo merge(List<SearchFaceRespVo> searchResults, Integer mergeMode) {
        SearchFaceRespVo mergedResult = new SearchFaceRespVo();

        if (searchResults == null || searchResults.isEmpty()) {
            return mergedResult;
        }

        List<String> allSearchJsons = new ArrayList<>();
        float maxScore = 0f;
        float maxFirstMatchRate = 0f;
        boolean hasLowThreshold = false;

        // 收集基础信息
        for (SearchFaceRespVo result : searchResults) {
            if (result.getSearchResultJson() != null) {
                allSearchJsons.add(result.getSearchResultJson());
            }
            if (result.getScore() > maxScore) {
                maxScore = result.getScore();
            }
            if (result.getFirstMatchRate() > maxFirstMatchRate) {
                maxFirstMatchRate = result.getFirstMatchRate();
            }
            if (result.isLowThreshold()) {
                hasLowThreshold = true;
            }
        }

        // 根据合并模式处理样本ID
        List<Long> finalSampleIds;
        if (Integer.valueOf(1).equals(mergeMode)) {
            // 模式1:交集 - 只保留所有搜索结果中都出现的样本ID
            finalSampleIds = computeIntersection(searchResults);
            log.debug("使用交集模式合并搜索结果,交集样本数: {}", finalSampleIds.size());
        } else {
            // 模式0:并集(默认) - 收集所有样本ID并去重
            Set<Long> allSampleIds = new LinkedHashSet<>();
            for (SearchFaceRespVo result : searchResults) {
                if (result.getSampleListIds() != null) {
                    allSampleIds.addAll(result.getSampleListIds());
                }
            }
            finalSampleIds = new ArrayList<>(allSampleIds);
            log.debug("使用并集模式合并搜索结果,并集样本数: {}", finalSampleIds.size());
        }

        mergedResult.setSampleListIds(finalSampleIds);
        mergedResult.setSearchResultJson(String.join("|", allSearchJsons));
        mergedResult.setScore(maxScore);
        mergedResult.setFirstMatchRate(maxFirstMatchRate);
        mergedResult.setLowThreshold(hasLowThreshold);

        log.debug("合并搜索结果完成,模式={}, 最终样本数: {}", mergeMode, finalSampleIds.size());

        return mergedResult;
    }

    /**
     * 计算多个搜索结果的交集
     * 返回在所有搜索结果中都出现的样本ID
     *
     * @param searchResults 搜索结果列表
     * @return 交集样本ID列表
     */
    public List<Long> computeIntersection(List<SearchFaceRespVo> searchResults) {
        if (searchResults == null || searchResults.isEmpty()) {
            return new ArrayList<>();
        }

        // 过滤掉空结果
        List<List<Long>> validSampleLists = searchResults.stream()
                .filter(result -> result.getSampleListIds() != null && !result.getSampleListIds().isEmpty())
                .map(SearchFaceRespVo::getSampleListIds)
                .toList();

        if (validSampleLists.isEmpty()) {
            return new ArrayList<>();
        }

        // 如果只有一个有效结果,直接返回
        if (validSampleLists.size() == 1) {
            return new ArrayList<>(validSampleLists.getFirst());
        }

        // 计算交集:从第一个列表开始,保留在所有其他列表中都出现的ID
        Set<Long> intersection = new LinkedHashSet<>(validSampleLists.getFirst());

        for (int i = 1; i < validSampleLists.size(); i++) {
            intersection.retainAll(validSampleLists.get(i));
        }

        return new ArrayList<>(intersection);
    }

    /**
     * 创建直接结果(模式2:不搜索,直接使用用户选择的faceSampleIds)
     *
     * @param faceSampleIds 用户选择的人脸样本ID列表
     * @return 搜索结果对象
     */
    public SearchFaceRespVo createDirectResult(List<Long> faceSampleIds) {
        SearchFaceRespVo result = new SearchFaceRespVo();

        // 直接使用用户选择的faceSampleIds作为结果
        result.setSampleListIds(new ArrayList<>(faceSampleIds));

        // 设置默认值
        result.setScore(1.0f);
        result.setFirstMatchRate(1.0f);
        result.setLowThreshold(false);
        result.setSearchResultJson("");

        log.debug("创建直接结果,样本数: {}", faceSampleIds.size());

        return result;
    }
}
