package cn.reghao.tnb.content.app.vod.service.rcmd;

import cn.reghao.tnb.content.app.util.redis.ds.RedisSortedSetStr;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 基于用户-物品关系及其打分的协同过滤
 *
 * @author reghao
 * @date 2023-02-21 21:58:27
 */
@Service
public class UserItemsScoreBased {
    private final RedisSortedSetStr redisSortedSetStr;

    public UserItemsScoreBased(RedisSortedSetStr redisSortedSetStr) {
        this.redisSortedSetStr = redisSortedSetStr;
    }

    /**
     * 对物品进行打分
     *
     * @param
     * @return
     * @date 2023-02-21 11:19 PM
     */
    public void rateItem(long userId, String itemId, double score) {
        redisSortedSetStr.add(RedisKeys.getUserItemstKey(userId), score, itemId);
        redisSortedSetStr.add(RedisKeys.getItemScoresKey(itemId), score, String.valueOf(userId));
    }

    /**
     * @param
     * @return
     * @date 2023-02-21 11:19 PM
     */
    public void getRatedItems(long userId) {
        // 获取用户打过分的物品
        Set<String> itemIds = redisSortedSetStr.zrange(RedisKeys.getUserItemstKey(userId), 0, -1);
        // 找出给相同物品打过分的用户
        redisSortedSetStr.zunionstore(RedisKeys.getUserSameItemsKey(userId), String.valueOf(itemIds.size()), itemIds);

        Set<String> userIds = redisSortedSetStr.zrange(RedisKeys.getUserSameItemsKey(userId), 0, -1);
        List<Long> userIds1 = userIds.stream().map(Long::parseLong).collect(Collectors.toList());
        long userId1 = userIds1.get(0);
        long userId2 = userIds1.get(1);
        Set<String> keys = userIds1.stream().map(RedisKeys::getUserItemstKey).collect(Collectors.toSet());
        // 将两个用户的差开平方根再取绝对值, 然后根据这个结果实现自己的逻辑来判断谁与给定用户最为接近
        redisSortedSetStr.zinterstore(RedisKeys.getRMSKey(userId1, userId2), String.valueOf(keys.size()), keys, 1, -1);
    }
}
