package com.kym.admin.jobs;

import cn.hutool.extra.mail.MailUtil;
import com.kym.common.utils.CommUtil;
import com.kym.entity.common.RedisKeys;
import com.kym.service.cache.KymCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author skyline
 * @description 设备离线通知
 * @date 2023-09-30 16:15
 */
@Component
@Slf4j
public class OfflineNotifyJob {

    private final StringRedisTemplate redisTemplate;

    @Value("${kym.notify-email}")
    private String notifyEmail;

    @Value("${kym.notify-email-switch}")
    private boolean notifyEmailSwitch;

    public OfflineNotifyJob(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 每小时的第30分钟执行一次
    @Scheduled(cron = "0 30 0/1 * * ? ")
    public void execute() {
        // 查询redis离线设备消息队列，存在且超过1小时的消息则发送邮件提醒
        Set<String> offlineList = redisTemplate.opsForZSet().rangeByScore(RedisKeys.OFFLINE, System.currentTimeMillis() - 60 * 60 * 1000, System.currentTimeMillis() + 60 * 60 * 1000);
        if (!CommUtil.isEmptyOrNull(offlineList)) {
            /*
             * 格式：
             * 【设备离线通知】
             * 【阳光科创中心】：001001,001002,001003
             * 【阳光粤海家园】：002001,002002,002003
             */
            var temp = "【%s】:%s\n";
            var map = new ArrayList<String>(offlineList).stream()
                    .collect(Collectors.toMap(KymCache.INSTANCE::getShortIdByEquipmentIdOrConnectorId, KymCache.INSTANCE::getStationNameByConnectorId));
            // 以站点名称分组
            var list = map.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue));
            StringBuilder sb = new StringBuilder();
            list.forEach((k, v) -> sb.append(temp.formatted(k, StringUtils.join(v.stream().map(Map.Entry::getKey).sorted(Comparator.comparingInt(Integer::parseInt)).toList(), ","))));
            log.warn(sb.toString());
            // 格式化信息，发送邮件
            redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, offlineList.toArray(Object[]::new));
            redisTemplate.opsForSet().add(RedisKeys.OFFLINE_EXPIRED, offlineList.toArray(String[]::new));
            if (notifyEmailSwitch) {
                MailUtil.send(notifyEmail, "【设备离线通知】", sb.toString(), false);
            }
        }

    }
}
