package com.ruoyi.ibs.dashboard.service.impl;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ibs.dashboard.domain.dto.NotificationDTO;
import com.ruoyi.ibs.dashboard.domain.vo.NotificationVO;
import com.ruoyi.ibs.dashboard.service.NotificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author 吴凯程
 * @Date 2025/4/1
 **/
@Service
@Slf4j
public class NotificationServiceImpl implements NotificationService {

    private final String NOTIFICATION_KEY = "NOTIFICATION_CONTENT_";
    private final String NOTIFICATION_DEPT_KEY = "NOTIFICATION_DEPT_CONTENT_";
    private final String NOTIFICATION_COUNT_KEY = "NOTIFICATION_COUNT_";

    @Resource
    private RedisCache redisCache;

    /**
     * @return
     */
    @Override
    public List<NotificationVO> getNotificationList() {
        List<NotificationVO> collect = new ArrayList<>();

        // 根据通知的键和当前用户的用户名生成一个模式字符串，用于匹配通知的键
        String pattern = NOTIFICATION_KEY + SecurityUtils.getUsername() + "*";
        // 从Redis缓存中获取匹配该模式的所有键
        Collection<String> keys = redisCache.keys(pattern);
        // 检查获取到的键集合是否为空，如果不为空，则进行进一步处理
        if (keys != null && keys.size() > 0) {
            // 使用流操作处理键集合，将每个键对应的值（通知对象）映射出来，并按读取状态排序
            for (String key : keys) {
                // 从Redis缓存中获取键对应的值（通知对象）
                NotificationVO notificationVO = redisCache.getCacheObject(key);
                // 返回通知对象
                collect.add(notificationVO);
            }
        }
        if(SecurityUtils.hasRole("branchAdmin")){
            pattern = NOTIFICATION_DEPT_KEY + SecurityUtils.getDeptId() + "*";
            keys = redisCache.keys(pattern);
            if (keys != null && keys.size() > 0) {
                for (String key : keys) {
                    NotificationVO notificationVO = redisCache.getCacheObject(key);
                    collect.add(notificationVO);
                }
            }
        }
        if (collect.size() > 0){
            collect = collect.stream().sorted((Comparator.comparing(NotificationVO::getReadStatus).thenComparing(NotificationVO::getCreateTime))).collect(Collectors.toList());
            return collect;
        }
        return null;
    }

    /**
     * @param notificationDTO
     * @return
     */
    @Override
    public String sendNotification(NotificationDTO notificationDTO) {
        // 创建一个通知对象
        NotificationVO notificationVO = new NotificationVO();
        // 设置通知的唯一标识UUID
        notificationVO.setUuid(UUID.randomUUID().toString());
        String key = null;
        String countKey = null;

        // 根据通知类型设置通知内容
        if(notificationDTO.getType().equals("0")){
            // 构建分配任务的通知内容
            String content = SecurityUtils.getLoginUser().getUser().getRoleName() + SecurityUtils.getLoginUser().getUser().getNickName() + "-" + SecurityUtils.getUsername()
                    + " 提醒您尽快去分配任务：" + notificationDTO.getTaskName();
            notificationVO.setContent(content);
            key = NOTIFICATION_DEPT_KEY + notificationDTO.getToDeptId() + "_" + notificationVO.getUuid();
            countKey = NOTIFICATION_COUNT_KEY + notificationDTO.getTaskName() + "_" + notificationDTO.getToDeptId();
        }else if (notificationDTO.getType().equals("1")){
            // 构建认领任务的通知内容
            String content = SecurityUtils.getLoginUser().getUser().getRoleName() + SecurityUtils.getLoginUser().getUser().getNickName() + "-" + SecurityUtils.getUsername()
                    + " 提醒您尽快去认领任务：" + notificationDTO.getTaskName() + "的客户";
            notificationVO.setContent(content);
            key = NOTIFICATION_KEY + notificationDTO.getToUserName() + "_" + notificationVO.getUuid();
            countKey = NOTIFICATION_COUNT_KEY + notificationDTO.getTaskName() + "_" + notificationDTO.getToUserName();
        }

        // 设置通知的阅读状态为未读
        notificationVO.setReadStatus(Boolean.FALSE);
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 创建 DateTimeFormatter 对象，并指定格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 格式化当前时间
        String formattedTime = now.format(formatter);
        // 设置通知的创建时间
        notificationVO.setCreateTime(formattedTime);

        // 检查今日是否已发送通知
        if (redisCache.hasKey(countKey)) {
            // 获取今日已发送的通知次数
            Integer count = redisCache.getCacheObject(countKey);
            // 如果今日通知次数超过2次，则抛出异常
            if (count > 2) {
                throw new ServiceException("今日已提醒3次，请勿重复提醒");
            }else{
                // 更新今日通知次数
                redisCache.setCacheObjectToEndDay(countKey, count + 1);
            }
        }else{
            // 初始化今日通知次数
            redisCache.setCacheObjectToEndDay(countKey, 1);
        }

        // 将通知对象存入Redis
        redisCache.setCacheObject(key, notificationVO);

        // 日志记录：发送的通知内容
        log.info("发送通知：" + notificationVO.getContent());

        // 返回消息通知发送成功的提示信息
        return "消息通知发送成功！";
    }

    /**
     * @param uuid
     * @return
     */
    @Override
    public String updateReadStatus(String uuid) {

        String pattern = "*" +  uuid + "*";
        Collection<String> keys = redisCache.keys(pattern);
        if (keys == null || keys.size() == 0){
            throw new ServiceException("消息不存在");
        }
        keys.forEach(key -> {
            // 从Redis缓存中获取通知对象
            NotificationVO notificationVO = redisCache.getCacheObject(key);

            // 设置通知的阅读状态为已读
            notificationVO.setReadStatus(Boolean.TRUE);

            // 更新Redis缓存中的通知对象，有效期至当天结束
            redisCache.setCacheObjectToEndDay(key, notificationVO);
        });
        // 返回表示消息已读的字符串
        return uuid + "消息已读";

    }


    /**
     * @param toUserName
     * @param content
     * @return
     */
    @Override
    public String sendNotification(String toUserName, String content) {
        String uuid = IdUtils.fastSimpleUUID();
        String key = NOTIFICATION_KEY + toUserName + "_" + uuid;

        // 创建一个通知对象
        NotificationVO notificationVO = new NotificationVO();
        // 设置通知的唯一标识UUID
        notificationVO.setUuid(uuid);

        notificationVO.setContent(content);

        // 设置通知的阅读状态为未读
        notificationVO.setReadStatus(Boolean.FALSE);
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 创建 DateTimeFormatter 对象，并指定格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 格式化当前时间
        String formattedTime = now.format(formatter);
        // 设置通知的创建时间
        notificationVO.setCreateTime(formattedTime);

        redisCache.setCacheObjectToEndDay(key, notificationVO);

        return "消息通知发送成功！";
    }
}
