import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { PrismaService } from '../../database/prisma.service';
import { NotificationService } from './notification.service';

@Injectable()
export class ScheduleNotificationService {
  private readonly logger = new Logger(ScheduleNotificationService.name);
  private isProcessing = false;

  constructor(
    private prisma: PrismaService,
    private notificationService: NotificationService,
  ) {}

  /**
   * 每30分钟检查一次即将开始的课程
   * 发送提醒给相关教师
   */
  @Cron(CronExpression.EVERY_30_MINUTES)
  async handleUpcomingScheduleReminders() {
    if (this.isProcessing) {
      this.logger.debug('Previous reminder task still processing, skipping...');
      return;
    }

    this.isProcessing = true;

    try {
      const now = new Date();

      // 计算接下来30分钟的时间范围
      const thirtyMinutesLater = new Date(now.getTime() + 30 * 60 * 1000);

      // 查找即将开始的排课（今天，未发送提醒）
      const upcomingSchedules = await this.prisma.schedulePlan.findMany({
        where: {
          status: 'ACTIVE',
          reminderSent: false,
          scheduledDate: {
            gte: new Date(now.toISOString().split('T')[0] + 'T00:00:00.000Z'),
            lt: new Date(now.toISOString().split('T')[0] + 'T23:59:59.999Z'),
          },
          teacherId: { not: null },
        },
        include: {
          teacher: {
            select: { id: true, name: true },
          },
          course: {
            select: { name: true, pictureBookName: true },
          },
          class: {
            select: { name: true },
          },
        },
      });

      // 过滤出即将开始的排课（根据时间段）
      const schedulesToRemind = upcomingSchedules.filter((schedule) => {
        if (!schedule.scheduledTime) return false;

        // 解析时间 "09:00-09:30"
        const [startTime] = schedule.scheduledTime.split('-');
        if (!startTime) return false;

        const [hours, minutes] = startTime.split(':').map(Number);
        const scheduleStartTime = new Date(now);
        scheduleStartTime.setHours(hours, minutes, 0, 0);

        // 检查是否在接下来的30分钟内
        return scheduleStartTime >= now && scheduleStartTime <= thirtyMinutesLater;
      });

      this.logger.log(`Found ${schedulesToRemind.length} schedules to send reminders for`);

      // 发送提醒
      for (const schedule of schedulesToRemind) {
        try {
          await this.sendScheduleReminder(schedule);
        } catch (error) {
          this.logger.error(`Failed to send reminder for schedule ${schedule.id}:`, error);
        }
      }
    } catch (error) {
      this.logger.error('Error in schedule reminder task:', error);
    } finally {
      this.isProcessing = false;
    }
  }

  /**
   * 发送单个排课提醒
   */
  private async sendScheduleReminder(schedule: any) {
    if (!schedule.teacherId || !schedule.teacher) {
      return;
    }

    const courseName = schedule.course?.pictureBookName || schedule.course?.name || '课程';
    const className = schedule.class?.name || '班级';
    const timeStr = schedule.scheduledTime || '时间待定';

    // 创建通知
    await this.notificationService.createNotification({
      tenantId: schedule.tenantId,
      recipientType: 'TEACHER',
      recipientId: schedule.teacherId,
      title: '课程提醒',
      content: `您即将在 ${timeStr} 为「${className}」讲授《${courseName}》，请做好准备。`,
      notificationType: 'LESSON',
      relatedType: 'SchedulePlan',
      relatedId: schedule.id,
    });

    // 标记已发送提醒
    await this.prisma.schedulePlan.update({
      where: { id: schedule.id },
      data: {
        reminderSent: true,
        reminderSentAt: new Date(),
      },
    });

    this.logger.log(
      `Reminder sent for schedule ${schedule.id} to teacher ${schedule.teacherId}`
    );
  }

  /**
   * 手动触发提醒检查（用于测试）
   */
  async triggerReminderCheck() {
    this.logger.log('Manual trigger of reminder check');
    await this.handleUpcomingScheduleReminders();
    return { message: 'Reminder check triggered' };
  }

  /**
   * 重置所有提醒状态（用于测试或重置）
   */
  async resetAllReminders() {
    const result = await this.prisma.schedulePlan.updateMany({
      where: {
        reminderSent: true,
      },
      data: {
        reminderSent: false,
        reminderSentAt: null,
      },
    });

    this.logger.log(`Reset ${result.count} schedule reminders`);

    return { message: `Reset ${result.count} reminders` };
  }

