package com.tzld.piaoquan.ad.engine.service.score.strategy;


import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
import com.tzld.piaoquan.ad.engine.commons.util.ComparatorUtil;
import com.tzld.piaoquan.ad.engine.commons.util.ObjUtil;
import com.tzld.piaoquan.ad.engine.commons.util.WeightRandom;
import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 人工权重排序，作为最后的兜底
 */
@Slf4j
@Component
public class RankStrategyByWeight extends RankStrategyBasic {

    @Override
    public List<AdRankItem> adItemRank(RankRecommendRequestParam request, ScoreParam scoreParam) {
        Set<String> noApiAdVerIds = getNoApiAdVerIds();

        List<AdPlatformCreativeDTO> creativeDTOS = request.getAdIdList();

        List<WeightRandom.ItemWithWeight<AdRankItem>> creativeItemWeights = new ArrayList<>(creativeDTOS.size());
        List<AdRankItem> adRankItems = new ArrayList<>(creativeDTOS.size());
        Random random = new Random();
        double originWeightSum = 0;
        for (AdPlatformCreativeDTO dto : creativeDTOS) {
            AdRankItem adRankItem = new AdRankItem();
            adRankItem.setAdId(dto.getCreativeId());
            adRankItem.setCreativeCode(dto.getCreativeCode());
            adRankItem.setAdVerId(dto.getAdVerId());
            adRankItem.setVideoId(scoreParam.getVideoId());
            adRankItem.setCpa(dto.getCpa());
            adRankItem.setId(dto.getAdId());
            adRankItem.setCampaignId(dto.getCampaignId());
            adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
            adRankItem.setRandom(random.nextInt(1000));
            adRankItem.setWeight(dto.getWeight());
            adRankItem.setScore(0d);
            adRankItem.getScoreMap().put("weight", dto.getWeight());
            if (noApiAdVerIds.contains(dto.getAdVerId())) {
                adRankItem.getExt().put("isApi", "0");
            } else {
                adRankItem.getExt().put("isApi", "1");
            }
            adRankItem.getExt().put("recallsources", dto.getRecallSources());
            fillAdRankItemExt(adRankItem, dto);


            adRankItems.add(adRankItem);

            originWeightSum += dto.getWeight();
            WeightRandom.ItemWithWeight<AdRankItem> itemWithWeight = new WeightRandom.ItemWithWeight<AdRankItem>();
            itemWithWeight.setItem(adRankItem);
            itemWithWeight.setWeight(adRankItem.getWeight());
            creativeItemWeights.add(itemWithWeight);
        }

        AdRankItem adRankItem = WeightRandom.getItemByWeight(creativeItemWeights);

        for (AdRankItem rankItem : adRankItems) {
            rankItem.getScoreMap().put("weightSum", originWeightSum);
            if (Objects.equals(rankItem.getAdId(), adRankItem.getAdId())) {
                rankItem.setScore(rankItem.getWeight() / originWeightSum);
            }
        }

        adRankItems.sort(ComparatorUtil.equalsRandomComparator());

        return adRankItems;
    }

}
