package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.entity.Announcement;
import com.zhentao.mapper.AnnouncementMapper;
import com.zhentao.service.AnnouncementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 公告服务实现类
 */
@Service
public class AnnouncementServiceImpl implements AnnouncementService {
    
    @Autowired
    private AnnouncementMapper announcementMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String ANNOUNCEMENT_CHANNEL = "announcement:update";
    private static final String ANNOUNCEMENT_CACHE_KEY = "announcement:active";
    
    @Override
    public Page<Announcement> getAnnouncementList(int current, int size, Integer status) {
        Page<Announcement> page = new Page<>(current, size);
        LambdaQueryWrapper<Announcement> wrapper = new LambdaQueryWrapper<>();
        
        if (status != null) {
            wrapper.eq(Announcement::getStatus, status);
        }
        
        wrapper.orderByDesc(Announcement::getPriority)
               .orderByDesc(Announcement::getCreateTime);
        
        return announcementMapper.selectPage(page, wrapper);
    }
    
    @Override
    public List<Announcement> getActiveAnnouncements() {
        LambdaQueryWrapper<Announcement> wrapper = new LambdaQueryWrapper<>();
        LocalDateTime now = LocalDateTime.now();
        
        wrapper.eq(Announcement::getStatus, 1)
               .and(w -> w.isNull(Announcement::getStartTime)
                         .or()
                         .le(Announcement::getStartTime, now))
               .and(w -> w.isNull(Announcement::getEndTime)
                         .or()
                         .ge(Announcement::getEndTime, now))
               .orderByDesc(Announcement::getPriority)
               .orderByDesc(Announcement::getCreateTime);
        
        return announcementMapper.selectList(wrapper);
    }
    
    @Override
    public Announcement getAnnouncementById(Long id) {
        return announcementMapper.selectById(id);
    }
    
    @Override
    public boolean createAnnouncement(Announcement announcement) {
        int result = announcementMapper.insert(announcement);
        if (result > 0) {
            // 发布Redis消息，通知更新
            publishAnnouncementUpdate();
            return true;
        }
        return false;
    }
    
    @Override
    public boolean updateAnnouncement(Announcement announcement) {
        int result = announcementMapper.updateById(announcement);
        if (result > 0) {
            // 发布Redis消息，通知更新
            publishAnnouncementUpdate();
            return true;
        }
        return false;
    }
    
    @Override
    public boolean deleteAnnouncement(Long id) {
        int result = announcementMapper.deleteById(id);
        if (result > 0) {
            // 发布Redis消息，通知更新
            publishAnnouncementUpdate();
            return true;
        }
        return false;
    }
    
    @Override
    public boolean batchDeleteAnnouncements(List<Long> ids) {
        int result = announcementMapper.deleteBatchIds(ids);
        if (result > 0) {
            // 发布Redis消息，通知更新
            publishAnnouncementUpdate();
            return true;
        }
        return false;
    }
    
    @Override
    public boolean updateAnnouncementStatus(Long id, Integer status) {
        Announcement announcement = new Announcement();
        announcement.setId(id);
        announcement.setStatus(status);
        int result = announcementMapper.updateById(announcement);
        if (result > 0) {
            // 发布Redis消息，通知更新
            publishAnnouncementUpdate();
            return true;
        }
        return false;
    }
    
    /**
     * 发布公告更新消息到Redis
     */
    private void publishAnnouncementUpdate() {
        try {
            redisTemplate.convertAndSend(ANNOUNCEMENT_CHANNEL, System.currentTimeMillis());
            // 清除缓存
            redisTemplate.delete(ANNOUNCEMENT_CACHE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