  // ==================== 任务提醒 ====================

  /**
   * 每天早上9点检查即将到期的任务
   * 发送提醒给家长
   */
  @Cron('0 9 * * *') // 每天早上9点
  async handleTaskDeadlineReminders() {
    this.logger.log('Starting task deadline reminder check...');

    try {
      const now = new Date();
      const threeDaysLater = new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000);
      const oneDayLater = new Date(now.getTime() + 24 * 60 * 60 * 1000);

      // 查找即将到期且未完成的任务
      const tasksToRemind = await this.prisma.task.findMany({
        where: {
          status: 'PUBLISHED',
          endDate: {
            gte: now,
            lte: threeDaysLater,
          },
        },
        include: {
          course: {
            select: { name: true, pictureBookName: true },
          },
          completions: {
            where: {
              status: { not: 'COMPLETED' },
            },
            include: {
              student: {
                select: {
                  id: true,
                  name: true,
                  parents: {
                    include: {
                      parent: {
                        select: { id: true },
                      },
                    },
                  },
                },
              },
            },
          },
        },
      });

      this.logger.log(`Found ${tasksToRemind.length} tasks with upcoming deadlines`);

      let reminderCount = 0;

      for (const task of tasksToRemind) {
        const daysRemaining = Math.ceil(
          (task.endDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000)
        );

        // 只在截止前3天、1天、当天发送提醒
        if (![3, 1, 0].includes(daysRemaining)) continue;

        const taskName = task.course?.pictureBookName || task.course?.name || task.title;

        for (const completion of task.completions) {
          // 发送提醒给每个学生的家长
          for (const parentRelation of completion.student.parents) {
            try {
              await this.notificationService.createNotification({
                tenantId: task.tenantId,
                recipientType: 'PARENT',
                recipientId: parentRelation.parent.id,
                title: '任务即将截止',
                content: `「${completion.student.name}」的任务《${taskName}》将在${daysRemaining === 0 ? '今天' : daysRemaining + '天后'}截止，请尽快完成。`,
                notificationType: 'TASK',
                relatedType: 'Task',
                relatedId: task.id,
              });
              reminderCount++;
            } catch (error) {
              this.logger.error(
                `Failed to send task reminder to parent ${parentRelation.parent.id}:`,
                error
              );
            }
          }
        }
      }

      this.logger.log(`Sent ${reminderCount} task reminder notifications`);
    } catch (error) {
      this.logger.error('Error in task deadline reminder task:', error);
    }
  }

  /**
   * 手动发送任务提醒（教师点击"发送提醒"按钮时调用）
   */
  async sendManualTaskReminder(tenantId: number, taskId: number) {
    const task = await this.prisma.task.findFirst({
      where: { id: taskId, tenantId },
      include: {
        course: {
          select: { name: true, pictureBookName: true },
        },
        completions: {
          where: {
            status: { not: 'COMPLETED' },
          },
          include: {
            student: {
              select: {
                id: true,
                name: true,
                parents: {
                  include: {
                    parent: {
                      select: { id: true, name: true },
                    },
                  },
                },
              },
            },
          },
        },
      },
    });

    if (!task) {
      return { success: false, message: '任务不存在' };
    }

    const taskName = task.course?.pictureBookName || task.course?.name || task.title;
    let reminderCount = 0;
    const remindedStudents: { id: number; name: string }[] = [];

    for (const completion of task.completions) {
      for (const parentRelation of completion.student.parents) {
        try {
          await this.notificationService.createNotification({
            tenantId: task.tenantId,
            recipientType: 'PARENT',
            recipientId: parentRelation.parent.id,
            title: '阅读任务提醒',
            content: `老师提醒您：「${completion.student.name}」的任务《${taskName}》尚未完成，请督促孩子尽快完成阅读任务。`,
            notificationType: 'TASK',
            relatedType: 'Task',
            relatedId: task.id,
          });
          reminderCount++;
        } catch (error) {
          this.logger.error(
            `Failed to send manual task reminder to parent ${parentRelation.parent.id}:`,
            error
          );
        }
      }
      remindedStudents.push({
        id: completion.student.id,
        name: completion.student.name,
      });
    }

    this.logger.log(
      `Manual task reminder sent for task ${taskId} to ${reminderCount} parents`
    );

    return {
      success: true,
      message: `已发送${reminderCount}条提醒`,
      remindedCount: reminderCount,
      students: remindedStudents,
    };
  }
}
