package com.wzj.soopin.content.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;

import com.wzj.soopin.content.domain.bo.*;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.po.Users;
import com.wzj.soopin.content.domain.vo.VlogerVO;
import com.wzj.soopin.content.enums.VlogStatusEnum;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.enums.YesOrNo;
import com.wzj.soopin.content.mapper.CommentMapper;
import com.wzj.soopin.content.mapper.MyLikedVlogMapper;
import com.wzj.soopin.content.mapper.UsersMapper;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.content.mapper.VlogMapper;
import com.wzj.soopin.content.mapper.VlogMapperCustom;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.PagedGridResult;
import com.wzj.soopin.content.utils.RedisOperator;
import com.wzj.soopin.content.utils.Sid;
import com.wzj.soopin.content.utils.TencentCloudUtil;
import com.wzj.soopin.member.service.IFansService;
import com.wzj.soopin.content.convert.VlogConvert;
import com.wzj.soopin.member.service.IMemberService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mq.config.RocketMQConfig;
import org.dromara.common.mq.domain.MQMessage;
import org.dromara.common.mq.enums.MQMessageType;
import org.dromara.common.mq.enums.MessageActionEnum;
import org.dromara.common.mq.utils.MqUtil;
import org.dromara.common.mq.utils.UserRocketMQConsumerManager;
import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.common.core.utils.MapstructUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;

import lombok.extern.slf4j.Slf4j;

import static com.wzj.soopin.content.domain.base.BaseInfoProperties.*;

