package com.lesingle.edu.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.edu.common.enums.GenericStatus;
import com.lesingle.edu.common.enums.NotificationRecipientType;
import com.lesingle.edu.common.enums.NotificationType;
import com.lesingle.edu.entity.SchedulePlan;
import com.lesingle.edu.entity.Teacher;
import com.lesingle.edu.mapper.SchedulePlanMapper;
import com.lesingle.edu.mapper.TeacherMapper;
import com.lesingle.edu.service.NotificationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

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

/**
 * 排课提醒定时任务
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ScheduleReminderTask {

    private final SchedulePlanMapper schedulePlanMapper;
    private final TeacherMapper teacherMapper;
    private final NotificationService notificationService;

    /**
     * 每天早上 7:00 发送当天排课提醒
     * cron: 秒 分 时 日 月 周
     */
    @Scheduled(cron = "0 0 7 * * ?")
    public void sendDailyScheduleReminder() {
        log.info("开始发送每日排课提醒...");

        LocalDate today = LocalDate.now();

        // 查询当天所有未取消且未发送提醒的排课
        LambdaQueryWrapper<SchedulePlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SchedulePlan::getScheduledDate, today)
                .ne(SchedulePlan::getStatus, GenericStatus.fromCode("CANCELLED").getCode())
                .eq(SchedulePlan::getReminderSent, 0);

        List<SchedulePlan> plans = schedulePlanMapper.selectList(wrapper);
        log.info("找到 {} 条待发送提醒的排课", plans.size());

        int successCount = 0;
        int failCount = 0;

        for (SchedulePlan plan : plans) {
            try {
                sendReminder(plan, "daily");
                // 标记已发送
                plan.setReminderSent(1);
                plan.setReminderSentAt(LocalDateTime.now());
                schedulePlanMapper.updateById(plan);
                successCount++;
            } catch (Exception e) {
                log.error("发送排课提醒失败: planId={}, error={}", plan.getId(), e.getMessage(), e);
                failCount++;
            }
        }

        log.info("每日排课提醒发送完成: 成功={}, 失败={}", successCount, failCount);
    }

    /**
     * 每 30 分钟检查即将开始的排课，发送提醒
     * 在课程开始前 30 分钟发送提醒
     */
    @Scheduled(cron = "0 0/30 * * * ?")
    public void sendUpcomingScheduleReminder() {
        log.debug("检查即将开始的排课...");

        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();
        LocalTime after30Minutes = now.plusMinutes(30);

        // 查询今天、未取消、未发送即将提醒、开始时间在接下来 30 分钟内的排课
        LambdaQueryWrapper<SchedulePlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SchedulePlan::getScheduledDate, today)
                .ne(SchedulePlan::getStatus, GenericStatus.fromCode("CANCELLED").getCode());

        List<SchedulePlan> plans = schedulePlanMapper.selectList(wrapper);

        for (SchedulePlan plan : plans) {
            try {
                LocalTime startTime = parseStartTime(plan.getScheduledTime());
                if (startTime == null) {
                    continue;
                }

                // 判断是否在接下来 30 分钟内开始
                if (startTime.isAfter(now) && !startTime.isAfter(after30Minutes)) {
                    // 检查是否已发送过即将开始提醒（使用 reminderSent 字段值为 2 表示已发送即将开始提醒）
                    if (plan.getReminderSent() == null || plan.getReminderSent() < 2) {
                        sendReminder(plan, "upcoming");
                        // 标记已发送即将开始提醒（设置为 2）
                        plan.setReminderSent(2);
                        plan.setReminderSentAt(LocalDateTime.now());
                        schedulePlanMapper.updateById(plan);
                        log.info("发送即将开始提醒: planId={}, time={}", plan.getId(), plan.getScheduledTime());
                    }
                }
            } catch (Exception e) {
                log.error("处理即将开始排课失败: planId={}, error={}", plan.getId(), e.getMessage());
            }
        }
    }

    /**
     * 发送提醒通知
     */
    private void sendReminder(SchedulePlan plan, String reminderType) {
        String title;
        String content;

        if ("daily".equals(reminderType)) {
            title = "今日课程提醒";
            content = String.format("您有课程「%s」安排在今天 %s，请提前做好准备。",
                    plan.getName(), plan.getScheduledTime());
        } else {
            title = "课程即将开始";
            content = String.format("您的课程「%s」将在 30 分钟内（%s）开始，请做好准备。",
                    plan.getName(), plan.getScheduledTime());
        }

        // 发送给教师
        if (plan.getTeacherId() != null) {
            Teacher teacher = teacherMapper.selectById(plan.getTeacherId());
            if (teacher != null) {
                notificationService.createNotification(
                        plan.getTenantId(),
                        0L,
                        NotificationType.SYSTEM.getCode(),
                        title,
                        content,
                        NotificationType.SCHEDULE.getCode(),
                        NotificationRecipientType.TEACHER.getCode(),
                        plan.getTeacherId()
                );
            }
        }

        // 可以扩展：发送给班级相关的人员（如班主任等）
    }

    /**
     * 解析开始时间
     */
    private LocalTime parseStartTime(String scheduledTime) {
        if (scheduledTime == null || scheduledTime.isEmpty()) {
            return null;
        }

        try {
            String[] parts = scheduledTime.split("-");
            if (parts.length >= 1) {
                return LocalTime.parse(parts[0].trim());
            }
        } catch (Exception e) {
            log.warn("解析时间失败: {}", scheduledTime);
        }

        return null;
    }

}
