<?php
declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit('CLI only');
}

$sessionPath = __DIR__ . '/../cache/cli_sessions';
if (!is_dir($sessionPath)) {
    @mkdir($sessionPath, 0777, true);
}
if (is_dir($sessionPath) && is_writable($sessionPath)) {
    session_save_path($sessionPath);
}

require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../config.php';

function reminderArg(string $name, array $argv, ?string $default = null): ?string
{
    foreach ($argv as $arg) {
        if (str_starts_with($arg, $name . '=')) {
            return substr($arg, strlen($name) + 1);
        }
    }
    return $default;
}

function reminderAlreadySent(mysqli $conn, int $teacherId, int $slotId, string $scheduleDate, string $reminderType): bool
{
    $stmt = $conn->prepare(
        "SELECT id
         FROM timetable_email_reminders
         WHERE teacher_id = ? AND slot_id = ? AND schedule_date = ? AND reminder_type = ? AND status = 'sent'
         LIMIT 1"
    );
    $stmt->bind_param('iiss', $teacherId, $slotId, $scheduleDate, $reminderType);
    $stmt->execute();
    $result = $stmt->get_result();
    $exists = $result->num_rows > 0;
    $stmt->close();
    return $exists;
}

function reminderLog(mysqli $conn, int $teacherId, int $slotId, string $scheduleDate, string $reminderType, string $email, string $status, ?string $error): void
{
    $sentAt = $status === 'sent' ? date('Y-m-d H:i:s') : null;
    $stmt = $conn->prepare(
        "INSERT INTO timetable_email_reminders
         (teacher_id, slot_id, schedule_date, reminder_type, recipient_email, status, error_message, sent_at)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
    );
    $stmt->bind_param('iissssss', $teacherId, $slotId, $scheduleDate, $reminderType, $email, $status, $error, $sentAt);
    $stmt->execute();
    $stmt->close();
}

function reminderEmailBody(string $teacherName, array $row, string $schoolName, int $minutesBefore, string $scheduleDate): string
{
    $startTime = substr((string) $row['start_time'], 0, 5);
    $room = trim((string) ($row['room'] ?? ''));
    $roomLine = $room !== '' ? '<p><strong>Room:</strong> ' . htmlspecialchars($room) . '</p>' : '';

    return '
        <div style="font-family: Arial, sans-serif; color: #1f2937; line-height: 1.6;">
            <h2 style="margin-bottom: 8px;">Timetable Reminder</h2>
            <p>Dear ' . htmlspecialchars($teacherName) . ',</p>
            <p>This is a reminder that your next class starts in <strong>' . $minutesBefore . ' minutes</strong>.</p>
            <p><strong>Date:</strong> ' . htmlspecialchars($scheduleDate) . '<br>
               <strong>Time:</strong> ' . htmlspecialchars($startTime) . '<br>
               <strong>Subject:</strong> ' . htmlspecialchars((string) ($row['subject_name'] ?? 'Scheduled Lesson')) . '<br>
               <strong>Class:</strong> ' . htmlspecialchars((string) $row['class_name']) . '<br>
               <strong>Period:</strong> ' . htmlspecialchars((string) $row['period_name']) . '</p>
            ' . $roomLine . '
            <p>Please be prepared to start on time.</p>
            <p>Regards,<br>' . htmlspecialchars($schoolName) . '</p>
        </div>
    ';
}

$dryRun = in_array('--dry-run', $argv, true);
$conn = getDBConnection();
if (!$conn instanceof mysqli) {
    fwrite(STDERR, "Database connection failed\n");
    exit(1);
}

$schoolName = getSettingValue('school_name') ?: SITE_NAME;
$academicYear = reminderArg('--academic-year', $argv, getAcademicYear());
$currentTerm = reminderArg('--term', $argv, getSettingValue('current_term') ?: 'First Term');
$today = reminderArg('--date', $argv, date('Y-m-d'));
$dayOfWeek = date('D', strtotime($today));

if ($dayOfWeek === 'Sun') {
    echo "No timetable reminders on Sunday.\n";
    exit(0);
}

