<?php
session_start();
require_once '../includes/db_connect.php';

/* ===== Хелпер ===== */
function h(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }

/* ===== Доступ: лише адмін ===== */
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] ?? '') !== 'admin') {
    header("Location: ../index.php");
    exit();
}

/* ===== Дозволяємо лише POST ===== */
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header("Location: ../admin/dashboard.php");
    exit();
}

/* ===== CSRF ===== */
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
$CSRF = $_SESSION['csrf_token'];
$csrf_post = $_POST['csrf_token'] ?? '';
if (!hash_equals($CSRF, $csrf_post)) {
    http_response_code(403);
    die('Помилка безпеки (CSRF). Оновіть сторінку і спробуйте ще раз.');
}

/* ===== Вхідні дані ===== */
$student_id   = (int)($_POST['student_id'] ?? 0);
$subject_id   = (int)($_POST['subject_id'] ?? 0);
$grade        = (int)($_POST['grade'] ?? 0);
$lesson_date  = trim($_POST['lesson_date'] ?? '');
$lesson_topic = trim($_POST['lesson_topic'] ?? '');

if ($student_id <= 0 || $subject_id <= 0 || $lesson_date === '') {
    http_response_code(400);
    die('Невірні дані.');
}

/* Нормалізуємо дату й оцінку */
$dt = DateTime::createFromFormat('Y-m-d', $lesson_date);
if (!$dt) { http_response_code(400); die('Невірний формат дати.'); }
$lesson_date = $dt->format('Y-m-d');

if ($grade < 0)  $grade = 0;
if ($grade > 12) $grade = 12;

/* Тема уроку: обмеження довжини */
if (mb_strlen($lesson_topic) > 255) {
    $lesson_topic = mb_substr($lesson_topic, 0, 255);
}

/* ===== Пошта: конфіг + PHPMailer (мовчазно; без розкриття секретів) ===== */
$MAIL_READY = false;
$MAIL_CFG   = [];

// Кандидати шляхів
$cfg_candidates = [
    __DIR__ . '/../includes/config_mail.php',
    $_SERVER['DOCUMENT_ROOT'] . '/includes/config_mail.php',
];
$phpmailer_base = [
    __DIR__ . '/../includes/PHPMailer/src',
    $_SERVER['DOCUMENT_ROOT'] . '/includes/PHPMailer/src',
];

foreach ($cfg_candidates as $c) {
    if (is_file($c)) {
        $MAIL_CFG = require $c; // очікуємо масив
        break;
    }
}
foreach ($phpmailer_base as $b) {
    if (is_dir($b)) {
        @require_once $b . '/PHPMailer.php';
        @require_once $b . '/SMTP.php';
        @require_once $b . '/Exception.php';
        break;
    }
}
if (class_exists('\PHPMailer\PHPMailer\PHPMailer')) {
    $MAIL_READY = true;
}

/** Створює та налаштовує PHPMailer. Повертає PHPMailer або null. */
function build_mailer(array $cfg) {
    if (!class_exists('\PHPMailer\PHPMailer\PHPMailer')) return null;
    $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
    try {
        $mail->isSMTP();
        $mail->Host       = $cfg['host']       ?? 'localhost';
        $mail->SMTPAuth   = (bool)($cfg['smtpauth'] ?? true);
        $mail->Username   = $cfg['username']   ?? '';
        $mail->Password   = $cfg['password']   ?? '';
        $mail->Port       = (int)($cfg['port'] ?? 587);
        $enc              = $cfg['encryption'] ?? ''; // 'tls' | 'ssl' | ''
        if ($enc) $mail->SMTPSecure = $enc;

        $fromEmail = $cfg['from_email'] ?? ($cfg['username'] ?? 'no-reply@example.com');
        $fromName  = $cfg['from_name']  ?? 'Електронний журнал';
        $mail->setFrom($fromEmail, $fromName);
        $mail->CharSet = 'UTF-8';
        $mail->isHTML(true);
        return $mail;
    } catch (Throwable $e) {
        // Без розкриття причин чи конфіга
        error_log('add_grade: mailer init failed');
        return null;
    }
}

/** Надсилає лист про оцінку (без логування адреси/імені/оцінки). */
function send_grade_email(array $cfg, string $toEmail, string $toName, string $subjectName, ?int $grade, string $lessonDate, string $topic): void {
    $mailer = build_mailer($cfg);
    if (!$mailer) return;

    try {
        $title = 'Нова оцінка: ' . $subjectName;

        $gradeText = (is_null($grade) || $grade === 0) ? '<strong>видалено</strong>' : '<strong>' . (int)$grade . '</strong>';
        $dateText  = $lessonDate ? date('d.m.Y', strtotime($lessonDate)) : '—';
        $topicText = $topic !== '' ? h($topic) : '—';

        $body  = "<p>Вам виставлено/змінено оцінку з предмету <strong>" . h($subjectName) . "</strong>.</p>";
        $body .= "<ul style=\"margin:0; padding-left:18px;\">";
        $body .= "<li><b>Урок:</b> {$topicText}</li>";
        $body .= "<li><b>Дата:</b> " . h($dateText) . "</li>";
        $body .= "<li><b>Оцінка:</b> {$gradeText}</li>";
        $body .= "</ul>";
        $body .= "<p>Це автоматичне повідомлення Електронного журналу.</p>";

        $mailer->clearAllRecipients();
        $mailer->addAddress($toEmail, $toName ?: $toEmail);
        $mailer->Subject = $title;
        $mailer->Body    = $body;
        $mailer->AltBody = "Предмет: {$subjectName}\nУрок: " . ($topic !== '' ? $topic : '—') .
                           "\nДата: {$dateText}\nОцінка: " . ((is_null($grade) || $grade === 0) ? 'видалено' : (string)$grade);

        $mailer->send();
        // Успіх без персональних даних у логах
        error_log('add_grade: email sent');
    } catch (Throwable $e) {
        // Не логувати email/ПІБ/оцінку/тему
        error_log('add_grade: email send failed');
    }
}

