package com.ruoyi.base.service.impl;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.event.BroadcastStartedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import com.ruoyi.base.mapper.RobotOpsBroadcastTaskMapper;
import com.ruoyi.base.domain.RobotOpsBroadcastTask;
import com.ruoyi.base.domain.RobotOpsBroadcastContent;
import com.ruoyi.base.service.IBroadcastRecordService;
import com.ruoyi.base.service.IRobotOpsBroadcastContentService;
import com.ruoyi.base.service.IRobotOpsBroadcastTaskService;

/**
 * 播报任务Service业务层处理
 *
 * @author ruoyi
 * @date 2026-04-27
 */
@Service
public class RobotOpsBroadcastTaskServiceImpl implements IRobotOpsBroadcastTaskService
{
    private static final Logger log = LoggerFactory.getLogger(RobotOpsBroadcastTaskServiceImpl.class);

    @Autowired
    private IBroadcastRecordService broadcastRecordService;

    @Autowired
    private IRobotOpsBroadcastContentService broadcastContentService;

    /** 事件发布器 */
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /** 资源访问基础URL，用于补全音频路径 */
    @Value("${screen.resource-base-url:}")
    private String resourceBaseUrl;

    /** 启用状态：0=停用，1=启用 */
    private static final String STATUS_ENABLED = "1";

    /** 循环类型：1=每天，2=工作日，3=指定日期 */
    private static final Long CYCLE_TYPE_DAILY = 1L;
    private static final Long CYCLE_TYPE_WEEKDAY = 2L;
    private static final Long CYCLE_TYPE_SPECIFIC = 3L;

    @Autowired
    private RobotOpsBroadcastTaskMapper robotOpsBroadcastTaskMapper;

    /**
     * 查询播报任务
     *
     * @param id 播报任务主键
     * @return 播报任务
     */
    @Override
    public RobotOpsBroadcastTask selectRobotOpsBroadcastTaskById(Long id)
    {
        return robotOpsBroadcastTaskMapper.selectRobotOpsBroadcastTaskById(id);
    }

    /**
     * 查询播报任务列表
     *
     * @param robotOpsBroadcastTask 播报任务
     * @return 播报任务
     */
    @Override
    public List<RobotOpsBroadcastTask> selectRobotOpsBroadcastTaskList(RobotOpsBroadcastTask robotOpsBroadcastTask)
    {
        return robotOpsBroadcastTaskMapper.selectRobotOpsBroadcastTaskList(robotOpsBroadcastTask);
    }

