package com.ruoyi.base.service.impl;

import com.ruoyi.base.service.IBroadcastRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class BroadcastRecordServiceImpl implements IBroadcastRecordService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final Logger log = LoggerFactory.getLogger(BroadcastRecordServiceImpl.class);

    private static final String KEY_PREFIX = "broadcast:next:";
    private static final int DEFAULT_EXPIRE_HOURS = 24;

    /**
     * 判断任务是否应该播报
     *
     * @param taskId 任务ID
     * @param frequencyMinutes 播报频率（分钟）
     * @return true-可以播报，false-未到播报时间
     */
    public boolean shouldBroadcast(Long taskId, Integer frequencyMinutes) {
        // 频率为空或小于等于0，允许播报
        if (frequencyMinutes == null || frequencyMinutes <= 0) {
            return true;
        }

        String key = buildKey(taskId);
        String nextTimeStr = redisTemplate.opsForValue().get(key);

        long now = System.currentTimeMillis();
        log.info("[播报记录] 检查是否可播报, 任务ID: {}, 频率: {}分钟, 下次播报时间: {}, 当前时间: {}",
                taskId, frequencyMinutes, nextTimeStr, now);

        // Redis中无记录，首次播报
        if (nextTimeStr == null) {
            return true;
        }

        try {
            long nextTime = Long.parseLong(nextTimeStr);

            // 健壮性检查：如果下次播报时间是过去的时间（可能是旧数据），立即播报
            // 如果下次播报时间距离现在超过7天（异常数据），也视为无效
            long sevenDaysMs = 7 * 24 * 60 * 60 * 1000L;
            if (nextTime <= now || (nextTime - now) > sevenDaysMs) {
                log.warn("[播报记录] 下次播报时间异常（已过期或太远），视为可播报: {}", nextTime);
                return true;
            }

            // 比较当前时间是否到达下次播报时间
            boolean result = now >= nextTime;
            log.info("[播报记录] 播报检查结果, 当前时间: {} >= 下次播报时间: {}, 结果: {}", now, nextTime, result);
            return result;
        } catch (NumberFormatException e) {
            // 解析失败，允许播报
            return true;
        }
    }


    /**
     * 记录播报（仅记录当前时间，不计算下次时间）
     * 注意：此方法未被使用，实际使用的是带频率参数的版本
     *
     * @param taskId 任务ID
     */
    public void recordBroadcast(Long taskId) {
        // 记录的是当前播报时间戳
        String key = buildKey(taskId);
        long currentMs = System.currentTimeMillis();
        System.out.println("zmj1下次可播报时间: ");
        redisTemplate.opsForValue().set(
                key,
                String.valueOf(currentMs),
                DEFAULT_EXPIRE_HOURS,
                TimeUnit.HOURS
        );
        log.info("[播报记录] 记录播报时间, 任务ID: {}, 键: {}, 时间戳: {}", taskId, key, currentMs);
    }

    /**
     * 记录播报并设置下次可播报时间
     * 这是主要使用的方法，直接计算并存储下次可播报的时间点
     *
     * @param taskId 任务ID
     * @param frequencyMinutes 播报频率（分钟）
     */
    public void recordBroadcast(Long taskId, Integer frequencyMinutes) {
        String key = buildKey(taskId);
        // 计算下次可播报时间 = 当前时间 + 频率分钟数
        long nextTime = System.currentTimeMillis() + frequencyMinutes * 60 * 1000L;
        System.out.println("zmj2下次可播报时间: " + nextTime);
        redisTemplate.opsForValue().set(
                key,
                String.valueOf(nextTime),
                DEFAULT_EXPIRE_HOURS,
                TimeUnit.HOURS
        );
        log.info("[播报记录] 记录下次播报时间, 任务ID: {}, 键: {}, 下次播报时间: {}", taskId, key, nextTime);
    }

    /**
     * 清除播报记录
     *
     * @param taskId 任务ID
     */
    public void clearRecord(Long taskId) {
        String key = buildKey(taskId);
        redisTemplate.delete(key);
    }

    /**
     * 获取距离下次播报的剩余秒数
     * 用于前端显示倒计时
     *
     * @param taskId 任务ID
     * @param frequencyMinutes 播报频率（分钟）
     * @return 剩余秒数，0表示可以立即播报
     */
    public long getRemainingSeconds(Long taskId, Integer frequencyMinutes) {
        String key = buildKey(taskId);
        String nextTimeStr = redisTemplate.opsForValue().get(key);

        // 无记录，返回0
        if (nextTimeStr == null) {
            return 0;
        }

        try {
            long nextTime = Long.parseLong(nextTimeStr);
            long now = System.currentTimeMillis();

            // 如果下次播报时间是过去的时间，返回0
            // 如果下次播报时间距离现在超过7天，返回0
            long sevenDaysMs = 7 * 24 * 60 * 60 * 1000L;
            if (nextTime <= now || (nextTime - now) > sevenDaysMs) {
                return 0;
            }

            // 计算剩余秒数
            long remaining = nextTime - now;
            return Math.max(0, remaining / 1000);
        } catch (NumberFormatException e) {
            // 解析失败，返回0
            return 0;
        }
    }

    private String buildKey(Long taskId) {
        return KEY_PREFIX + (taskId != null ? taskId : "unknown");
    }
}
