<?php
/**
 * update.php — оновлення бази даних Електронного журналу
 *
 * ЩО РОБИТЬ:
 *  - додає роль 'parent' у колонку users.role (ENUM)
 *  - додає колонку users.child_id (якщо її ще немає)
 *  - створює таблицю parent_links (якщо її ще немає)
 *
 * КОРИСТУВАННЯ:
 *  1) Увійдіть на сайт як адміністратор.
 *  2) Відкрийте в браузері: https://ВАШ_САЙТ/update.php
 *  3) Перевірте результат. Після успішного оновлення — видаліть цей файл з сервера.
 */

declare(strict_types=1);
session_start();

// ===== Перевірка, що користувач — адмін (мінімальний захист) =====
if (!isset($_SESSION['user_id']) || (($_SESSION['role'] ?? '') !== 'admin')) {
    http_response_code(403);
    echo 'Доступ заборонено. Увійдіть як адміністратор.';
    exit;
}

// ===== Підключення до БД через стандартний файл журналу =====
require_once __DIR__ . '/includes/db_connect.php';

if (!isset($conn) || !($conn instanceof mysqli)) {
    http_response_code(500);
    echo 'Помилка: не знайдено або не ініціалізовано змінну $conn (mysqli). Перевірте includes/db_connect.php.';
    exit;
}

$conn->set_charset('utf8mb4');

// Масив для логів кроків
$steps = [];

/**
 * Додати запис про крок
 */
function add_step(array &$steps, string $title, bool $ok, string $message): void {
    $steps[] = [
        'title'   => $title,
        'ok'      => $ok,
        'message' => $message,
    ];
}

/**
 * Безпечне HTML-екранування
 */
