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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.*;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.service.IVlogPullService;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.TencentCloudUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mq.domain.MQMessage;
import org.dromara.common.mq.domain.VlogPushEvent;
import org.dromara.common.mq.utils.UserRocketMQConsumerManager;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

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

import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_USER_LIKE_VLOG;
import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS;
import static org.dromara.common.core.constant.GlobalConstants.HOT_VLOG_TAG;

@Service
@AllArgsConstructor
@Slf4j
public class VlogPullServiceImpl implements IVlogPullService {

    private final UserRocketMQConsumerManager mqConsumerManager;
    private final VlogService vlogService;
    private final ApplicationEventPublisher eventPublisher;
    private final TencentCloudUtil tencentCloudUtil;

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

        List<MessageExt> messageExts = new ArrayList<>();

        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
            if (loginUser == null) {
                messageExts = mqConsumerManager.pullUserMessages(HOT_VLOG_TAG, (int) page.getSize());
            } else {
                messageExts = mqConsumerManager.pullUserMessages(loginUser.getUserId() + "", (int) page.getSize());

            }
            List<String> ids = messageExts.stream().map(messageExt -> {
                MQMessage mqMessage = JsonUtils.parseObject(messageExt.getBody(), MQMessage.class);
                return mqMessage.getData().toString();
            }).collect(Collectors.toList());
            VlogBO vlogBO = new VlogBO();
            if (ids.size() > 0) {

                vlogBO.setIds(ids);
                List<IndexVlogVO> vlogVOList = vlogService.getIndexVlogList(vlogBO);
                return page.setRecords(vlogVOList);
            } else {
                if (loginUser != null) {
                    eventPublisher.publishEvent(new VlogPushEvent(loginUser.getUserId() + ""));

                } else {
                    eventPublisher.publishEvent(new VlogPushEvent(HOT_VLOG_TAG));
                }
                //发出事件
                //先临时取10条数据
                Page<IndexVlogVO> indexVlogVOPage = vlogService.getIndexVlogList(vlogBO, page);
                //直接获取数据库数据，并要求push类推送数据
                return indexVlogVOPage;
            }

        } catch (Exception e) {
            log.error("拉取视频失败", e);
        }
        return page;
    }


    @Override
    public void pullFromTencentCloud(VlogBO vlogBO) {
        try {

            // 如果有模糊查询条件、时间区间条件，或者有排序条件，则只查询数据库
            if (StringUtils.isNotBlank(vlogBO.getMobile())
                || StringUtils.isNotBlank(vlogBO.getNickname())
                || StringUtils.isNotBlank(vlogBO.getTitleQuery())
                || vlogBO.getStartTime() != null
                || vlogBO.getEndTime() != null
                || vlogBO.getStatus() != null
                || StringUtils.isNotBlank(vlogBO.getColumn())) {

                // 创建分页对象
                Page<Map<String, Object>> page = new Page<>(vlogBO.getCurrent(), vlogBO.getSize());

                // 调用服务层方法进行查询
                IPage<Map<String, Object>> result = vlogService.getVlogListByMobile(page, vlogBO);

                return;
            }

            // 否则查询腾讯云点播
            // 验证密钥配置
            String secretId = tencentCloudUtil.getSecretId();
            String secretKey = tencentCloudUtil.getSecretKey();
            if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
                log.error("腾讯云密钥未配置");
                return;
            }

            // 计算实际的offset
            long offset = (long) ((vlogBO.getCurrent() - 1) * vlogBO.getSize());
            if (offset < 0) {
                offset = 0;
            }

            // 打印分页参数
            log.info("分页参数 - 当前页码: {}, 每页记录数: {}, 偏移量: {}", vlogBO.getCurrent(), vlogBO.getSize(), offset);

            // 创建请求对象
            SearchMediaRequest req = new SearchMediaRequest();

            // 设置分页参数
            req.setOffset(offset);
            req.setLimit(vlogBO.getSize().longValue());

            // 设置排序
            SortBy sort = new SortBy();
            sort.setField("CreateTime");
            sort.setOrder("Desc");
            req.setSort(sort);

            // 调用腾讯云API获取视频列表
            log.info("开始调用腾讯云 SearchMedia API");
            SearchMediaResponse resp = searchMedia(req);
            log.info("腾讯云 SearchMedia API 调用成功，总记录数: {}", resp.getTotalCount());

            // 处理响应结果
            Map<String, Object> result = new HashMap<>();
            result.put("total", resp.getTotalCount());
            result.put("current", vlogBO.getCurrent());
            result.put("size", vlogBO.getSize());
            result.put("pages", (resp.getTotalCount() + vlogBO.getSize() - 1) / vlogBO.getSize()); // 总页数

            // 批量获取所有视频的统计信息，避免重复查询
            Map<String, String> fileIdToVlogIdMap = new HashMap<>();
            List<String> allVlogIds = new ArrayList<>();

            if (resp.getMediaInfoSet() != null) {
                for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
                    String fileId = mediaInfo.getFileId();
                    Map<String, Object> statistics = vlogService.getVlogStatistics(fileId);
                    String vlogId = (String) statistics.get("vlogId");
                    if (StringUtils.isNotBlank(vlogId)) {
                        fileIdToVlogIdMap.put(fileId, vlogId);
                        allVlogIds.add(vlogId);
                    }
                }
            }

            // 批量获取所有点赞数据
            Map<String, Integer> vlogLikeCounts = new HashMap<>();
            Map<String, Integer> vlogCommentCounts = new HashMap<>();
            long totalLikeCounts = 0;
            long totalCommentCounts = 0;

            if (!allVlogIds.isEmpty()) {
                // 批量获取所有点赞键
                String likePattern = REDIS_USER_LIKE_VLOG + ":*";
                Collection<String> allLikeKeys = RedisUtils.keys(likePattern);

                if (allLikeKeys != null && !allLikeKeys.isEmpty()) {
                    // 逐个获取点赞值（由于RedisUtils没有批量方法）
                    Map<String, String> likeKeyValueMap = new HashMap<>();
                    for (String likeKey : allLikeKeys) {
                        String likeValue = RedisUtils.getCacheObject(likeKey);
                        if ("1".equals(likeValue)) {
                            likeKeyValueMap.put(likeKey, likeValue);
                        }
                    }

                    // 按vlogId分组统计点赞数
                    for (String vlogId : allVlogIds) {
                        int likeCount = 0;
                        for (String likeKey : likeKeyValueMap.keySet()) {
                            if (likeKey.endsWith(":" + vlogId)) {
                                likeCount++;
                            }
                        }
                        vlogLikeCounts.put(vlogId, likeCount);
                        totalLikeCounts += likeCount;
                    }
                }

                // 批量获取所有评论数
                for (String vlogId : allVlogIds) {
                    String commentKey = REDIS_VLOG_COMMENT_COUNTS + ":" + vlogId;
                    String commentCountsStr = RedisUtils.getCacheObject(commentKey);
                    int commentCount = 0;
                    if (StringUtils.isNotBlank(commentCountsStr)) {
                        try {
                            commentCount = Integer.valueOf(commentCountsStr);
                        } catch (NumberFormatException e) {
                            log.warn("Redis中视频{}的评论数格式错误: {}", vlogId, commentCountsStr);
                        }
                    }
                    vlogCommentCounts.put(vlogId, commentCount);
                    totalCommentCounts += commentCount;
                }
            }

            // 将总的点赞数和评论数添加到结果中
            result.put("totalLikeCounts", totalLikeCounts);
            result.put("totalCommentCounts", totalCommentCounts);

            List<Map<String, Object>> mediaList = new ArrayList<>();
            if (resp.getMediaInfoSet() != null) {
                for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
                    Map<String, Object> mediaMap = new HashMap<>();
                    // 基础信息
                    MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
                    mediaMap.put("fileId", mediaInfo.getFileId());
                    mediaMap.put("name", basicInfo.getName());
                    mediaMap.put("description", basicInfo.getDescription());
                    mediaMap.put("createTime", basicInfo.getCreateTime());
                    mediaMap.put("updateTime", basicInfo.getUpdateTime());
                    mediaMap.put("expireTime", basicInfo.getExpireTime());
                    mediaMap.put("classId", basicInfo.getClassId());
                    mediaMap.put("className", basicInfo.getClassName());
                    mediaMap.put("classPath", basicInfo.getClassPath());
                    mediaMap.put("coverUrl", basicInfo.getCoverUrl());
                    mediaMap.put("type", basicInfo.getType());
                    mediaMap.put("mediaUrl", basicInfo.getMediaUrl());
                    mediaMap.put("status", basicInfo.getStatus());
                    mediaMap.put("storageRegion", basicInfo.getStorageRegion());
                    mediaMap.put("category", basicInfo.getCategory());
                    mediaMap.put("storageClass", basicInfo.getStorageClass());
                    mediaMap.put("tagSet", basicInfo.getTagSet());

                    // 获取视频统计信息
                    Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId());
                    mediaMap.putAll(statistics);

                    // 从statistics中获取vlogId，用于Redis查询
                    String vlogId = (String) statistics.get("vlogId");
                    log.info("处理视频 fileId: {}, vlogId: {}", mediaInfo.getFileId(), vlogId);

                    // 使用批量获取的数据，避免重复查询Redis
                    int videoLikeCounts = 0;
                    int videoCommentCounts = 0;
                    if (StringUtils.isNotBlank(vlogId)) {
                        videoLikeCounts = vlogLikeCounts.getOrDefault(vlogId, 0);
                        videoCommentCounts = vlogCommentCounts.getOrDefault(vlogId, 0);
                    }
                    mediaMap.put("likeCounts", videoLikeCounts);
                    mediaMap.put("commentCounts", videoCommentCounts);

                    // 获取视频上传者信息
                    Map<String, String> uploaderInfo = vlogService.getVlogUploaderInfo(mediaInfo.getFileId());
                    if (uploaderInfo != null) {
                        mediaMap.put("nickname", uploaderInfo.get("name"));
                        mediaMap.put("mobile", uploaderInfo.get("phone"));
                    }

                    mediaList.add(mediaMap);
                }
            }
            result.put("records", mediaList);
        }catch (Exception e){
            log.error("拉取视频失败: {}", e.getMessage(), e);
        }
    }

    public SearchMediaResponse searchMedia(SearchMediaRequest req) {
        try {
            // 获取VOD客户端实例
            VodClient client = tencentCloudUtil.getVodClient();

            // 设置默认值
            if (req.getOffset() == null) {
                req.setOffset(0L);
            }
            if (req.getLimit() == null) {
                req.setLimit(10L);
            }

            // 添加日志，打印请求参数
//            log.info("SearchMediaRequest 请求参数: {}", req.toJsonString());

            // 添加调试信息
            log.info("请求时间戳: {}", System.currentTimeMillis());
            log.info("请求参数详情 - Offset: {}, Limit: {}, Sort: {}, Filters: {}",
                req.getOffset(),
                req.getLimit(),
//                req.getSort() != null ? req.getSort().toJsonString() : "null",
                req.getFilters() != null ? String.join(",", req.getFilters()) : "null");

            // 验证请求参数
            validateSearchRequest(req);

            SearchMediaResponse response = client.SearchMedia(req);
            log.info("SearchMedia API 调用成功，返回结果数: {}", response.getTotalCount());
            return response;
        } catch (TencentCloudSDKException e) {
            log.error("搜索媒体文件失败: {}", e.getMessage(), e);
            // 添加更详细的错误信息
            if (e.getMessage().contains("signature")) {
                log.error("签名验证失败，请检查：\n1. 密钥是否正确\n2. 服务器时间是否准确\n3. 时区设置是否正确");
            } else if (e.getMessage().contains("InvalidParameterValue")) {
                log.error("参数值错误，请检查：\n1. 分页参数 Offset 和 Limit 是否有效\n2. 搜索条件是否合法\n3. 排序参数是否正确");
            } else if (e.getMessage().contains("UnauthorizedOperation")) {
                log.error("未授权操作，请检查：\n1. 密钥是否有权限\n2. 应用 ID 是否正确\n3. 是否开通了点播服务");
            }
            throw new RuntimeException("搜索媒体文件失败: " + e.getMessage());
        }
    }
    /**
     * 验证搜索请求参数
     */
    private void validateSearchRequest(SearchMediaRequest req) {
        // 验证分页参数
        if (req.getOffset() < 0) {
            throw new IllegalArgumentException("Offset 不能小于 0");
        }
        if (req.getLimit() < 1 || req.getLimit() > 50) {
            throw new IllegalArgumentException("Limit 必须在 1-50 之间");
        }
        if (req.getOffset() + req.getLimit() > 5000) {
            throw new IllegalArgumentException("Offset + Limit 不能超过 5000");
        }

        // 验证搜索条件
        if (req.getFileIds() != null && req.getFileIds().length > 10) {
            throw new IllegalArgumentException("FileIds 数组长度不能超过 10");
        }
        if (req.getNames() != null && req.getNames().length > 10) {
            throw new IllegalArgumentException("Names 数组长度不能超过 10");
        }
        if (req.getNamePrefixes() != null && req.getNamePrefixes().length > 10) {
            throw new IllegalArgumentException("NamePrefixes 数组长度不能超过 10");
        }
        if (req.getDescriptions() != null && req.getDescriptions().length > 10) {
            throw new IllegalArgumentException("Descriptions 数组长度不能超过 10");
        }
        if (req.getClassIds() != null && req.getClassIds().length > 10) {
            throw new IllegalArgumentException("ClassIds 数组长度不能超过 10");
        }
        if (req.getTags() != null && req.getTags().length > 16) {
            throw new IllegalArgumentException("Tags 数组长度不能超过 16");
        }
        if (req.getSourceTypes() != null && req.getSourceTypes().length > 10) {
            throw new IllegalArgumentException("SourceTypes 数组长度不能超过 10");
        }
        if (req.getStreamIds() != null && req.getStreamIds().length > 10) {
            throw new IllegalArgumentException("StreamIds 数组长度不能超过 10");
        }
        if (req.getStorageRegions() != null && req.getStorageRegions().length > 20) {
            throw new IllegalArgumentException("StorageRegions 数组长度不能超过 20");
        }
//        if (req.getMediaTypes() != null && req.getMediaTypes().length > 10) {
//            throw new IllegalArgumentException("MediaTypes 数组长度不能超过 10");
//        }
//        if (req.getStatus() != null && req.getStatus().length > 10) {
//            throw new IllegalArgumentException("Status 数组长度不能超过 10");
//        }
//        if (req.getReviewResults() != null && req.getReviewResults().length > 10) {
//            throw new IllegalArgumentException("ReviewResults 数组长度不能超过 10");
//        }
//        if (req.getTrtcSdkAppIds() != null && req.getTrtcSdkAppIds().length > 10) {
//            throw new IllegalArgumentException("TrtcSdkAppIds 数组长度不能超过 10");
//        }
//        if (req.getTrtcRoomIds() != null && req.getTrtcRoomIds().length > 10) {
//            throw new IllegalArgumentException("TrtcRoomIds 数组长度不能超过 10");
//        }
    }
}