try {
    $conn->begin_transaction();

    /* Перевіряємо існування предмета */
    $q = $conn->prepare("SELECT id, subject_name FROM subjects WHERE id = ?");
    $q->bind_param("i", $subject_id);
    $q->execute();
    $res = $q->get_result();
    if ($res->num_rows === 0) {
        throw new Exception('Предмет не знайдено.');
    }
    $subject_row  = $res->fetch_assoc();
    $subject_name = (string)$subject_row['subject_name'];
    $q->close();

    /* Знаходимо або створюємо урок у таблиці lessons */
    $q = $conn->prepare("SELECT id, topic FROM lessons WHERE subject_id = ? AND lesson_date = ?");
    $q->bind_param("is", $subject_id, $lesson_date);
    $q->execute();
    $res = $q->get_result();

    if ($row = $res->fetch_assoc()) {
        $lesson_id = (int)$row['id'];
        $old_topic = (string)($row['topic'] ?? '');
        $q->close();

        if ($lesson_topic !== '' && $lesson_topic !== $old_topic) {
            $q = $conn->prepare("UPDATE lessons SET topic = ? WHERE id = ?");
            $q->bind_param("si", $lesson_topic, $lesson_id);
            $q->execute();
            $q->close();
        } else {
            $lesson_topic = $lesson_topic !== '' ? $lesson_topic : $old_topic;
        }
    } else {
        $q->close();
        $q = $conn->prepare("INSERT INTO lessons (subject_id, lesson_date, topic) VALUES (?, ?, ?)");
        $q->bind_param("iss", $subject_id, $lesson_date, $lesson_topic);
        $q->execute();
        $lesson_id = $conn->insert_id;
        $q->close();
    }

    /* Додаємо/оновлюємо оцінку для конкретного уроку */
    $q = $conn->prepare("SELECT id, grade FROM grades WHERE student_id = ? AND subject_id = ? AND lesson_id = ?");
    $q->bind_param("iii", $student_id, $subject_id, $lesson_id);
    $q->execute();
    $res = $q->get_result();

    $was_changed = false;
    if ($row = $res->fetch_assoc()) {
        $grade_id   = (int)$row['id'];
        $prev_grade = (int)($row['grade'] ?? 0);
        $q->close();

        if ($prev_grade !== $grade) {
            $q = $conn->prepare("UPDATE grades SET grade = ? WHERE id = ?");
            $q->bind_param("ii", $grade, $grade_id);
            $q->execute();
            $q->close();
            $was_changed = true;
        }
    } else {
        $q->close();
        $q = $conn->prepare("INSERT INTO grades (student_id, subject_id, grade, lesson_id) VALUES (?, ?, ?, ?)");
        $q->bind_param("iiii", $student_id, $subject_id, $grade, $lesson_id);
        $q->execute();
        $q->close();
        $was_changed = true;
    }

    $conn->commit();

    /* ===== Після коміту: надсилання e-mail (за потреби) ===== */
    if ($was_changed && $MAIL_READY) {
        try {
            $q = $conn->prepare("SELECT email, full_name FROM users WHERE id = ?");
            $q->bind_param("i", $student_id);
            $q->execute();
            $res = $q->get_result();
            if ($info = $res->fetch_assoc()) {
                $toEmail = trim((string)$info['email']);
                $toName  = (string)($info['full_name'] ?? '');
                $q->close();

                if ($toEmail !== '') {
                    $grade_for_mail = ($grade === 0) ? null : $grade; // 0 => «видалено»
                    send_grade_email($MAIL_CFG, $toEmail, $toName, $subject_name, $grade_for_mail, $lesson_date, $lesson_topic);
                } else {
                    // Без email — просто пропускаємо
                    error_log('add_grade: student has no email');
                }
            } else {
                $q->close();
                error_log('add_grade: student not found after commit');
            }
        } catch (Throwable $e) {
            error_log('add_grade: post-commit mail block failed');
        }
    } else {
        if (!$was_changed) error_log('add_grade: no change -> skip email');
        if (!$MAIL_READY)  error_log('add_grade: mailer not ready -> skip email');
    }

    header("Location: ../admin/dashboard.php?success=1");
    exit();
} catch (Throwable $e) {
    $conn->rollback();
    http_response_code(500);
    // Не розкриваємо текст виключення користувачу
    echo "Сталася помилка при додаванні оцінки. Спробуйте пізніше або зверніться до адміністратора.";
}
