<?php
declare(strict_types=1);
session_start();

header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: strict-origin-when-cross-origin');
header("Content-Security-Policy: default-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; img-src 'self' data:; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net;");

const ROOT_DIR = __DIR__;
const INCLUDES_DIR = __DIR__ . '/includes';
const STORAGE_DIR = __DIR__ . '/storage';
const INSTALL_DIR = __DIR__ . '/storage/install';
const INSTALL_STATE_FILE = INSTALL_DIR . '/state.php';
const DB_RUNTIME_FILE = INCLUDES_DIR . '/db_runtime.php';
const MAIL_RUNTIME_FILE = INCLUDES_DIR . '/mail_runtime.php';
const INSTALL_LOG_FILE = INSTALL_DIR . '/install.log';
const TELEMETRY_LOG_FILE = INSTALL_DIR . '/telemetry.log';
const SQL_DUMP_FILE = ROOT_DIR . '/rozklad.sql';
const LICENSE_HASH = '$2y$12$60fROgI8T7Iyj0j65sh6vuUBqfkOirOt1/prOTJS4oxP3hJlM6WY2'; // Аварійний локальний код ROZKLAD26
const LICENSE_API_URL = 'https://sitepro.net.ua/license-center/api/license-hook.php';
const LICENSE_PRODUCT_SLUG = 'elektronniy-rozklad';
const LICENSE_REQUIRE_REMOTE = true;

$step = max(1, min(6, (int)($_GET['step'] ?? 1)));
$errors = [];
$oks = [];
$state = load_state();

if (!isset($_SESSION['install_csrf'])) {
    $_SESSION['install_csrf'] = bin2hex(random_bytes(32));
}

