package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhentao.common.PageResult;
import com.zhentao.dto.DynamicQueryDTO;
import com.zhentao.entity.UserDynamics;
import com.zhentao.mapper.UserDynamicsMapper;
import com.zhentao.service.UserDynamicsService;
import com.zhentao.vo.DynamicVO;
import com.zhentao.vo.UserSimpleVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户动态服务实现类
 */
@Service
public class UserDynamicsServiceImpl implements UserDynamicsService {

    @Autowired
    private UserDynamicsMapper userDynamicsMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private static final String DYNAMIC_CACHE_KEY = "dynamic:detail:";
    private static final String VIEW_COUNT_KEY = "dynamic:view:";
    private static final String SYS_MSG_QUEUE = "system.message";

    @Autowired
    private com.zhentao.service.SystemMessageService systemMessageService;

    @Autowired
    private com.zhentao.mapper.DynamicReportsMapper reportMapper;

    @Override
    public PageResult<DynamicVO> getDynamicList(DynamicQueryDTO queryDTO) {
        // 创建分页对象
        Page<UserDynamics> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        
        // 查询数据
        IPage<UserDynamics> dynamicsPage = userDynamicsMapper.selectDynamicsWithUserInfo(
                page,
                queryDTO.getCurrentUserId(),
                queryDTO.getAuditStatus() != null ? queryDTO.getAuditStatus() : 1, // 默认查询审核通过的
                queryDTO.getVisibility() != null ? queryDTO.getVisibility() : 1 // 默认查询公开的
        );

        // 转换为VO
        List<DynamicVO> voList = dynamicsPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 返回分页结果
        return new PageResult<>(voList, dynamicsPage.getTotal(), dynamicsPage.getCurrent(), dynamicsPage.getSize());
    }

    @Override
    public DynamicVO getDynamicDetail(Integer dynamicId, Integer userId) {
        // 先从缓存获取（容错）
        String cacheKey = DYNAMIC_CACHE_KEY + dynamicId + ":" + userId;
        try {
            Object cached = redisTemplate.opsForValue().get(cacheKey);
            if (cached != null) {
                return (DynamicVO) cached;
            }
        } catch (Exception ignore) {
            // ignore redis failures
        }

        // 从数据库查询
        UserDynamics dynamic = userDynamicsMapper.selectDynamicDetailById(dynamicId, userId);
        if (dynamic == null) {
            return null;
        }

        // 转换为VO
        DynamicVO vo = convertToVO(dynamic);

        // 异步增加浏览数（容错）
        increaseViewCount(dynamicId);

        // 缓存结果（5分钟，容错）
        try {
            redisTemplate.opsForValue().set(cacheKey, vo, 5, TimeUnit.MINUTES);
        } catch (Exception ignore) {
        }

        return vo;
    }

    @Override
    public PageResult<DynamicVO> getUserDynamics(DynamicQueryDTO queryDTO) {
        if (queryDTO.getTargetUserId() == null) {
            throw new IllegalArgumentException("目标用户ID不能为空");
        }

        // 创建分页对象
        Page<UserDynamics> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        // 查询数据
        IPage<UserDynamics> dynamicsPage = userDynamicsMapper.selectDynamicsByUserId(
                page,
                queryDTO.getTargetUserId(),
                queryDTO.getCurrentUserId()
        );

        // 转换为VO
        List<DynamicVO> voList = dynamicsPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 返回分页结果
        return new PageResult<>(voList, dynamicsPage.getTotal(), dynamicsPage.getCurrent(), dynamicsPage.getSize());
    }