$nowArg = reminderArg('--now', $argv);
$now = $nowArg !== null ? new DateTimeImmutable($nowArg) : new DateTimeImmutable('now');
$windowStart = $now->sub(new DateInterval('PT59S'));
$intervals = [
    '30_min' => 30,
    '10_min' => 10,
];

$stmt = $conn->prepare(
    "SELECT ts.id AS slot_id, ts.class_name, ts.room, ts.teacher_id AS original_teacher_id,
            p.period_name, p.start_time,
            s.subject_name,
            sub.substitute_teacher_id,
            orig.full_name AS original_teacher_name,
            orig.email AS original_teacher_email,
            subteach.full_name AS substitute_teacher_name,
            subteach.email AS substitute_teacher_email
     FROM timetable_slots ts
     INNER JOIN timetable_periods p ON ts.period_id = p.id
     LEFT JOIN subjects s ON ts.subject_id = s.id
     LEFT JOIN timetable_substitutions sub
       ON sub.slot_id = ts.id AND sub.substitution_date = ?
     LEFT JOIN staff orig ON ts.teacher_id = orig.id
     LEFT JOIN staff subteach ON sub.substitute_teacher_id = subteach.id
     WHERE ts.day_of_week = ?
       AND ts.academic_year = ?
       AND ts.term = ?
       AND p.is_break = 0
     ORDER BY p.start_time ASC"
);
$stmt->bind_param('ssss', $today, $dayOfWeek, $academicYear, $currentTerm);
$stmt->execute();
$result = $stmt->get_result();

$processed = 0;
$sent = 0;
$skipped = 0;
$failed = 0;

while ($row = $result->fetch_assoc()) {
    $processed++;
    $effectiveTeacherId = (int) ($row['substitute_teacher_id'] ?: $row['original_teacher_id']);
    $effectiveTeacherName = (string) ($row['substitute_teacher_name'] ?: $row['original_teacher_name'] ?: 'Teacher');
    $effectiveTeacherEmail = trim((string) ($row['substitute_teacher_email'] ?: $row['original_teacher_email'] ?: ''));

    if ($effectiveTeacherId <= 0 || $effectiveTeacherEmail === '') {
        $skipped++;
        continue;
    }

    $classStart = new DateTimeImmutable($today . ' ' . substr((string) $row['start_time'], 0, 8));

    foreach ($intervals as $reminderType => $minutesBefore) {
        $reminderTime = $classStart->sub(new DateInterval('PT' . $minutesBefore . 'M'));
        if ($reminderTime <= $windowStart || $reminderTime > $now) {
            continue;
        }

        if (reminderAlreadySent($conn, $effectiveTeacherId, (int) $row['slot_id'], $today, $reminderType)) {
            $skipped++;
            continue;
        }

        $subject = sprintf(
            'Timetable Reminder: %s in %d minutes',
            (string) ($row['subject_name'] ?: 'Scheduled Lesson'),
            $minutesBefore
        );
        $body = reminderEmailBody($effectiveTeacherName, $row, (string) $schoolName, $minutesBefore, $today);

        if ($dryRun) {
            echo sprintf(
                "[DRY RUN] %s -> %s | %s | %s %s\n",
                $effectiveTeacherName,
                $effectiveTeacherEmail,
                $subject,
                $today,
                substr((string) $row['start_time'], 0, 5)
            );
            $sent++;
            continue;
        }

        $ok = sendEmail($effectiveTeacherEmail, $subject, $body);
        if ($ok) {
            reminderLog($conn, $effectiveTeacherId, (int) $row['slot_id'], $today, $reminderType, $effectiveTeacherEmail, 'sent', null);
            $sent++;
        } else {
            reminderLog($conn, $effectiveTeacherId, (int) $row['slot_id'], $today, $reminderType, $effectiveTeacherEmail, 'failed', 'SMTP sendEmail() returned false');
            $failed++;
        }
    }
}

$stmt->close();

echo sprintf(
    "Processed: %d | Sent: %d | Skipped: %d | Failed: %d | Term: %s | Academic Year: %s\n",
    $processed,
    $sent,
    $skipped,
    $failed,
    $currentTerm,
    $academicYear
);
