package com.fs.course.service.impl;

import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.bean.BeanUtils;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.domain.FsUserVideo;
import com.fs.course.dto.VideoFavoriteStatusDTO;
import com.fs.course.dto.VideoLikeStatusDTO;
import com.fs.course.mapper.*;
import com.fs.course.param.*;
import com.fs.course.service.IFsUserVideoService;
import com.fs.course.service.IRecommendationService;
import com.fs.course.vo.FsUserVideoListPVO;
import com.fs.course.vo.FsUserVideoListUVO;
import com.fs.course.vo.FsUserVideoPVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课堂视频Service业务层处理
 *
 * @author fs
 * @date 2024-05-15
 */
@Service
public class FsUserVideoServiceImpl implements IFsUserVideoService
{
    @Autowired
    private FsUserVideoMapper fsUserVideoMapper;
    @Autowired
    private FsUserVideoLikeMapper fsUserVideoLikeMapper;
    @Autowired
    private FsUserVideoFavoriteMapper fsUserVideoFavoriteMapper;
    @Autowired
    private FsUserVideoCommentMapper fsUserVideoCommentMapper;
    @Autowired
    private IRecommendationService recommendationService;
    @Autowired
    private RedisTemplate redisTemplate;
    private static final String LIKE_KEY_PREFIX = "like:video:";
    private static final String FAVORITE_KEY_PREFIX = "favorite:video:";

    /**
     * 查询课堂视频
     *
     * @param videoId 课堂视频主键
     * @return 课堂视频
     */
    @Override
    public FsUserVideo selectFsUserVideoByVideoId(String videoId)
    {
        return fsUserVideoMapper.selectFsUserVideoByVideoId(videoId);
    }

    /**
     * 查询课堂视频列表
     *
     * @param fsUserVideo 课堂视频
     * @return 课堂视频
     */
    @Override
    public List<FsUserVideo> selectFsUserVideoList(FsUserVideo fsUserVideo)
    {
        return fsUserVideoMapper.selectFsUserVideoList(fsUserVideo);
    }

    /**
     * 新增课堂视频
     *
     * @param fsUserVideo 课堂视频
     * @return 结果
     */
    @Override
    public int insertFsUserVideo(FsUserVideo fsUserVideo)
    {
        fsUserVideo.setCreateTime(DateUtils.getNowDate());
        return fsUserVideoMapper.insertFsUserVideo(fsUserVideo);
    }

    /**
     * 修改课堂视频
     *
     * @param fsUserVideo 课堂视频
     * @return 结果
     */
    @Override
    public int updateFsUserVideo(FsUserVideo fsUserVideo)
    {
        fsUserVideo.setUpdateTime(DateUtils.getNowDate());
        return fsUserVideoMapper.updateFsUserVideo(fsUserVideo);
    }

    /**
     * 批量删除课堂视频
     *
     * @param videoIds 需要删除的课堂视频主键
     * @return 结果
     */
    @Override
    public int deleteFsUserVideoByVideoIds(String[] videoIds)
    {
        return fsUserVideoMapper.deleteFsUserVideoByVideoIds(videoIds);
    }

    /**
     * 删除课堂视频信息
     *
     * @param videoId 课堂视频主键
     * @return 结果
     */
    @Override
    public int deleteFsUserVideoByVideoId(String videoId)
    {
        return fsUserVideoMapper.deleteFsUserVideoByVideoId(videoId);
    }

    @Override
    public List<FsUserVideo> selectFsUserVideoListByCourseId(FsUserVideo fsUserVideo) {
        return fsUserVideoMapper.selectFsUserVideoListByCourseId(fsUserVideo);
    }

    @Override
    public R addUserVideo(FsUserVideoAddParam param) {
        FsUserVideo fsUserVideo = new FsUserVideo();
        BeanUtils.copyProperties(param, fsUserVideo);
        fsUserVideo.setCreateTime(DateUtils.getNowDate());
        fsUserVideo.setIsAudit(0);
        fsUserVideo.setSource(1);
        fsUserVideo.setStatus(1);
//        fsUserVideo.setComments(0L);
        fsUserVideoMapper.insertFsUserVideo(fsUserVideo);
        return R.ok();
    }

    @Override
    public List<FsUserVideoListPVO> selectFsUserVideoListPVO(FsUserVideoParam param) {
        return fsUserVideoMapper.selectFsUserVideoListPVO(param);
    }

    @Override
    public int updateLikes(Long videoId, Integer type) {
        if (type == 1){
            return fsUserVideoMapper.addLikes(videoId);
        }else {
            return fsUserVideoMapper.minusLikes(videoId);
        }
    }


    @Override
    public int updateFavorite(Long videoId, Integer type) {
        if (type == 1){
            return fsUserVideoMapper.addFavorite(videoId);
        }else {
            return fsUserVideoMapper.minusFavorite(videoId);
        }
    }


    @Override
    public List<FsUserVideoListUVO> selectFsUserVideoListUVO(FsUserVideoListUParam param) {
        List<FsUserVideoListUVO> list = fsUserVideoMapper.selectFsUserVideoListUVO(param);

        if (param != null && param.getUserId() != null) {
            Long userId = param.getUserId();
            list = selectLikesAndFavorites(userId, list);
        }
        return list;
    }



    @Override
    public List<FsUserVideoListUVO> selectFsUserFavoriteVideoListUVO(FsUserVideoFavoriteListUParam param) {
        List<FsUserVideoListUVO> list = new ArrayList<>();
        if (param.getType()==1){
            list = fsUserVideoMapper.selectFsUserLikeVideoListUVO(param.getUserId());
        }else if(param.getType()==2){
            list = fsUserVideoMapper.selectFsUserFavoriteVideoListUVO(param.getUserId());
        }else {
            list = fsUserVideoMapper.selectFsUserCommentVideoListUVO(param.getUserId());
        }
        list = selectLikesAndFavorites(param.getUserId(), list);
        return list;
    }