    @Override
    public void increaseViewCount(Integer dynamicId) {
        // 使用Redis记录浏览数，定期同步到数据库（容错）
        String key = VIEW_COUNT_KEY + dynamicId;
        try {
            redisTemplate.opsForValue().increment(key, 1);
            redisTemplate.expire(key, 1, TimeUnit.DAYS);
        } catch (Exception ignore) {
            // ignore redis failures
        }
        // TODO: 定时任务批量同步到数据库
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminModerate(Integer dynamicId, Integer action, String reason) {
        if (dynamicId == null || action == null || reason == null || reason.trim().isEmpty()) {
            throw new IllegalArgumentException("参数不合法");
        }

        // 2=封禁 3=删除（沿用status逻辑：1正常，2封禁，3删除）
        int updated = userDynamicsMapper.updateDynamicStatus(dynamicId, action, reason);
        if (updated <= 0) {
            return false;
        }

        // 查询动态以获取标题和作者
        UserDynamics dynamic = userDynamicsMapper.selectById(dynamicId);
        Integer authorId = dynamic != null ? dynamic.getUserId() : null;
        String titleFull = dynamic != null ? (dynamic.getContent() == null ? "" : dynamic.getContent()) : "";
        String dynamicTitle = titleFull.length() > 20 ? titleFull.substring(0,20) + "..." : titleFull;

        // 直接落库存储系统消息（后续可扩展为MQ）——被举报人（作者）
        try {
            String type = action == 2 ? "ban" : (action == 3 ? "delete" : "unban");
            systemMessageService.sendDynamicModerationMessage(authorId, dynamicId, dynamicTitle, type, reason);
        } catch (Exception ignore) {}

        // 通知所有举报人（封禁/删除/解除封禁均发送结果通知）
        if (action == 1 || action == 2 || action == 3) {
            try {
                // 查询该动态的所有举报记录，逐个发送“举报处理结果”通知
                java.util.List<com.zhentao.entity.DynamicReports> reports =
                        reportMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<com.zhentao.entity.DynamicReports>()
                                .eq("dynamic_id", dynamicId));
                if (reports != null) {
                    String resultText = (action == 2 ? "已封禁" : (action == 3 ? "已删除" : "已解除封禁"));
                    for (com.zhentao.entity.DynamicReports r : reports) {
                        if (r.getReporterId() == null) continue;
                        String resTitle = "系统通知 - 举报处理结果";
                        String resContent = String.format("您举报的动态《%s》已被处理（%s），感谢您对社区规范的维护。", dynamicTitle, resultText);
                        systemMessageService.sendMessage(r.getReporterId(), dynamicId, resTitle, resContent, "report_result");
                    }
                }
            } catch (Exception ignore) {}
        }

        // 同时向系统消息通道发送一条通知（可供其他服务订阅）
        try {
            java.util.Map<String, Object> payload = new java.util.HashMap<>();
            String type = action == 2 ? "ban" : (action == 3 ? "delete" : "unban");
            payload.put("type", type);
            payload.put("dynamicId", dynamicId);
            payload.put("reason", reason);
            payload.put("time", java.time.LocalDateTime.now().toString());
            payload.put("authorId", authorId);
            redisTemplate.convertAndSend(SYS_MSG_QUEUE, payload);
        } catch (Exception ignore) {}

        return true;
    }

    /**
     * 将实体类转换为VO
     */
    private DynamicVO convertToVO(UserDynamics dynamic) {
        DynamicVO vo = new DynamicVO();
        BeanUtils.copyProperties(dynamic, vo);

        // 解析媒体URL JSON字符串
        if (dynamic.getMediaUrls() != null && !dynamic.getMediaUrls().isEmpty()) {
            try {
                List<String> urls = objectMapper.readValue(
                        dynamic.getMediaUrls(), 
                        new TypeReference<List<String>>() {}
                );
                vo.setMediaUrls(urls);
            } catch (Exception e) {
                vo.setMediaUrls(new ArrayList<>());
            }
        } else {
            vo.setMediaUrls(new ArrayList<>());
        }

        // 转换用户信息
        if (dynamic.getUser() != null) {
            UserSimpleVO userVO = new UserSimpleVO();
            userVO.setUserId(dynamic.getUser().getUserId());
            userVO.setNickname(dynamic.getUser().getNickname());
            userVO.setAvatarUrl(dynamic.getUser().getAvatarUrl());
            userVO.setGender(dynamic.getUser().getGender());
            vo.setUser(userVO);
        }

        return vo;
    }
}