function h(string $s): string {
    return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// ===== Отримати ім'я поточної бази =====
$dbName = null;
$resDb = $conn->query('SELECT DATABASE() AS db');
if ($resDb && $rowDb = $resDb->fetch_assoc()) {
    $dbName = $rowDb['db'];
}
if (!$dbName) {
    add_step($steps, 'Визначення поточної бази даних', false, 'Не вдалося визначити ім’я бази даних через SELECT DATABASE().');
} else {
    add_step($steps, 'Визначення поточної бази даних', true, 'Використовується база: ' . $dbName);
}

// ===== Перевірити, що таблиця users існує =====
$usersTableExists = false;
if ($dbName) {
    $stmt = $conn->prepare('SELECT COUNT(*) AS cnt FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "users"');
    if ($stmt) {
        $stmt->bind_param('s', $dbName);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($res && $row = $res->fetch_assoc()) {
            $usersTableExists = ((int)$row['cnt'] > 0);
        }
        $stmt->close();
    }
}

if (!$usersTableExists) {
    add_step($steps, 'Перевірка таблиці users', false, 'Таблиця users не знайдена. Оновлення перервано.');
} else {
    add_step($steps, 'Перевірка таблиці users', true, 'Таблиця users існує.');
}

/* ------------------------------------------------------------------
 * 1) ОНОВЛЕННЯ ENUM ДЛЯ users.role (додати "parent")
 * ------------------------------------------------------------------ */
if ($usersTableExists) {
    $hasParentInEnum = false;
    $resRole = $conn->query("SHOW COLUMNS FROM `users` LIKE 'role'");
    if ($resRole && $col = $resRole->fetch_assoc()) {
        $type = strtolower((string)$col['Type']); // наприклад: enum('student','teacher','admin')
        if (strpos($type, "'parent'") !== false) {
            $hasParentInEnum = true;
        }
    }

    if ($hasParentInEnum) {
        add_step($steps, 'Оновлення поля users.role', true, "Поле role вже містить 'parent', ALTER не потрібен.");
    } else {
        $sql = "ALTER TABLE `users`
                MODIFY `role` ENUM('student','teacher','admin','parent') NOT NULL DEFAULT 'student'";
        if ($conn->query($sql)) {
            add_step(
                $steps,
                'Оновлення поля users.role',
                true,
                "Поле role оновлено до ENUM('student','teacher','admin','parent') NOT NULL DEFAULT 'student'."
            );
        } else {
            add_step(
                $steps,
                'Оновлення поля users.role',
                false,
                'Помилка ALTER TABLE: ' . $conn->error
            );
        }
    }
}

/* ------------------------------------------------------------------
 * 2) ДОДАТИ КОЛОНКУ users.child_id, якщо її ще немає
 * ------------------------------------------------------------------ */
if ($usersTableExists && $dbName) {
    $hasChildId = false;

    $stmt = $conn->prepare('SELECT COUNT(*) AS cnt
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "users" AND COLUMN_NAME = "child_id"');
    if ($stmt) {
        $stmt->bind_param('s', $dbName);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($res && $row = $res->fetch_assoc()) {
            $hasChildId = ((int)$row['cnt'] > 0);
        }
        $stmt->close();
    }

    if ($hasChildId) {
        add_step($steps, 'Додавання колонки users.child_id', true, 'Колонка child_id вже існує, додавання не потрібне.');
    } else {
        // Без AFTER, щоб не впасти, якщо group_id відсутнє
        $sql = "ALTER TABLE `users`
                ADD COLUMN `child_id` INT(11) DEFAULT NULL";
        if ($conn->query($sql)) {
            add_step($steps, 'Додавання колонки users.child_id', true, 'Колонку child_id успішно додано до таблиці users.');
        } else {
            add_step(
                $steps,
                'Додавання колонки users.child_id',
                false,
                'Помилка ALTER TABLE (ADD COLUMN child_id): ' . $conn->error
            );
        }
    }
}

/* ------------------------------------------------------------------
 * 3) СТВОРИТИ ТАБЛИЦЮ parent_links, якщо її ще немає
 * ------------------------------------------------------------------ */
$parentLinksExists = false;
if ($dbName) {
    $stmt = $conn->prepare('SELECT COUNT(*) AS cnt FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "parent_links"');
    if ($stmt) {
        $stmt->bind_param('s', $dbName);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($res && $row = $res->fetch_assoc()) {
            $parentLinksExists = ((int)$row['cnt'] > 0);
        }
        $stmt->close();
    }
}

if ($parentLinksExists) {
    add_step($steps, 'Створення таблиці parent_links', true, 'Таблиця parent_links вже існує, створення не потрібне.');
} else {
    $sql = "CREATE TABLE IF NOT EXISTS `parent_links` (
                `parent_id` INT(11) NOT NULL,
                `student_id` INT(11) NOT NULL,
                `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                KEY `idx_parent` (`parent_id`),
                KEY `idx_student` (`student_id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    if ($conn->query($sql)) {
        add_step($steps, 'Створення таблиці parent_links', true, 'Таблиця parent_links успішно створена (або вже існувала).');
    } else {
        add_step(
            $steps,
            'Створення таблиці parent_links',
            false,
            'Помилка CREATE TABLE parent_links: ' . $conn->error
        );
    }
}

// ===== (ОПЦІЙНО) Можна записати версію оновлення у таблицю settings, якщо вона є =====
$settingsTableExists = false;
if ($dbName) {
    $stmt = $conn->prepare('SELECT COUNT(*) AS cnt FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "settings"');
    if ($stmt) {
        $stmt->bind_param('s', $dbName);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($res && $row = $res->fetch_assoc()) {
            $settingsTableExists = ((int)$row['cnt'] > 0);
        }
        $stmt->close();
    }
}

if ($settingsTableExists) {
    $version = '2025-11-13';
    $sql = "INSERT INTO `settings` (`setting_name`, `setting_value`)
            VALUES ('ejournal_version', ?)
            ON DUPLICATE KEY UPDATE `setting_value` = VALUES(`setting_value`)";
    $stmt = $conn->prepare($sql);
    if ($stmt) {
        $stmt->bind_param('s', $version);
        if ($stmt->execute()) {
            add_step(
                $steps,
                'Запис версії у settings',
                true,
                'Версію оновлення збережено як ejournal_version = ' . $version
            );
        } else {
            add_step(
                $steps,
                'Запис версії у settings',
                false,
                'Помилка INSERT/UPDATE settings: ' . $stmt->error
            );
        }
        $stmt->close();
    } else {
        add_step(
            $steps,
            'Запис версії у settings',
            false,
            'Не вдалося підготувати запит INSERT INTO settings: ' . $conn->error
        );
    }
} else {
    add_step(
        $steps,
        'Запис версії у settings',
        false,
        'Таблиця settings не знайдена. Цей крок пропущено (це не критична помилка).'
    );
}

// ===== Вивід результату у вигляді простої HTML-сторінки =====
?>
<!doctype html>
<html lang="uk">
<head>
    <meta charset="utf-8">
    <title>Оновлення бази даних — Електронний журнал</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <style>
        :root {
            --bg:#0b1a2b;
            --card:#10243a;
            --accent:#1e90ff;
            --text:#e8f1ff;
            --muted:#a9c1da;
            --ok:#2ecc71;
            --err:#ff4d4f;
        }
        *{box-sizing:border-box;margin:0;padding:0}
        body{
            font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
            background:radial-gradient(circle at top,#163457,#050b14);
            color:var(--text);
            min-height:100vh;
            display:flex;
            align-items:flex-start;
            justify-content:center;
            padding:24px;
        }
        .wrap{
            width:100%;
            max-width:900px;
            background:rgba(9,17,33,0.92);
            border-radius:16px;
            box-shadow:0 18px 45px rgba(0,0,0,0.6);
            padding:24px 20px;
            border:1px solid rgba(255,255,255,0.06);
        }
        h1{
            font-size:22px;
            margin-bottom:8px;
        }
        .sub{
            font-size:14px;
            color:var(--muted);
            margin-bottom:16px;
        }
        .badge{
            display:inline-flex;
            align-items:center;
            gap:6px;
            padding:3px 10px;
            border-radius:999px;
            font-size:11px;
            background:rgba(30,144,255,0.12);
            color:var(--accent);
            margin-bottom:16px;
        }
        .badge span{
            width:8px;
            height:8px;
            border-radius:50%;
            background:var(--accent);
        }
        table{
            width:100%;
            border-collapse:collapse;
            margin-top:10px;
            font-size:14px;
        }
        th,td{
            padding:8px 10px;
            border-bottom:1px solid rgba(255,255,255,0.05);
            vertical-align:top;
        }
        th{
            text-align:left;
            font-weight:600;
            color:var(--muted);
            font-size:12px;
            text-transform:uppercase;
            letter-spacing:0.04em;
        }
        tr:last-child td{border-bottom:none}
        .status{
            font-size:12px;
            font-weight:600;
            padding:2px 8px;
            border-radius:999px;
            display:inline-block;
        }
        .status.ok{
            background:rgba(46,204,113,0.14);
            color:var(--ok);
        }
        .status.err{
            background:rgba(255,77,79,0.14);
            color:var(--err);
        }
        .footer{
            margin-top:16px;
            font-size:12px;
            color:var(--muted);
        }
        .footer strong{color:var(--accent);}
        .warn{
            margin-top:10px;
            font-size:13px;
            color:#ffdd99;
        }
        @media (max-width:600px){
            .wrap{padding:18px 14px;}
            h1{font-size:18px;}
            table{font-size:13px;}
        }
    </style>
</head>
<body>
<div class="wrap">
    <div class="badge"><span></span>Скрипт оновлення бази даних</div>
    <h1>Електронний журнал — оновлення БД</h1>
    <p class="sub">
        Нижче показано результат виконання міграцій. Після успішного оновлення <strong>обов’язково видаліть файл <code>update.php</code></strong> з сервера.
    </p>

    <table>
        <thead>
        <tr>
            <th style="width:25%;">Крок</th>
            <th style="width:10%;">Статус</th>
            <th>Деталі</th>
        </tr>
        </thead>
        <tbody>
        <?php foreach ($steps as $step): ?>
            <tr>
                <td><?=h($step['title'])?></td>
                <td>
                    <?php if ($step['ok']): ?>
                        <span class="status ok">OK</span>
                    <?php else: ?>
                        <span class="status err">Помилка</span>
                    <?php endif; ?>
                </td>
                <td><?=nl2br(h($step['message']))?></td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>

    <p class="warn">
        Після того, як переконаєтеся, що журнал працює коректно (роль батьків, прив’язка дитини, тощо),
        видаліть цей файл, щоб ніхто сторонній не міг повторно запускати оновлення.
    </p>

    <p class="footer">
        Якщо якийсь крок позначено як <strong>Помилка</strong>, сфотографуйте/скопіюйте повідомлення і надішліть його розробнику.
    </p>
</div>
</body>
</html>