    //查询点赞信息和收藏信息
    public List<FsUserVideoListUVO> selectLikesAndFavorites(Long userId,List<FsUserVideoListUVO> list) {
        if (list!=null&&!list.isEmpty()){
            List<Long> videoIds = list.stream().map(vo -> Long.parseLong(vo.getId())).collect(Collectors.toList());

            // 批量查询Redis中的点赞信息
            List<String> likeKeys = videoIds.stream()
                    .map(videoId -> LIKE_KEY_PREFIX + videoId + ":user:" + userId)
                    .collect(Collectors.toList());
            List<Boolean> redisLikes = redisTemplate.opsForValue().multiGet(likeKeys);

            // 批量查询Redis中的收藏信息
            List<String> favoriteKeys = videoIds.stream()
                    .map(videoId -> FAVORITE_KEY_PREFIX + videoId + ":user:" + userId)
                    .collect(Collectors.toList());
            List<Boolean> redisFavorites = redisTemplate.opsForValue().multiGet(favoriteKeys);

            // 缓存未命中的视频ID列表
            List<Long> missingLikeVideoIds = new ArrayList<>();
            List<Long> missingFavoriteVideoIds = new ArrayList<>();

            // 设置点赞和收藏信息
            for (int i = 0; i < list.size(); i++) {
                FsUserVideoListUVO vo = list.get(i);
                Long videoId = Long.parseLong(vo.getId());
                Integer commentCount = fsUserVideoCommentMapper.selectCommentCountByVideos(videoId);
                vo.setSmsNum(commentCount);
                // 优先使用Redis中的点赞数据
                if (redisLikes != null && redisLikes.get(i) != null) {
                    vo.setLike(Boolean.TRUE.equals(redisLikes.get(i)) ? 1 : 0);
                } else {
                    missingLikeVideoIds.add(videoId);
                }

                // 优先使用Redis中的收藏数据
                if (redisFavorites != null && redisFavorites.get(i) != null) {
                    vo.setFavorite(Boolean.TRUE.equals(redisFavorites.get(i)) ? 1 : 0);
                } else {
                    missingFavoriteVideoIds.add(videoId);
                }
            }

            // 查询数据库中的点赞和收藏信息
            if (!missingLikeVideoIds.isEmpty()) {
                Map<Long, VideoLikeStatusDTO> likeMap = fsUserVideoLikeMapper.checkLikes(missingLikeVideoIds, userId);
                for (FsUserVideoListUVO vo : list) {
                    Long videoId = Long.parseLong(vo.getId());
                    if (missingLikeVideoIds.contains(videoId)) {
                        vo.setLike(likeMap.getOrDefault(videoId, new VideoLikeStatusDTO()).getLiked() ? 1 : 0);
                    }
                }
            }

            if (!missingFavoriteVideoIds.isEmpty()) {
                Map<Long, VideoFavoriteStatusDTO> favoriteMap = fsUserVideoFavoriteMapper.checkFavorites(missingFavoriteVideoIds, userId);
                for (FsUserVideoListUVO vo : list) {
                    Long videoId = Long.parseLong(vo.getId());
                    if (missingFavoriteVideoIds.contains(videoId)) {
                        vo.setFavorite(favoriteMap.getOrDefault(videoId, new VideoFavoriteStatusDTO()).getFavorite() ? 1 : 0);
                    }
                }
            }

        }
        return list;
    }

    @Override
    public FsUserVideoPVO selectFsUserVideoPVOByVideoId(Long videoId) {
        return fsUserVideoMapper.selectFsUserVideoPVO(videoId);
    }

    @Override
    public int updateShares(Long videoId) {
        return fsUserVideoMapper.updateShares(videoId);
    }

    @Override
    public FsUserVideoListUVO getVideoById(Long videoId) {
        return fsUserVideoMapper.selectFsUserVideoListUVOByVideoId(videoId);
    }

    @Override
    public int auditUserVideos(FsUserVideoAuditParam param) {
        return fsUserVideoMapper.auditUserVideos(param);
    }

    @Override
    public int updateFsUserVideoIsShow(Long[] videoIds, int i) {
        return fsUserVideoMapper.updateFsUserVideoIsShow(videoIds,i);
    }

    @Autowired
    private FsUserCourseVideoMapper courseVideoMapper;

    @Override
    public void updateVideoUrl() {
        List<FsUserCourseVideo> videos = courseVideoMapper.selectVideoIsPrivate();
        for (FsUserCourseVideo video:videos ){
            String url = updateUrlPrefix(video.getLineTwo());
            FsUserCourseVideo video1 = new FsUserCourseVideo();
            video1.setLineTwo(url);
            video1.setVideoId(video.getVideoId());
            courseVideoMapper.updateFsUserCourseVideo(video1);
        }
    }

    public static String updateUrlPrefix(String url) {
        final String oldPrefix = "https://obs.ylrztop.com";
        final String newPrefix = "https://rtobs.ylrztop.com";

        // 判断是否以 oldPrefix 开头，如果是，则进行替换
        if (url.startsWith(oldPrefix)) {
            // 去掉 oldPrefix 前缀，然后拼上 newPrefix
            return newPrefix + url.substring(oldPrefix.length());
        }
        // 如果不是以 oldPrefix 开头，则原样返回
        return url;
    }




}