function h(string $v): string { return htmlspecialchars($v, ENT_QUOTES, 'UTF-8'); }
function current_scheme(): string {
    $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443);
    return $https ? 'https' : 'http';
}
function current_host(): string { return preg_replace('~[^a-z0-9\.-]~i', '', (string)($_SERVER['HTTP_HOST'] ?? 'localhost')) ?: 'localhost'; }
function current_base_url(): string { return current_scheme() . '://' . current_host(); }
function current_path(): string { return rtrim(str_replace('\\', '/', dirname((string)($_SERVER['SCRIPT_NAME'] ?? '/'))), '/'); }
function client_ip(): string { return (string)($_SERVER['REMOTE_ADDR'] ?? 'unknown'); }
function ensure_dirs(): void {
    foreach ([INCLUDES_DIR, STORAGE_DIR, INSTALL_DIR, STORAGE_DIR . '/logs', STORAGE_DIR . '/cache'] as $dir) {
        if (!is_dir($dir)) @mkdir($dir, 0775, true);
    }
}
function write_php_array_file(string $path, array $data): bool {
    $content = "<?php\nreturn " . var_export($data, true) . ";\n";
    $tmp = $path . '.tmp';
    if (@file_put_contents($tmp, $content, LOCK_EX) === false) return false;
    return @rename($tmp, $path);
}
function append_log(string $path, string $message): void {
    ensure_dirs();
    @file_put_contents($path, '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL, FILE_APPEND | LOCK_EX);
}
function load_state(): array {
    if (is_file(INSTALL_STATE_FILE)) {
        $data = require INSTALL_STATE_FILE;
        return is_array($data) ? $data : [];
    }
    return [];
}
function save_state(array $state): bool { return write_php_array_file(INSTALL_STATE_FILE, $state); }
function verify_csrf(): void {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') return;
    $token = (string)($_POST['csrf_token'] ?? '');
    if (!hash_equals((string)($_SESSION['install_csrf'] ?? ''), $token)) {
        http_response_code(400);
        die('CSRF token mismatch');
    }
}
function installer_can_continue(): bool {
    $state = load_state();
    if (empty($state['installed'])) return true;
    return empty($state['mail_configured']);
}
function rate_limit_license(): bool {
    $key = 'license_attempts';
    $slot = 'license_attempts_started';
    $now = time();
    if (empty($_SESSION[$slot]) || ($now - (int)$_SESSION[$slot]) > 900) {
        $_SESSION[$slot] = $now;
        $_SESSION[$key] = 0;
    }
    $_SESSION[$key] = (int)($_SESSION[$key] ?? 0) + 1;
    return $_SESSION[$key] <= 8;
}
function detect_mail_configured(array $cfg): bool {
    return !empty($cfg['host']) && !empty($cfg['from_email']);
}
function server_fingerprint(): string {
    $parts = [
        current_host(),
        current_base_url(),
        PHP_OS_FAMILY,
        php_uname('n'),
        $_SERVER['SERVER_ADDR'] ?? '',
        __DIR__,
    ];
    return hash('sha256', implode('|', $parts));
}
function telemetry_payload(string $event, array $extra = []): array {
    return array_merge([
        'event' => $event,
        'install_id' => load_state()['install_id'] ?? '',
        'product_slug' => LICENSE_PRODUCT_SLUG,
        'domain' => current_host(),
        'base_url' => current_base_url(),
        'path' => current_path(),
        'ip' => client_ip(),
        'time' => gmdate('c'),
        'php' => PHP_VERSION,
        'fingerprint' => server_fingerprint(),
    ], $extra);
}
function post_json(string $url, array $payload): array {
    $json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $headers = [
        'Content-Type: application/json',
        'Content-Length: ' . strlen((string)$json),
    ];
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $json,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 8,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
        ]);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        $http = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        curl_close($ch);
        if ($response === false) {
            return ['ok' => false, 'error' => 'cURL error #' . $errno . ': ' . $error, 'http_code' => $http];
        }
        $data = json_decode((string)$response, true);
        if (!is_array($data)) {
            return ['ok' => false, 'error' => 'Некоректна JSON-відповідь від сервера ліцензій.', 'http_code' => $http, 'raw' => (string)$response];
        }
        $data['http_code'] = $http;
        return $data;
    }
    $ctx = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => implode("\r\n", $headers) . "\r\n",
            'content' => $json,
            'timeout' => 8,
            'ignore_errors' => true,
        ],
    ]);
    $response = @file_get_contents($url, false, $ctx);
    if ($response === false) {
        return ['ok' => false, 'error' => 'Не вдалося виконати HTTP-запит до сервера ліцензій.'];
    }
    $data = json_decode((string)$response, true);
    if (!is_array($data)) {
        return ['ok' => false, 'error' => 'Некоректна JSON-відповідь від сервера ліцензій.', 'raw' => (string)$response];
    }
    return $data;
}
function remote_license_request(string $action, array $extra = []): array {
    $state = load_state();
    $payload = array_merge(telemetry_payload($action, [
        'action' => $action,
        'license_key' => $extra['license_key'] ?? ($state['license_key'] ?? ''),
        'install_id' => $state['install_id'] ?? ($extra['install_id'] ?? ''),
    ]), $extra);
    return post_json(LICENSE_API_URL, $payload);
}
function send_telemetry(string $event, array $extra = []): void {
    $payload = telemetry_payload($event, $extra);
    append_log(TELEMETRY_LOG_FILE, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    if (LICENSE_API_URL === '') return;
    @remote_license_request('telemetry', ['telemetry_event' => $event] + $extra);
}
function verify_remote_license_or_local(string $licenseCode, array &$state, array &$errors): bool {
    if (empty($state['install_id'])) {
        $state['install_id'] = bin2hex(random_bytes(16));
    }
    if (LICENSE_API_URL !== '') {
        $response = remote_license_request('verify_install', [
            'license_key' => $licenseCode,
            'install_id' => $state['install_id'],
            'product_slug' => LICENSE_PRODUCT_SLUG,
        ]);
        if (!empty($response['ok']) && !empty($response['license_valid'])) {
            $state['license_verified'] = true;
            $state['license_verified_at'] = date('c');
            $state['license_key'] = $licenseCode;
            $state['license_remote_required'] = true;
            $state['license_remote_status'] = (string)($response['license_status'] ?? 'active');
            $state['license_last_remote_check_at'] = date('c');
            $state['license_installation_uid'] = (string)($response['installation_uid'] ?? '');
            $state['license_owner_email'] = (string)($response['license_email'] ?? '');
            $state['license_product_name'] = (string)($response['product_name'] ?? 'Електронний розклад');
            $state['license_remote_message'] = (string)($response['message'] ?? 'Ліцензію підтверджено віддалено.');
            return true;
        }
        $errors[] = (string)($response['message'] ?? $response['error'] ?? 'Сервер ліцензій відхилив активацію.');
        append_log(INSTALL_LOG_FILE, 'Віддалена перевірка ліцензії не пройдена для IP ' . client_ip() . '; response=' . json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
        return false;
    }
    if (LICENSE_REQUIRE_REMOTE) {
        $errors[] = 'Віддалена перевірка ліцензії увімкнена, але LICENSE_API_URL не налаштовано.';
        return false;
    }
    if (password_verify($licenseCode, LICENSE_HASH)) {
        $state['license_verified'] = true;
        $state['license_verified_at'] = date('c');
        $state['license_key'] = $licenseCode;
        $state['license_remote_required'] = false;
        $state['license_remote_status'] = 'local-fallback';
        return true;
    }
    $errors[] = 'Невірний код доступу.';
    append_log(INSTALL_LOG_FILE, 'Невдала локальна спроба введення коду з IP ' . client_ip());
    return false;
}
function try_connect_host_variants(string $host, string $user, string $pass, ?string $db, int $port = 3306): array {
    $candidates = array_unique([$host ?: 'localhost', $host === 'localhost' ? '127.0.0.1' : 'localhost']);
    $debug = [];
    mysqli_report(MYSQLI_REPORT_OFF);
    foreach ($candidates as $h) {
        $conn = @new mysqli($h, $user, $pass, $db ?? '', $port);
        if ($conn && !$conn->connect_errno) {
            @$conn->set_charset('utf8mb4');
            return [$conn, $h, implode("\n", array_merge($debug, ["✔ Підключено: {$h}:{$port}"]))];
        }
        $err = $conn ? '[' . $conn->connect_errno . '] ' . $conn->connect_error : 'невідома помилка';
        $debug[] = "✖ {$h}:{$port} — {$err}";
    }
    return [null, $host, implode("\n", $debug)];
}
function import_sql(mysqli $conn, string $sql): void {
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn->set_charset('utf8mb4');
    $conn->query('SET NAMES utf8mb4');
    $conn->query('SET FOREIGN_KEY_CHECKS=0');
    $conn->multi_query($sql);
    do { if ($res = $conn->store_result()) $res->free(); } while ($conn->more_results() && $conn->next_result());
    $conn->query('SET FOREIGN_KEY_CHECKS=1');
}
function send_admin_activation_email(array $mailCfg, array $admin): array {
    require_once __DIR__ . '/includes/PHPMailer/src/PHPMailer.php';
    require_once __DIR__ . '/includes/PHPMailer/src/Exception.php';
    require_once __DIR__ . '/includes/PHPMailer/src/SMTP.php';
    $mail = new PHPMailer\PHPMailer\PHPMailer(true);
    $link = current_base_url() . '/verify.php?token=' . urlencode((string)$admin['verification_token']);
    try {
        $mail->isSMTP();
        $mail->Host = (string)$mailCfg['host'];
        $mail->SMTPAuth = true;
        $mail->Username = (string)($mailCfg['username'] ?? '');
        $mail->Password = (string)($mailCfg['password'] ?? '');
        $enc = strtolower((string)($mailCfg['encryption'] ?? 'tls'));
        if ($enc === 'ssl') {
            $mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
            $mail->Port = (int)($mailCfg['port'] ?? 465);
        } else {
            $mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port = (int)($mailCfg['port'] ?? 587);
        }
        $mail->CharSet = 'UTF-8';
        $mail->setFrom((string)$mailCfg['from_email'], (string)($mailCfg['from_name'] ?? 'Розклад занять'));
        $mail->addAddress((string)$admin['email'], (string)$admin['full_name']);
        $mail->isHTML(true);
        $mail->Subject = 'Активація адміністратора';
        $mail->Body = '<p>Вітаємо!</p><p>Щоб активувати обліковий запис адміністратора, відкрийте посилання:</p><p><a href="' . h($link) . '">' . h($link) . '</a></p>';
        $mail->AltBody = 'Щоб активувати обліковий запис адміністратора, відкрийте: ' . $link;
        $mail->send();
        return [true, 'Лист активації адміністратора відправлено.'];
    } catch (Throwable $e) {
        return [false, 'Не вдалося надіслати лист активації: ' . $mail->ErrorInfo];
    }
}

if (!installer_can_continue() && $step !== 6) {
    $step = 6;
}

if ($step >= 3 && empty($_SESSION['installer_license_ok'])) $step = 2;
if ($step >= 4 && empty($_SESSION['installer_db_ok'])) $step = 3;
if ($step >= 5 && empty($_SESSION['installer_mail_step_done'])) $step = 4;
if ($step >= 6 && empty($_SESSION['installer_admin_ok'])) $step = 5;

if ($step === 1) {
    ensure_dirs();
    $req = [
        ['PHP >= 8.0', version_compare(PHP_VERSION, '8.0.0', '>=')],
        ['mysqli', extension_loaded('mysqli')],
        ['mbstring', extension_loaded('mbstring')],
        ['json', extension_loaded('json')],
        ['openssl', extension_loaded('openssl')],
        ['curl або allow_url_fopen', function_exists('curl_init') || filter_var((string)ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)],
    ];
    foreach ($req as [$name, $ok]) if (!$ok) $errors[] = 'Відсутня вимога: ' . $name;
    if (!is_writable(INCLUDES_DIR)) $errors[] = 'Немає прав на запис у /includes.';
    if (!is_writable(STORAGE_DIR)) $errors[] = 'Немає прав на запис у /storage.';
}

if ($step === 2 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    if (!rate_limit_license()) {
        $errors[] = 'Забагато спроб. Спробуйте трохи пізніше.';
    } else {
        $license_code = trim((string)($_POST['license_code'] ?? ''));
        if ($license_code === '') {
            $errors[] = 'Введіть код доступу.';
        } elseif (verify_remote_license_or_local($license_code, $state, $errors)) {
            $_SESSION['installer_license_ok'] = true;
            save_state($state);
            send_telemetry('license_verified', ['license_remote_status' => $state['license_remote_status'] ?? 'unknown']);
            header('Location: install.php?step=3'); exit;
        }
    }
}

if ($step === 3 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    $db_host = trim((string)($_POST['db_host'] ?? 'localhost'));
    $db_port = (int)($_POST['db_port'] ?? 3306);
    $db_name = trim((string)($_POST['db_name'] ?? ''));
    $db_user = trim((string)($_POST['db_user'] ?? ''));
    $db_pass = (string)($_POST['db_pass'] ?? '');

    if ($db_name === '' || $db_user === '') {
        $errors[] = 'Назва БД та користувач БД — обов’язкові.';
    } else {
        list($server, $usedHost, $dbg1) = try_connect_host_variants($db_host, $db_user, $db_pass, null, $db_port);
        if (!$server) {
            $errors[] = "Не вдалося підключитися до MySQL.\n" . $dbg1;
        } else {
            try {
                $server->query("CREATE DATABASE IF NOT EXISTS `{$db_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
                $server->close();
                list($conn, $usedDbHost, $dbg2) = try_connect_host_variants($db_host, $db_user, $db_pass, $db_name, $db_port);
                if (!$conn) {
                    $errors[] = "Не вдалося підключитися до БД {$db_name}.\n" . $dbg2;
                } else {
                    if (!is_file(SQL_DUMP_FILE)) {
                        $errors[] = 'Не знайдено файл rozklad.sql.';
                    } else {
                        $sql = (string)file_get_contents(SQL_DUMP_FILE);
                        import_sql($conn, $sql);
                        write_php_array_file(DB_RUNTIME_FILE, [
                            'host' => $usedDbHost,
                            'port' => $db_port,
                            'name' => $db_name,
                            'user' => $db_user,
                            'pass' => $db_pass,
                        ]);
                        $_SESSION['installer_db_ok'] = true;
                        $state['db_configured'] = true;
                        $state['db_name'] = $db_name;
                        $state['installed_domain'] = current_host();
                        save_state($state);
                        $conn->close();
                        send_telemetry('database_imported', ['db_name' => $db_name]);
                        header('Location: install.php?step=4'); exit;
                    }
                }
            } catch (Throwable $e) {
                $errors[] = 'Помилка налаштування БД: ' . $e->getMessage();
            }
        }
    }
}

if ($step === 4 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    $skip = !empty($_POST['skip_mail']);
    if ($skip) {
        @unlink(MAIL_RUNTIME_FILE);
        $_SESSION['installer_mail_step_done'] = true;
        $_SESSION['installer_mail_ok'] = false;
        $state['mail_configured'] = false;
        save_state($state);
        header('Location: install.php?step=5'); exit;
    }

    $cfg = [
        'host' => trim((string)($_POST['smtp_host'] ?? '')),
        'port' => (int)($_POST['smtp_port'] ?? 587),
        'encryption' => trim((string)($_POST['smtp_secure'] ?? 'tls')),
        'username' => trim((string)($_POST['smtp_user'] ?? '')),
        'password' => (string)($_POST['smtp_pass'] ?? ''),
        'from_email' => trim((string)($_POST['from_email'] ?? '')),
        'from_name' => trim((string)($_POST['from_name'] ?? 'Розклад занять')),
    ];
    if ($cfg['host'] === '' || $cfg['port'] <= 0 || $cfg['from_email'] === '') {
        $errors[] = 'Заповніть SMTP-хост, порт та email відправника.';
    } else {
        write_php_array_file(MAIL_RUNTIME_FILE, $cfg);
        $_SESSION['installer_mail_step_done'] = true;
        $_SESSION['installer_mail_ok'] = true;
        $state['mail_configured'] = true;
        save_state($state);
        send_telemetry('mail_configured');
        header('Location: install.php?step=5'); exit;
    }
}

if ($step === 5 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    $admin_username = trim((string)($_POST['admin_username'] ?? 'admin'));
    $admin_password = (string)($_POST['admin_password'] ?? '');
    $admin_email = trim((string)($_POST['admin_email'] ?? ''));
    $admin_full_name = trim((string)($_POST['admin_full_name'] ?? ''));

    if ($admin_username === '' || $admin_password === '' || $admin_email === '' || $admin_full_name === '') {
        $errors[] = 'Усі поля адміністратора — обов’язкові.';
    } else {
        $db = require DB_RUNTIME_FILE;
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        try {
            $conn = new mysqli((string)$db['host'], (string)$db['user'], (string)$db['pass'], (string)$db['name'], (int)$db['port']);
            $conn->set_charset('utf8mb4');
            $stmt = $conn->prepare('SELECT id FROM users WHERE username=? OR email=? LIMIT 1');
            $stmt->bind_param('ss', $admin_username, $admin_email);
            $stmt->execute();
            $res = $stmt->get_result();
            if ($res && $res->num_rows > 0) {
                $errors[] = 'Логін або email вже зайняті.';
            } else {
                $hash = password_hash($admin_password, PASSWORD_DEFAULT);
                $verification_token = bin2hex(random_bytes(32));
                $is_verified = 0;
                $is_active = 0;
                $role = 'admin';
                $stmt2 = $conn->prepare('INSERT INTO users (username,password,full_name,email,role,is_verified,verification_token,is_active,created_at) VALUES (?,?,?,?,?,?,?, ?, NOW())');
                $stmt2->bind_param('sssssisi', $admin_username, $hash, $admin_full_name, $admin_email, $role, $is_verified, $verification_token, $is_active);
                $stmt2->execute();
                $admin = ['username' => $admin_username, 'email' => $admin_email, 'full_name' => $admin_full_name, 'verification_token' => $verification_token];
                $state['admin_created'] = true;
                $state['admin_email'] = $admin_email;
                $state['admin_username'] = $admin_username;
                $state['installed'] = true;
                $state['installed_at'] = date('c');
                save_state($state);
                if (!empty($state['mail_configured']) && is_file(MAIL_RUNTIME_FILE)) {
                    $mailCfg = require MAIL_RUNTIME_FILE;
                    [$ok, $msg] = send_admin_activation_email($mailCfg, $admin);
                    if ($ok) $oks[] = $msg; else $errors[] = $msg;
                }
                $_SESSION['installer_admin_ok'] = true;
                send_telemetry('admin_created', ['admin_email' => $admin_email]);
                header('Location: install.php?step=6'); exit;
            }
        } catch (Throwable $e) {
            $errors[] = 'Помилка створення адміністратора: ' . $e->getMessage();
        }
    }
}

$state = load_state();
?>
<!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:#0f172a;--card:#111827;--muted:#94a3b8;--primary:#22c55e;--primary2:#16a34a;--danger:#ef4444;--warn:#f59e0b;--border:#1f2937;--text:#e5e7eb}
*{box-sizing:border-box}body{margin:0;background:linear-gradient(180deg,#0f172a,#111827);font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial;color:var(--text)}
.wrap{max-width:980px;margin:34px auto;padding:18px}.card{background:rgba(17,24,39,.96);border:1px solid var(--border);border-radius:18px;padding:26px;box-shadow:0 10px 40px rgba(0,0,0,.35)}
h1{margin:0 0 6px;font-size:30px}h2{color:var(--muted);margin:0 0 24px;font-weight:500;font-size:17px}.steps{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}.step{padding:8px 12px;border-radius:999px;border:1px solid #334155;color:#cbd5e1}.step.active{background:#0b1220;color:#fff;border-color:#64748b}.msg{padding:12px 14px;border-radius:12px;margin:10px 0;white-space:pre-wrap}.ok{background:rgba(34,197,94,.08);border:1px solid rgba(34,197,94,.25)}.err{background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.25)}.warn{background:rgba(245,158,11,.08);border:1px solid rgba(245,158,11,.25);padding:12px 14px;border-radius:12px;margin:12px 0}form{display:grid;gap:12px}.row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.form-group{display:flex;flex-direction:column}label{font-size:14px;color:#cbd5e1;margin-bottom:6px}input,select{background:#0b1220;border:1px solid #1f2937;border-radius:12px;padding:11px 12px;color:#e5e7eb;outline:none}input:focus,select:focus{border-color:#475569}button{background:linear-gradient(180deg,var(--primary),var(--primary2));border:none;color:#041108;padding:12px 16px;border-radius:12px;font-weight:700;cursor:pointer}.secondary{background:#1e293b;color:#e2e8f0}.warningBtn{background:linear-gradient(180deg,#f59e0b,#d97706);color:#180f03}.actions{display:flex;gap:12px;justify-content:flex-end;flex-wrap:wrap;margin-top:8px}.muted{color:#93a2b1;font-size:14px}.note{background:#0b1220;border:1px dashed #334155;border-radius:12px;padding:14px;margin:8px 0}.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:16px 0}.feature{background:#0b1220;border:1px solid #1f2937;border-radius:14px;padding:14px}.feature b{display:block;margin-bottom:8px}.code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:#020617;padding:2px 6px;border-radius:8px}.small{font-size:13px;color:#9fb0c3}@media (max-width:700px){.row,.grid3{grid-template-columns:1fr}}</style>
</head>
<body>
<div class="wrap"><div class="card">
<h1>Майстер встановлення</h1>
<h2>Готовий двіжок для розкладу занять, консультацій і профілів викладачів</h2>
<div class="steps">
<div class="step <?= $step===1?'active':''; ?>">1. Перевірка</div>
<div class="step <?= $step===2?'active':''; ?>">2. Ліцензія</div>
<div class="step <?= $step===3?'active':''; ?>">3. База даних</div>
<div class="step <?= $step===4?'active':''; ?>">4. Пошта</div>
<div class="step <?= $step===5?'active':''; ?>">5. Адмін</div>
<div class="step <?= $step===6?'active':''; ?>">6. Готово</div>
</div>
<?php foreach ($oks as $m): ?><div class="msg ok">✅ <?= h($m) ?></div><?php endforeach; ?>
<?php foreach ($errors as $m): ?><div class="msg err">❌ <?= h($m) ?></div><?php endforeach; ?>

<?php if ($step === 1): ?>
  <div class="grid3">
    <div class="feature"><b>1. Розклад занять</b>Публікація груп, уроків, кабінетів, замін, архіву і PDF-версій.</div>
    <div class="feature"><b>2. Консультації</b>Окремий розділ консультацій, викладачів та оновлень для користувачів.</div>
    <div class="feature"><b>3. Користувачі й адмінка</b>Реєстрація, підтвердження email, профілі викладачів і керування через адмінпанель.</div>
  </div>
  <p class="muted">Перед початком переконайтеся, що папки <span class="code">/includes</span> і <span class="code">/storage</span> доступні для запису. Файл <span class="code">rozklad.sql</span> уже входить до пакета.</p>
  <div class="actions"><button onclick="location.href='install.php?step=2'">Далі →</button></div>

<?php elseif ($step === 2): ?>
  <div class="note">
    <p><strong>Як отримати ліцензійний код.</strong></p>
    <p>Напишіть у <a href="https://t.me/siteprocms" target="_blank" rel="noopener noreferrer">https://t.me/siteprocms</a> і вкажіть, яку саме CMS хочете придбати. Після цього з вами зв'яжеться адміністратор.</p>
  </div>
  <form method="post" action="install.php?step=2">
    <input type="hidden" name="csrf_token" value="<?= h($_SESSION['install_csrf']) ?>">
    <div class="form-group"><label>Ліцензійний ключ *</label><input name="license_code" required placeholder="Наприклад: EROZ-XXXX-XXXX-XXXX"></div>
    <div class="actions"><button type="button" class="secondary" onclick="location.href='install.php?step=1'">← Назад</button><button type="submit">Перевірити ліцензію →</button></div>
  </form>

<?php elseif ($step === 3): ?>
  <form method="post" action="install.php?step=3">
    <input type="hidden" name="csrf_token" value="<?= h($_SESSION['install_csrf']) ?>">
    <div class="row">
      <div class="form-group"><label>Хост</label><input name="db_host" value="<?= h($_POST['db_host'] ?? 'localhost') ?>" required></div>
      <div class="form-group"><label>Порт</label><input name="db_port" value="<?= h($_POST['db_port'] ?? '3306') ?>" required></div>
    </div>
    <div class="row">
      <div class="form-group"><label>База даних</label><input name="db_name" value="<?= h($_POST['db_name'] ?? 'rozklad') ?>" required></div>
      <div class="form-group"><label>Користувач БД</label><input name="db_user" value="<?= h($_POST['db_user'] ?? '') ?>" required></div>
    </div>
    <div class="form-group"><label>Пароль БД</label><input type="password" name="db_pass" value="<?= h($_POST['db_pass'] ?? '') ?>"></div>
    <div class="actions"><button type="button" class="secondary" onclick="location.href='install.php?step=2'">← Назад</button><button type="submit">Імпортувати базу →</button></div>
  </form>

<?php elseif ($step === 4): ?>
  <div class="warn">Пошту можна пропустити, але тоді обліковий запис адміністратора не буде активований, реєстрація користувачів і відновлення пароля не працюватимуть, доки ви не завершите цей крок.</div>
  <form method="post" action="install.php?step=4">
    <input type="hidden" name="csrf_token" value="<?= h($_SESSION['install_csrf']) ?>">
    <div class="row">
      <div class="form-group"><label>SMTP-хост</label><input name="smtp_host" value="<?= h($_POST['smtp_host'] ?? 'smtp.gmail.com') ?>"></div>
      <div class="form-group"><label>Порт</label><input name="smtp_port" value="<?= h($_POST['smtp_port'] ?? '587') ?>"></div>
    </div>
    <div class="row">
      <div class="form-group"><label>Шифрування</label><select name="smtp_secure"><option value="tls">TLS</option><option value="ssl">SSL</option></select></div>
      <div class="form-group"><label>SMTP-користувач</label><input name="smtp_user" value="<?= h($_POST['smtp_user'] ?? '') ?>"></div>
    </div>
    <div class="form-group"><label>SMTP-пароль</label><input type="password" name="smtp_pass" value="<?= h($_POST['smtp_pass'] ?? '') ?>"></div>
    <div class="row">
      <div class="form-group"><label>Email відправника</label><input name="from_email" value="<?= h($_POST['from_email'] ?? '') ?>"></div>
      <div class="form-group"><label>Ім’я відправника</label><input name="from_name" value="<?= h($_POST['from_name'] ?? 'Розклад занять') ?>"></div>
    </div>
    <div class="actions">
      <button type="button" class="secondary" onclick="location.href='install.php?step=3'">← Назад</button>
      <button type="submit">Зберегти пошту →</button>
    </div>
  </form>
  <form method="post" action="install.php?step=4" style="margin-top:10px">
    <input type="hidden" name="csrf_token" value="<?= h($_SESSION['install_csrf']) ?>">
    <input type="hidden" name="skip_mail" value="1">
    <div class="actions"><button type="submit" class="warningBtn">Пропустити налаштування пошти</button></div>
  </form>

<?php elseif ($step === 5): ?>
  <?php if (empty($state['mail_configured'])): ?><div class="warn">Пошта пропущена. Адміністратор буде створений як неактивний. Увійти в адмінпанель до завершення поштового кроку не вийде.</div><?php endif; ?>
  <form method="post" action="install.php?step=5">
    <input type="hidden" name="csrf_token" value="<?= h($_SESSION['install_csrf']) ?>">
    <div class="row">
      <div class="form-group"><label>Логін адміністратора</label><input name="admin_username" value="<?= h($_POST['admin_username'] ?? 'admin') ?>" required></div>
      <div class="form-group"><label>Email адміністратора</label><input type="email" name="admin_email" value="<?= h($_POST['admin_email'] ?? '') ?>" required></div>
    </div>
    <div class="row">
      <div class="form-group"><label>ПІБ адміністратора</label><input name="admin_full_name" value="<?= h($_POST['admin_full_name'] ?? '') ?>" required></div>
      <div class="form-group"><label>Пароль адміністратора</label><input type="password" name="admin_password" required></div>
    </div>
    <div class="actions"><button type="button" class="secondary" onclick="location.href='install.php?step=4'">← Назад</button><button type="submit">Створити адміністратора →</button></div>
  </form>

<?php else: ?>
  <div class="msg ok">Інсталяція завершена.</div>
  <div class="feature"><b>Домен інсталяції:</b> <?= h($state['installed_domain'] ?? current_host()) ?></div>
  <div class="feature"><b>ID інсталяції:</b> <span class="code"><?= h($state['install_id'] ?? '') ?></span></div>
  <div class="feature"><b>Стан ліцензії:</b> <?= h($state['license_remote_status'] ?? 'unknown') ?></div>
  <?php if (!empty($state['mail_configured'])): ?>
    <div class="msg ok">Пошта налаштована. Лист активації адміністратора мав бути відправлений на email адміністратора. Після підтвердження можна входити на сайт.</div>
  <?php else: ?>
    <div class="warn">Пошта не налаштована. Сайт встановлено в обмеженому режимі: вхід, реєстрація і відновлення пароля не працюватимуть, доки ви не завершите крок налаштування пошти.</div>
    <div class="actions"><button onclick="location.href='install.php?step=4'">Налаштувати пошту зараз</button></div>
  <?php endif; ?>
  <div class="actions"><button onclick="location.href='/'">Перейти на сайт</button></div>
<?php endif; ?>

</div></div>
</body>
</html>