    /**
     * 新增播报任务
     *
     * @param robotOpsBroadcastTask 播报任务
     * @return 结果
     */
    @Override
    public int insertRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask)
    {
        robotOpsBroadcastTask.setCreateTime(DateUtils.getNowDate());
        return robotOpsBroadcastTaskMapper.insertRobotOpsBroadcastTask(robotOpsBroadcastTask);
    }

    /**
     * 修改播报任务
     *
     * @param robotOpsBroadcastTask 播报任务
     * @return 结果
     */
    @Override
    public int updateRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask)
    {
        robotOpsBroadcastTask.setUpdateTime(DateUtils.getNowDate());
        return robotOpsBroadcastTaskMapper.updateRobotOpsBroadcastTask(robotOpsBroadcastTask);
    }

    /**
     * 批量删除播报任务
     *
     * @param ids 需要删除的播报任务主键
     * @return 结果
     */
    @Override
    public int deleteRobotOpsBroadcastTaskByIds(Long[] ids)
    {
        return robotOpsBroadcastTaskMapper.deleteRobotOpsBroadcastTaskByIds(ids);
    }

    /**
     * 删除播报任务信息
     *
     * @param id 播报任务主键
     * @return 结果
     */
    @Override
    public int deleteRobotOpsBroadcastTaskById(Long id)
    {
        return robotOpsBroadcastTaskMapper.deleteRobotOpsBroadcastTaskById(id);
    }

    /**
     * 获取当前播报任务（根据时间和循环类型判断）
     */
    @Override
    public RobotOpsBroadcastTask selectCurrentBroadcastTask()
    {
        try
        {
            // 获取所有启用的任务
            RobotOpsBroadcastTask query = new RobotOpsBroadcastTask();
            query.setStatus(STATUS_ENABLED);
            List<RobotOpsBroadcastTask> enabledTasks = robotOpsBroadcastTaskMapper.selectRobotOpsBroadcastTaskList(query);

            if (enabledTasks == null || enabledTasks.isEmpty())
            {
                return null;
            }

            LocalTime now = LocalTime.now();
            LocalDate today = LocalDate.now();

            for (RobotOpsBroadcastTask task : enabledTasks)
            {
                // 检查时间范围
                if (!isWithinTimeRange(task, now))
                {
                    continue;
                }

                // 检查循环类型
                if (!isCycleMatch(task, today))
                {
                    continue;
                }

                // 检查播报频率（根据上次播报时间判断是否应该再次播报）
                if (!broadcastRecordService.shouldBroadcast(task.getId(), Math.toIntExact(task.getFrequencyMinutes())))
                {
                    log.debug("[BroadcastTask] 播报任务频率未到，ID: {}, 名称: {}, 频率: {}分钟",
                            task.getId(), task.getTaskName(), task.getFrequencyMinutes());
                    continue;
                }

                log.info("[BroadcastTask] 命中播报任务，ID: {}, 名称: {}", task.getId(), task.getTaskName());

                // 发布播报开始事件
                publishBroadcastStartedEvent(task);

                return task;
            }

            return null;
        }
        catch (Exception e)
        {
            log.error("[BroadcastTask] 获取当前播报任务异常: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 发布播报开始事件
     */
    private void publishBroadcastStartedEvent(RobotOpsBroadcastTask task)
    {
        if (eventPublisher == null || task == null || task.getContentId() == null)
        {
            return;
        }
        try
        {
            // 获取播报内容
            RobotOpsBroadcastContent content = broadcastContentService.selectRobotOpsBroadcastContentById(task.getContentId());
            if (content == null)
            {
                log.warn("[BroadcastTask] 播报内容不存在，contentId: {}", task.getContentId());
                return;
            }

            // 检查内容是否启用
            if (!"1".equals(content.getStatus()))
            {
                log.info("[BroadcastTask] 播报内容未启用，contentId: {}", content.getId());
                return;
            }

            // 检查音频是否合成成功
            if (!"1".equals(content.getAudioStatus()) || content.getAudioPath() == null || content.getAudioPath().isEmpty())
            {
                log.info("[BroadcastTask] 播报内容音频未就绪，contentId: {}, audioStatus: {}",
                        content.getId(), content.getAudioStatus());
                return;
            }

            // 补全音频 URL
            String audioUrl = completeAudioUrl(content.getAudioPath());

            // 转换内容类型
            String contentType = convertContentType(content.getContentType());

            // 发布播报开始事件
            BroadcastStartedEvent event = new BroadcastStartedEvent(
                    this,
                    task.getId(),
                    content.getId(),
                    task.getTaskName(),
                    content.getContentName(),
                    content.getBroadcastText(),
                    contentType,
                    audioUrl,
                    content.getAudioDuration()
            );
            eventPublisher.publishEvent(event);

            // 记录下次可播报时间 = 当前时间 + 频率
            broadcastRecordService.recordBroadcast(task.getId(), task.getFrequencyMinutes().intValue());

            log.info("[BroadcastTask] 发布播报开始事件，taskId: {}, 频率: {}分钟", task.getId(), task.getFrequencyMinutes());
        }
        catch (Exception e)
        {
            log.error("[BroadcastTask] 发布播报开始事件失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 补全音频 URL
     */
    private String completeAudioUrl(String audioPath)
    {
        if (audioPath == null || audioPath.isEmpty())
        {
            return "";
        }
        // 如果已经是完整 URL（包含 http 或 /profile）
        if (audioPath.startsWith("http://") || audioPath.startsWith("https://"))
        {
            return audioPath;
        }
        if (audioPath.startsWith("/profile/"))
        {
            return audioPath;
        }
        // 如果配置了资源基础 URL
        if (resourceBaseUrl != null && !resourceBaseUrl.isEmpty())
        {
            if (audioPath.startsWith("/"))
            {
                return resourceBaseUrl + audioPath;
            }
            else
            {
                return resourceBaseUrl + "/" + audioPath;
            }
        }
        // 默认拼接 /profile/
        if (audioPath.startsWith("/"))
        {
            return "/profile" + audioPath;
        }
        else
        {
            return "/profile/" + audioPath;
        }
    }

    /**
     * 转换内容类型
     */
    private String convertContentType(Long contentType)
    {
        if (contentType == null)
        {
            return "custom";
        }
        switch (contentType.intValue())
        {
            case 1:
                return "notice";
            case 2:
                return "promotion";
            case 3:
                return "tip";
            case 4:
                return "security";
            default:
                return "custom";
        }
    }

    /**
     * 获取当前播报任务及其关联的播报内容
     */
    @Override
    public Map<String, Object> selectCurrentBroadcastTaskWithContent()
    {
        try
        {
            RobotOpsBroadcastTask task = selectCurrentBroadcastTask();
            if (task == null)
            {
                return null;
            }

            Map<String, Object> result = new HashMap<>();
            result.put("taskId", task.getId());
            result.put("taskName", task.getTaskName());
            result.put("contentId", task.getContentId());
            result.put("startTime", task.getStartTime());
            result.put("endTime", task.getEndTime());

            return result;
        }
        catch (Exception e)
        {
            log.error("[BroadcastTask] 获取当前播报任务及内容异常: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 检查当前时间是否在任务时间范围内
     */
    private boolean isWithinTimeRange(RobotOpsBroadcastTask task, LocalTime now)
    {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");

        // 检查开始时间
        if (task.getStartTime() != null && !task.getStartTime().isEmpty())
        {
            try
            {
                LocalTime startTime = LocalTime.parse(task.getStartTime(), formatter);
                if (now.isBefore(startTime))
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                log.warn("[BroadcastTask] 解析开始时间失败: {}", task.getStartTime());
            }
        }

        // 检查结束时间
        if (task.getEndTime() != null && !task.getEndTime().isEmpty())
        {
            try
            {
                LocalTime endTime = LocalTime.parse(task.getEndTime(), formatter);
                if (now.isAfter(endTime))
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                log.warn("[BroadcastTask] 解析结束时间失败: {}", task.getEndTime());
            }
        }

        return true;
    }

    /**
     * 检查当前日期是否匹配循环规则
     */
    private boolean isCycleMatch(RobotOpsBroadcastTask task, LocalDate today)
    {
        if (task.getCycleType() == null)
        {
            // 没有设置循环类型，默认每天
            return true;
        }

        if (task.getCycleType() == CYCLE_TYPE_DAILY) {// 每天
            return true;
        } else if (task.getCycleType() == CYCLE_TYPE_WEEKDAY) {// 工作日（周一到周五）
            DayOfWeek dayOfWeek = today.getDayOfWeek();
            return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
        } else if (task.getCycleType() == CYCLE_TYPE_SPECIFIC) {// 指定日期，cycleValue 格式为 "1,2,3,4,5,6,7" 表示周一到周日
            return isSpecificDayMatch(task.getCycleValue(), today);
        }
        return true;
    }

    /**
     * 检查指定日期是否匹配
     */
    private boolean isSpecificDayMatch(String cycleValue, LocalDate today)
    {
        if (cycleValue == null || cycleValue.trim().isEmpty())
        {
            return true;
        }

        try
        {
            DayOfWeek dayOfWeek = today.getDayOfWeek();
            int dayNum = dayOfWeek.getValue(); // 1=周一, 7=周日

            String[] days = cycleValue.split(",");
            for (String day : days)
            {
                if (day.trim().equals(String.valueOf(dayNum)))
                {
                    return true;
                }
            }
            return false;
        }
        catch (Exception e)
        {
            log.warn("[BroadcastTask] 解析指定日期失败: {}, 错误: {}", cycleValue, e.getMessage());
            return true; // 解析失败时默认匹配
        }
    }
}