@Slf4j
@Service
@AllArgsConstructor
public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements VlogService {

    private final VlogMapper vlogMapper;
    private final VlogMapperCustom vlogMapperCustom;
    private final MyLikedVlogMapper myLikedVlogMapper;
    private final IFansService fansService;
    private final MsgService msgService;
    private final Sid sid;
    private final CommentMapper commentMapper;
    private final MemberMapper memberMapper;
    private final RedisCache cache;
    private final RedisCache redisCache;
    private final VlogConvert vlogConvert;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private RedisOperator redis;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateVlogStatus(String fileId, Integer status, String reason) {
        LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Vlog::getFileId, fileId)
            .set(Vlog::getStatus, status)
            .set(Vlog::getReason, reason);
        vlogMapper.update(null, updateWrapper);

        // 1. 获取视频信息，找到上传者
        Vlog vlog = vlogMapper.selectByFileId(fileId);
        if (vlog == null) return;
        String uploaderId = vlog.getMemberId();

        // 2. 选择模板（假设你有模板ID，实际可配置到常量或数据库）
        Long templateId = (status == 1) ? 1938491493736902658L : 1938491899007332353L; // 1001=审核通过模板，1002=驳回模板
//        SysMessageTemplateVo template = templateService.selectTemplateById(templateId);
//        if (template == null) return;
//
//        // 3. 参数替换
//        String content = template.getTemplateContent()
//            .replace("${videoTitle}", vlog.getTitle() == null ? "" : vlog.getTitle())
//            .replace("${reason}", reason == null ? "" : reason);
//
//        // 4. 构造消息对象
//        SysMessageBo messageBo = new SysMessageBo();
//        messageBo.setTitle(template.getTitle());
//        messageBo.setContent(content);
//        messageBo.setSenderId(1L); // 系统管理员
//        // 可根据需要设置更多字段
//
//        // 5. 发送消息
//        sysMessageService.sendMessageToUser(messageBo, Long.valueOf(uploaderId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateVlogFirstImg(String fileId, String url, String fileUrl) {
        LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Vlog::getFileId, fileId)
            .set(Vlog::getFirstFrameImg, url)
            .set(Vlog::getUrl, fileUrl);
        vlogMapper.update(null, updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createVlog(VlogBO vlogBO) {


        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        vlogBO.setMemberId(String.valueOf(loginUser.getUserId()));

        String vid = sid.nextShort();
        Vlog vlog = vlogConvert.toPo(vlogBO);
        vlog.setId(vid);
        vlog.setLikeCounts(0);
        vlog.setCommentsCounts(0);
        vlog.setStatus(0);
        vlog.setIsPrivate(YesOrNo.NO.type);

        vlog.setMemberId(loginUser.getUserId()+"");
        vlog.setUrl("#");
        vlogMapper.insert(vlog);


        //发出mq消息，异步处理上传
        MQMessage message = MQMessage.builder()
            .messageType("json")
            .data(vlog.getId())
            .source("app")
            .topic("VLOG_UPLOAD_TOPIC")
            .tag("upload")
            .sendTime(LocalDateTime.now())
            .build();
        MqUtil.sendMessage(RocketMQConfig.VLOG_UPLOAD_TOPIC+":"+"upload", message);
    }


    @Override
    public Integer getVlogBeLikedCounts(String vlogId) {
        Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);

        return count == null ? 0 : count.intValue();
    }

    private Integer getVlogComment(String vlogId) {
        Double count = cache.zSetScore(REDIS_VLOG_COMMENT_COUNTS, vlogId);
        return count == null ? 0 : count.intValue();
    }

    private boolean doILikeVlog(String myId, String vlogId) {
        String doILike = cache.getCacheObject(REDIS_USER_LIKE_VLOG + ":" + myId + ":" + vlogId);
        return StringUtils.isNotBlank(doILike) && doILike.equalsIgnoreCase("1");
    }

    @Override
    @Cacheable(cacheNames = GlobalConstants.VLOG_KEY, key = "#vlogId")
    public IndexVlogVO getVlogDetailById(String vlogId) {
        Vlog vlog = vlogMapper.selectById(vlogId);
        if (vlog == null) {
            return null;
        }
        IndexVlogVO vo = MapstructUtils.convert(vlog, IndexVlogVO.class);
        //获取用户信息
        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
            if (loginUser != null) {
                vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(loginUser.getUserId() + "", vlog.getMemberId()));
                vo.setDoILikeThisVlog(doILikeVlog(loginUser.getUserId() + "", vlogId));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        vo.setLikeCounts(getVlogBeLikedCounts(vlogId));
        vo.setCommentsCounts(getVlogComment(vlogId));

        // 补充作者信息（头像/昵称）
        Member author = memberMapper.selectById(vlog.getMemberId());
        if (author != null) {
            vo.setAvatar(author.getAvatar());
            vo.setNickname(author.getNickname());
        }

        return vo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override

    @CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
    public void changeToPrivateOrPublic(String userId, String vlogId, Integer yesOrNo) {
        LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Vlog::getId, vlogId)
            .eq(Vlog::getMemberId, userId)
            .set(Vlog::getIsPrivate, yesOrNo);
        vlogMapper.update(null, updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
    public void changeVlogStatus(String userId, String vlogId, Integer status) {
        LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Vlog::getId, vlogId)
            .eq(Vlog::getMemberId, userId)
            .set(Vlog::getStatus, status);
        vlogMapper.update(null, updateWrapper);
    }

    @Override
    public Page<IndexVlogVO> queryMyVlogList(MyListBO bo, Page page) {
        int current = (int) page.getCurrent();
        int size = (int) page.getSize();
        Page<Vlog> pageParam = new Page<>(current, size);
        LambdaQueryWrapper<Vlog> queryWrapper = new LambdaQueryWrapper<>();

        if (bo.getUserId() == null) {
            LoginUser user = LoginHelper.getLoginUser();
            if (user == null) {
                throw new ServiceException("用户未登录");
            }
            queryWrapper.eq(Vlog::getMemberId, user.getUserId());
        } else {
            queryWrapper.eq(Vlog::getMemberId, bo.getUserId());

        }
        queryWrapper.eq(bo.getPrivateFlag() != null, Vlog::getIsPrivate, bo.getPrivateFlag());
        Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper);
        List<Vlog> vlogList = vlogPage.getRecords();

        List<IndexVlogVO> voList = vlogList.stream().map(vlog -> {
            IndexVlogVO vo = MapstructUtils.convert(vlog, IndexVlogVO.class);
            String uid = bo.getUserId();
            if (StringUtils.isBlank(uid)) {
                LoginUser user = LoginHelper.getLoginUser();
                uid = user != null ? String.valueOf(user.getUserId()) : null;
            }
            if (StringUtils.isNotBlank(uid)) {
                vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(uid, vlog.getMemberId()));
                vo.setDoILikeThisVlog(doILikeVlog(uid, vlog.getId()));
            }
            vo.setLikeCounts(getVlogBeLikedCounts(vlog.getId()));
            vo.setCommentsCounts(getVlogComment(vlog.getId()));

            // 补充用户信息（头像/昵称）
            Member author = memberMapper.selectById(vlog.getMemberId());
            if (author != null) {
                vo.setAvatar(author.getAvatar());
                vo.setNickname(author.getNickname());
            }

            return vo;
        }).collect(Collectors.toList());

        Page<IndexVlogVO> gridResult = new Page<IndexVlogVO>();
        gridResult.setRecords(voList);
        gridResult.setSize(vlogPage.getSize());
        gridResult.setCurrent(current);
        gridResult.setTotal(vlogPage.getTotal());
        return gridResult;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
    public void userLikeVlog(String userId, String vlogId) {
        //获取vlog
        Vlog vlog = this.getVlog(vlogId);
        if (vlog == null) {
            throw new ServiceException("视频不存在");
        }
        // 我点赞的视频，关联关系保存到数据库

        String rid = sid.nextShort();
        MyLikedVlog likedVlog = new MyLikedVlog();
        likedVlog.setId(rid);
        likedVlog.setVlogId(vlogId);
        likedVlog.setUserId(userId);
        myLikedVlogMapper.insert(likedVlog);

        // 点赞后，视频和视频发布者的获赞都会 +1
        cache.zSetIncrement(REDIS_VLOGER_BE_LIKED_COUNTS, vlog.getMemberId(), 1);
        cache.zSetIncrement(REDIS_VLOG_BE_LIKED_COUNTS, vlogId, 1);

        // 我点赞的视频，需要在redis中保存关联关系
        cache.setCacheObject(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId, "1");
        Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);
        if (count > 0) {
            //更新数据库的点赞数
            this.flushCounts(vlogId, count.intValue());
        }
        //发送消息
        MqUtil.sendIMMessage(buildMessage(vlog));
    }

    private MQMessage buildMessage(Vlog vlog){

        Map<String,Object> params=new HashMap<>();
        LoginUser loginUser=LoginHelper.getLoginUser();
        params.put("userId", loginUser.getUserId());
        params.put("nickname", loginUser.getNickname() == null ? "" : loginUser.getNickname());
        params.put("faceUrl", loginUser.getAvatar()  );
        params.put("action", MessageActionEnum.INTERACTION_LIKE.getAccount());
        params.put("toUserId",vlog.getMemberId());

        MQMessage mqMessage = new MQMessage();
        mqMessage.setTag(MessageActionEnum.INTERACTION_LIKE.getAccount());
        mqMessage.setData(params);
        return mqMessage;
    }

    @Override
    public Vlog getVlog(String id) {
        return vlogMapper.selectById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void flushCounts(String vlogId, Integer counts) {
        LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Vlog::getId, vlogId)
            .set(Vlog::getLikeCounts, counts);
        vlogMapper.update(null, updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
    public void userUnLikeVlog(String userId, String vlogId) {

        //获取vlog
        Vlog vlog = this.getVlog(vlogId);
        if (vlog == null) {
            throw new ServiceException("视频不存在");
        }

        // 我取消点赞的视频，关联关系删除
        LambdaQueryWrapper<MyLikedVlog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MyLikedVlog::getUserId, userId);
        queryWrapper.eq(MyLikedVlog::getVlogId, vlogId);
        myLikedVlogMapper.delete(queryWrapper);

        cache.zSetDecrement(REDIS_VLOGER_BE_LIKED_COUNTS, vlog.getMemberId(), 1);
        cache.zSetDecrement(REDIS_VLOG_BE_LIKED_COUNTS, vlogId, 1);
        cache.deleteObject(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId);


        Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);
        if (count > 0) {
            //更新数据库的点赞数
            this.flushCounts(vlogId, count.intValue());
        }
    }

    @Override
    public Page<IndexVlogVO> getMyLikedVlogList(Page page) {

        LoginUser user = LoginHelper.getLoginUser();
        if (user == null) {
            throw new ServiceException("用户未登录");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("myId", user.getUserId());
        Page<IndexVlogVO> likedPage = vlogMapperCustom.getMyLikedVlogList(map, page);

        likedPage.getRecords().stream().forEach(
            liked -> {
                liked.setDoIFollowVloger(true);
                liked.setDoILikeThisVlog(true);
            });
        return likedPage;
    }

    @Override
    public Page<IndexVlogVO> getMyFollowVlogList(Page page) {
        LoginUser user = LoginHelper.getLoginUser();
        if (user == null) {
            throw new ServiceException("用户未登录");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("myId", user.getUserId());
        Page<IndexVlogVO> voPage = vlogMapperCustom.getMyFollowVlogList(map, page);

        return voPage;
    }

    @Override
    public Page<IndexVlogVO> getMyFriendVlogList(Page page) {
        LoginUser user = LoginHelper.getLoginUser();
        if (user == null) {
            throw new ServiceException("用户未登录");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("myId", user.getUserId());
        Page<IndexVlogVO> voPage = vlogMapperCustom.getMyFriendVlogList(map, page);
        fillRedisColumn(voPage.getRecords());

        return voPage;
    }

    @Override
    public Vlog getVlogByFileId(String fileId) {
        return vlogMapper.selectByFileId(fileId);
    }

    @Override


    public Map<String, Object> getVlogStatistics(String fileId) {
        Map<String, Object> result = new HashMap<>();

        // 获取视频基本信息
        Vlog vlog = vlogMapper.selectByFileId(fileId);
        if (vlog != null) {
            result.put("vlogId", vlog.getId());
            result.put("title", vlog.getTitle());
            result.put("width", vlog.getWidth());
            result.put("height", vlog.getHeight());
            result.put("reason", vlog.getReason());

            // 注意：点赞数和评论数现在在控制器中直接从Redis获取
            // 这里不再统计，避免重复计算

            // 获取粉丝数量：优先 Redis，无则 MySQL
            String fansCountsStr = cache.getCacheObject(REDIS_MY_FANS_COUNTS + ":" + vlog.getMemberId());
            Integer fansCounts = 0;
            if (StringUtils.isNotBlank(fansCountsStr)) {
                fansCounts = Integer.valueOf(fansCountsStr);
            } else {
//                fansCounts = fansService.countFansByVlogerId(vlog.getVlogerId());
//                if (fansCounts != null) {
//                    redis.set(REDIS_MY_FANS_COUNTS + ":" + vlog.getVlogerId(), String.valueOf(fansCounts));
//                }
            }
            result.put("fansCounts", fansCounts);
        } else {
            result.put("vlogId", null);
            result.put("reason", null);
            result.put("fansCounts", 0);
        }

        return result;
    }

    @Override
    public Map<String, Object> getVlogDetailInfo(String fileId) {
        Map<String, Object> result = new HashMap<>();

        // 获取视频基本信息
        Vlog vlog = vlogMapper.selectByFileId(fileId);
        if (vlog != null) {
            // 如果找到vlog信息，使用fileId查询腾讯云
//            Object vodDetail = tencentCloudUtil.getVodMediaInfo(fileId);
//            if (vodDetail instanceof Map) {
//                result.putAll((Map<String, Object>) vodDetail);
//            } else {
//                result.put("vodDetail", vodDetail);
//            }
            IndexVlogVO vo = MapstructUtils.convert(vlog, IndexVlogVO.class);
            // 添加评论信息
            List<Map<String, Object>> comments = commentMapper.selectCommentsByVlogId(vlog.getId());
            result.put("comments", comments);

            // 从Redis获取点赞数
            int likeCounts = getVlogBeLikedCounts(vlog.getId());

            result.put("likeCounts", likeCounts);
            result.put("vlogId", vlog.getId());

            List<Map<String, Object>> likedUsers = myLikedVlogMapper.selectLikedUsersByVlogId(vlog.getId());
            result.put("likedUsers", likedUsers);
            result.put("vlog", vo);

            // 添加粉丝列表
//            Page<FansVO> fansPage = fansService.queryMyFans(vlog.getVlogerId(), 0, 10);
//            result.put("fansList", fansPage);
        } else {
            // 如果没有找到vlog信息，只返回腾讯云视频信息
//            Object vodDetail = tencentCloudUtil.getVodMediaInfo(fileId);
//            if (vodDetail instanceof Map) {
//                result.putAll((Map<String, Object>) vodDetail);
//            } else {
//                result.put("vodDetail", vodDetail);
//            }
            // 设置默认值
            result.put("comments", Collections.emptyList());
            result.put("likeCounts", 0);
            result.put("likedUsers", Collections.emptyList());
            result.put("fansList", Collections.emptyList());
        }

        return result;
    }

    @Override
    public List<Map<String, Object>> getVlogComments(String vlogId) {
        return commentMapper.selectCommentsByVlogId(vlogId);
    }

    @Override
    public List<Map<String, Object>> getLikedUsers(String vlogId) {
        return myLikedVlogMapper.selectLikedUsersByVlogId(vlogId);
    }


    @Override
    public Map<String, String> getVlogUploaderInfo(String fileId) {
        // 通过 fileId 获取视频信息
        Vlog vlog = vlogMapper.selectByFileId(fileId);
        if (vlog == null) {
            return null;
        }

        // 获取上传者ID
        String uploaderId = vlog.getMemberId();
        if (uploaderId == null) {
            return null;
        }

        // 从 ums_member 表获取用户信息
        Member user = memberMapper.selectById(uploaderId);
        if (user == null) {
            return null;
        }

        Map<String, String> result = new HashMap<>();
        result.put("name", user.getNickname());
        result.put("phone", user.getPhoneHidden());

        return result;
    }

    @Override
    public IPage<Map<String, Object>> getVlogListByMobile(Page<Map<String, Object>> page, VlogBO vlogBO) {
        // 统一调用新的Mapper方法进行查询和排序
        // 预处理时间字符串，确保转换为MySQL DATETIME兼容格式
        String beginTimeStr = vlogBO.getStartTime() != null ? vlogBO.getStartTime().toString() : null;
        if (StringUtils.isNotBlank(beginTimeStr)) {
            try {
                // 移除双引号，解析为 Instant，然后转换为 LocalDateTime
                String cleanedBeginTimeStr = beginTimeStr.trim().replace("\"", "");
                System.out.println("Original beginTimeStr: " + beginTimeStr);
                System.out.println("Cleaned beginTimeStr: " + cleanedBeginTimeStr);
                Instant instant = Instant.parse(cleanedBeginTimeStr);
                LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
                System.out.println("Formatted startTime: " + dateTime);
                vlogBO.setStartTime(dateTime);
            } catch (Exception e) {
                // 处理解析异常，例如日志记录
                System.err.println("Error parsing beginTime: " + beginTimeStr + " - " + e.getMessage());
                vlogBO.setStartTime(null);
            }
        } else {
            System.out.println("beginTimeStr is blank or null.");
            vlogBO.setStartTime(null);
        }

        String endTimeStr = vlogBO.getEndTime() != null ? vlogBO.getEndTime().toString() : null;
        if (StringUtils.isNotBlank(endTimeStr)) {
            try {
                // 移除双引号，解析为 Instant，然后转换为 LocalDateTime
                String cleanedEndTimeStr = endTimeStr.trim().replace("\"", "");
                System.out.println("Original endTimeStr: " + endTimeStr);
                System.out.println("Cleaned endTimeStr: " + cleanedEndTimeStr);
                Instant instant = Instant.parse(cleanedEndTimeStr);
                LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
                System.out.println("Formatted endTime: " + dateTime);
                vlogBO.setEndTime(dateTime);
            } catch (Exception e) {
                // 处理解析异常，例如日志记录
                System.err.println("Error parsing endTime: " + endTimeStr + " - " + e.getMessage());
                vlogBO.setEndTime(null);
            }
        } else {
            System.out.println("endTimeStr is blank or null.");
            vlogBO.setEndTime(null);
        }

        return vlogMapper.selectVlogListWithAggregatedData(page, vlogBO);
    }


    @Override
    public List<Map<String, Object>> getRandomVlogs(int limit) {
        try {
            log.info("开始随机查询{}条视频", limit);
            List<Map<String, Object>> randomVlogs = vlogMapper.selectRandomVlogs(limit);
            log.info("成功随机查询到{}条视频", randomVlogs.size());
            return randomVlogs;
        } catch (Exception e) {
            log.error("随机查询视频失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public IPage<String> getVlogForUser(Page<IndexVlogVO> page, Long memberId) {
        return baseMapper.getVlogForUser(page, memberId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int readVlog(Long memberId, String vlogId) {
        //加入已读缓存列表，数量为1
        if (!redisCache.zSetHasMember("vlog:read:" + memberId, vlogId)) {
            redisCache.zSetAdd("vlog:read:" + memberId, vlogId, 1);
        } else {
            redisCache.zSetIncrement("vlog:read:" + memberId, vlogId, 1);
        }
        return baseMapper.readVlog(memberId, vlogId);
    }

    @Override
    public List<IndexVlogVO> getIndexVlogList(VlogBO bo) {
        List<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(bo);
        fillRedisColumn(indexVlogVOPage);
        return indexVlogVOPage;
    }

    @Override
    public Page<IndexVlogVO> getIndexVlogList(VlogBO bo, Page page) {
        Page<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(bo, page);
        fillRedisColumn(indexVlogVOPage.getRecords());
        return indexVlogVOPage;
    }

    private void fillRedisColumn(List<IndexVlogVO> vlogList) {
        LoginUser user = LoginHelper.getLoginUser();
        vlogList.parallelStream().forEach(vlog -> {
            if (user != null) {
                vlog.setDoIFollowVloger(fansService.queryDoIFollowVloger(user.getUserId() + "", vlog.getMemberId()));
                vlog.setDoILikeThisVlog(doILikeVlog(user.getUserId() + "", vlog.getId()));
            }
            vlog.setLikeCounts(getVlogBeLikedCounts(vlog.getId()));
            vlog.setCommentsCounts(getVlogComment(vlog.getId()));
        });
    }

    @Override
    public Page<IndexVlogVO> getIndexSearchVlogList(SearchBO bo, Page page) {
        String userId = bo.getUserId();
        int current = (int) page.getCurrent();
        int size = (int) page.getSize();
        Page<Vlog> pageParam = new Page<>(current, size);

        LambdaQueryWrapper<Vlog> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(bo.getTitle())) {
            queryWrapper.like(Vlog::getTitle, bo.getTitle());
        }
        if (StringUtils.isNotBlank(bo.getCityCode())) {
            queryWrapper.eq(Vlog::getCityCode, bo.getCityCode());
        }

        queryWrapper.eq(Vlog::getStatus, VlogStatusEnum.APPROVED.type);

        // 去掉黑名单的视频
        if (StringUtils.isNotBlank(userId)) {
            String redisKey = REDIS_VIDEO_BLOCK + ":" + userId;
            if (redis.keyIsExist(redisKey)) {
                List<String> blockVdList = new ArrayList<>();
                ObjectMapper objectMapper = new ObjectMapper();
                List<String> reports = redis.lrange(redisKey, 0, -1);
                for (String report : reports) {
                    try {
                        Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {
                        });
                        String vlogId = (String) reportMap.get("vlogId");
                        blockVdList.add(vlogId);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                }
                if (!blockVdList.isEmpty()) {
                    queryWrapper.notIn(Vlog::getId, blockVdList);
                }
            }
        }
        // 去掉黑名单的用户
        if (StringUtils.isNotBlank(userId)) {
            String redisKey = REDIS_USER_BLOCK + ":" + userId;
            if (redis.keyIsExist(redisKey)) {
                List<String> blockUserList = new ArrayList<>();
                ObjectMapper objectMapper = new ObjectMapper();
                List<String> reports = redis.lrange(redisKey, 0, -1);
                for (String report : reports) {
                    try {
                        Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {
                        });
                        String memberId = (String) reportMap.get("MemberId");
                        blockUserList.add(memberId);
                    } catch (JsonProcessingException e) {
                        log.error(e.getMessage());
                    }
                }
                if (!blockUserList.isEmpty()) {
                    queryWrapper.notIn(Vlog::getMemberId, blockUserList);
                }
            }
        }

        Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper);
        List<Vlog> vlogList = vlogPage.getRecords();
        List<IndexVlogVO> voList = vlogList.stream().map(v -> {
            IndexVlogVO vo = MapstructUtils.convert(v, IndexVlogVO.class);
            if (StringUtils.isNotBlank(userId)) {
                vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(userId, v.getMemberId()));
                vo.setDoILikeThisVlog(doILikeVlog(userId, v.getId()));
            }
            vo.setLikeCounts(getVlogBeLikedCounts(v.getId()));
            vo.setCommentsCounts(getVlogComment(v.getId()));
            MemberVO m = memberService.getMemberInfo(vo.getMemberId());
            if (m != null) {
                vo.setAvatar(m.getAvatar());
                vo.setNickname(m.getNickname());
            }
            return vo;
        }).collect(Collectors.toList());

        // 封装分页结果
        Page<IndexVlogVO> gridResult = new Page<IndexVlogVO>();
        gridResult.setRecords(voList);             // 当前页数据列表
        gridResult.setCurrent(current);            // 当前页码
        gridResult.setTotal(vlogPage.getTotal()); // 总记录数
        gridResult.setSize(vlogPage.getPages());  // 总页数

        return gridResult;
    }
}
