<!DOCTYPE html>
<html lang="uk">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Панель Адміністратора WebQuiz</title>
    <style>
        :root {
            --bg-color: #f5f5f5;
            --container-bg: white;
            --text-color: #333;
            --border-color: #ddd;
            --button-bg: #007bff;
            --button-hover: #0056b3;
            --success-bg: #d4edda;
            --success-border: #c3e6cb;
            --success-color: #155724;
            --error-bg: #f8d7da;
            --error-border: #f5c6cb;
            --error-color: #721c24;
            --warning-bg: #fff3cd;
            --warning-border: #ffeaa7;
            --warning-color: #856404;
            --disabled-bg: #ccc;
            --light-bg: #fafafa;
            --success-green: #28a745;
            --success-green-hover: #218838;
            --danger-red: #dc3545;
            --danger-red-hover: #c82333;
            --muted-gray: #6c757d;
            --light-gray: #aaa;
            --text-muted: #666;
            --white: white;
            --shadow: rgba(0,0,0,0.1);
            --modal-overlay: rgba(0,0,0,0.5);
        }

        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: var(--bg-color);
            color: var(--text-color);
        }

        .container {
            background: var(--container-bg);
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 10px var(--shadow);
            margin-bottom: 20px;
        }

        h1 {
            text-align: center;
            color: var(--text-color);
            margin-bottom: 30px;
        }

        .form-group {
            margin-bottom: 10px;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }

        input[type="password"], select {
            width: 100%;
            padding: 10px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            font-size: 16px;
            box-sizing: border-box;
        }

        button {
            background: var(--button-bg);
            color: var(--white);
            border: none;
            padding: 12px 24px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            margin: 5px;
        }

        button:hover {
            background: var(--button-hover);
        }

        button:disabled {
            background: var(--disabled-bg);
            cursor: not-allowed;
        }

        .hidden {
            display: none;
        }

        .message {
            padding: 10px;
            border-radius: 5px;
            margin: 10px 0;
        }

        .success {
            background: var(--success-bg);
            border: 1px solid var(--success-border);
            color: var(--success-color);
        }

        .error {
            background: var(--error-bg);
            border: 1px solid var(--error-border);
            color: var(--error-color);
        }

        .warning {
            background: var(--warning-bg);
            border: 1px solid var(--warning-border);
            color: var(--warning-color);
        }



        /* Multi-select quiz dropdown */
        .quiz-select {
            width: 100%;
            padding: 10px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            font-size: 14px;
            box-sizing: border-box;
            background: var(--light-bg);
            font-family: monospace;
        }

        .quiz-select option {
            padding: 8px;
        }

        .quiz-select option.current-quiz {
            font-weight: bold;
            background: var(--warning-bg);
        }

        .selection-hint {
            font-size: 0.85em;
            color: var(--text-muted);
            margin-top: 5px;
            font-style: italic;
        }

        .btn-success {
            background: var(--success-green);
            color: var(--white);
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
        }

        .btn-success:hover {
            background: var(--success-green-hover);
        }

        .hidden {
            display: none !important;
        }

        /* Mobile responsive for quiz select */
        @media (max-width: 768px) {
            .quiz-select {
                font-size: 16px; /* Prevent zoom on iOS */
            }

            .selection-hint {
                display: none; /* Hide Ctrl+click hint on mobile */
            }
        }

        .actions {
            text-align: center;
            margin-top: 20px;
        }

        .actions-sticky {
            position: sticky;
            bottom: 0;
            background: white;
            padding: 15px 0;
            margin-top: 20px;
            margin-left: -15px;
            margin-right: -15px;
            margin-bottom: -15px;
            border-top: 1px solid var(--border-color);
            box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
            z-index: 10;
            text-align: center;
        }

        .back-link {
            text-align: center;
            margin-top: 20px;
        }

        .back-link a {
            color: var(--button-bg);
            text-decoration: none;
        }

        .back-link a:hover {
            text-decoration: underline;
        }

        /* Modal styles */
        .modal {
            display: none;
            position: fixed;
            z-index: 1000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: var(--modal-overlay);
        }

        .modal-content {
            background-color: var(--container-bg);
            margin: 5% auto;
            padding: 15px;
            border-radius: 10px;
            width: 90%;
            max-width: 800px;
            max-height: 80vh;
            overflow-y: auto;
        }

        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            border-bottom: 1px solid var(--border-color);
            padding-bottom: 10px;
        }

        .close {
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
            color: var(--light-gray);
        }

        .close:hover {
            color: var(--text-color);
        }

        .editor-content {
            margin-top: 12px;
        }

        .question-item {
            border: 1px solid var(--border-color);
            border-radius: 5px;
            padding: 10px;
            margin: 8px 0;
            background: var(--light-bg);
        }

        .question-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 6px;
            padding: 10px;
            background: var(--question-bg, #e9ecef);
            border-radius: 5px;
            cursor: pointer;
            user-select: none;
        }

        .question-header:hover {
            background: var(--question-bg-hover, #dee2e6);
        }

        .question-header-left {
            display: flex;
            align-items: flex-start;
            gap: 10px;
            flex: 1;
            min-width: 0;
        }

        .question-collapse-icon {
            font-size: 12px;
            transition: transform 0.2s ease;
            color: var(--text-muted);
            margin-top: 3px;
        }

        .question-item.collapsed .question-collapse-icon {
            transform: rotate(-90deg);
        }

        .question-number {
            font-weight: bold;
            white-space: nowrap;
        }

        .question-preview {
            color: var(--text-muted);
            font-size: 0.9em;
            flex: 1;
        }

        .question-indicators {
            display: flex;
            gap: 5px;
            margin-left: 8px;
            flex-shrink: 0;
        }

        .question-indicator {
            font-size: 14px;
            opacity: 0.8;
        }

        .question-indicator.points-indicator {
            color: darkgoldenrod;
            font-weight: bold;
        }

        .question-header-buttons {
            display: flex;
            gap: 5px;
            flex-shrink: 0;
            align-self: flex-start;
        }

        .question-header-buttons button {
            padding: 5px 8px;
            font-size: 12px;
            margin: 0;
        }

        .drag-handle {
            cursor: grab;
            color: var(--text-muted);
            font-size: 16px;
            padding: 2px 4px;
            user-select: none;
        }

        .drag-handle:active {
            cursor: grabbing;
        }

        .question-item.dragging {
            opacity: 0.5;
            background: var(--question-bg-hover, #dee2e6);
        }

        .question-item.drag-over {
            border-top: 3px solid var(--button-bg);
        }

        .question-body {
            overflow: hidden;
            transition: max-height 0.3s ease, opacity 0.2s ease, padding 0.2s ease;
            max-height: 2000px;
            opacity: 1;
            padding-top: 10px;
        }

        .question-item.collapsed .question-body {
            max-height: 0;
            opacity: 0;
            padding-top: 0;
        }

        .question-item.collapsed {
            padding-bottom: 0;
        }

        .option-item {
            display: flex;
            align-items: center;
            margin: 5px 0;
        }

        .option-item input[type="text"] {
            flex: 1;
            margin: 0 10px;
        }

        .option-item input[type="radio"] {
            margin-right: 5px;
        }

        .validation-errors {
            color: var(--error-color);
            background: var(--error-bg);
            border: 1px solid var(--error-border);
            border-radius: 5px;
            padding: 10px;
            margin: 10px 0;
        }

        .quiz-actions {
            display: flex;
            gap: 10px;
            margin: 10px 0;
        }

        .quiz-actions button {
            flex: 1;
        }

        .btn-danger {
            background: var(--danger-red);
        }

        .btn-danger:hover {
            background: var(--danger-red-hover);
        }

        .downloadable-quiz-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            margin-bottom: 10px;
            background: var(--white);
        }

        .downloadable-quiz-info {
            flex: 1;
        }

        .downloadable-quiz-name {
            font-weight: bold;
            margin-bottom: 5px;
        }

        .downloadable-quiz-url {
            font-size: 0.9em;
            color: var(--text-muted);
            word-break: break-all;
        }

        .download-btn {
            background: var(--success-green);
            color: var(--white);
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.9em;
        }

        .download-btn:hover {
            background: var(--success-green-hover);
        }

        .download-btn:disabled {
            background: var(--muted-gray);
            cursor: not-allowed;
        }

        .btn-danger:disabled {
            background: var(--danger-red);
            color: var(--white);
            opacity: 0.6;
        }

        /* Network info styles */
        .network-info {
            background: var(--warning-bg);
            border: 1px solid var(--warning-border);
            border-radius: 5px;
            padding: 20px;
            margin: 20px 0;
        }

        .network-info h3 {
            margin-top: 0;
            color: var(--warning-color);
        }

        .info-section {
            margin: 15px 0;
        }

        .url-list {
            margin-top: 10px;
        }

        .url-item {
            background: var(--white);
            border: 1px solid var(--border-color);
            border-radius: 3px;
            padding: 10px;
            margin: 5px 0;
            font-family: monospace;
        }

        .tunnel-info {
            background: var(--info-bg);
            border: 1px solid var(--info-border);
            border-radius: 5px;
            padding: 20px;
            margin: 20px 0;
        }

        .tunnel-info h3 {
            margin-top: 0;
            color: var(--info-color);
        }

        .tunnel-public-key {
            background: var(--white);
            border: 1px solid var(--border-color);
            border-radius: 3px;
            padding: 10px;
            margin: 10px 0;
            font-family: monospace;
            font-size: 12px;
            word-break: break-all;
            position: relative;
        }

        .copy-button {
            margin-left: 10px;
            padding: 5px 10px;
            font-size: 12px;
            cursor: pointer;
        }

        .tunnel-url {
            background: var(--success-bg);
            border: 1px solid var(--success-border);
            border-radius: 3px;
            padding: 10px;
            margin: 10px 0;
            font-family: monospace;
        }

        .tunnel-error {
            color: var(--error-color);
            margin: 10px 0;
        }

        .url-item .label {
            font-weight: bold;
            color: var(--button-bg);
            margin-bottom: 5px;
        }

        .url-item .url {
            color: var(--text-muted);
            font-size: 14px;
        }

        .url-item a {
            color: var(--button-bg);
            text-decoration: none;
            margin-right: 15px;
        }

        .url-item a:hover {
            text-decoration: underline;
        }

        /* Image picker styles */
        .image-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
            gap: 15px;
            padding: 20px;
            max-height: 400px;
            overflow-y: auto;
        }

        .image-item {
            border: 2px solid transparent;
            border-radius: 8px;
            padding: 10px;
            text-align: center;
            cursor: pointer;
            transition: all 0.2s ease;
            background: var(--container-bg);
        }

        .image-item:hover {
            border-color: var(--button-bg);
            transform: scale(1.05);
            box-shadow: 0 4px 12px var(--shadow);
        }

        .image-item img {
            width: 100%;
            height: 100px;
            object-fit: cover;
            border-radius: 4px;
            margin-bottom: 8px;
        }

        .image-filename {
            font-size: 12px;
            color: var(--text-color);
            word-break: break-word;
            line-height: 1.2;
        }

        #image-picker-modal .modal-content {
            max-width: 800px;
            width: 90%;
        }

        /* File picker styles */
        .file-list {
            padding: 15px;
            max-height: 400px;
            overflow-y: auto;
        }

        .file-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 12px 15px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            margin-bottom: 8px;
            cursor: pointer;
            transition: all 0.2s ease;
            background: var(--container-bg);
        }

        .file-item:hover {
            border-color: var(--button-bg);
            background: var(--stats-bg);
        }

        .file-item-info {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .file-item-icon {
            font-size: 20px;
        }

        .file-item-name {
            font-size: 14px;
            color: var(--text-color);
            word-break: break-word;
        }

        .file-item-size {
            font-size: 12px;
            color: var(--text-muted);
            white-space: nowrap;
        }

        /* Quiz Editor Form Styles */
        .question-text, .question-image, .option-text {
            width: 100%;
            padding: 8px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            font-size: 14px;
            box-sizing: border-box;
        }

        .options-container {
            margin: 10px 0;
        }

        /* Image preview styles in quiz editor */
        .image-preview-container {
            margin-top: 8px;
            display: none;
        }

        .image-preview-container.has-image {
            display: block;
        }

        .image-preview {
            max-width: 200px;
            max-height: 150px;
            border-radius: 8px;
            border: 2px solid var(--border-color);
            object-fit: contain;
            background: var(--light-bg);
            cursor: pointer;
            transition: transform 0.2s ease, box-shadow 0.2s ease;
        }

        .image-preview:hover {
            transform: scale(1.02);
            box-shadow: 0 4px 12px var(--shadow);
            border-color: var(--button-bg);
        }

        .option-image-preview {
            max-width: 80px;
            max-height: 60px;
            border-radius: 4px;
            border: 1px solid var(--border-color);
            object-fit: contain;
            background: var(--light-bg);
            margin-left: 5px;
            cursor: pointer;
            vertical-align: middle;
        }

        .option-image-preview:hover {
            border-color: var(--button-bg);
        }

        /* Full-size image preview modal */
        .image-fullscreen-modal {
            display: none;
            position: fixed;
            z-index: 2000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.9);
            cursor: pointer;
        }

        .image-fullscreen-modal img {
            max-width: 90%;
            max-height: 90%;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
        }

        .image-fullscreen-close {
            position: absolute;
            top: 20px;
            right: 30px;
            color: white;
            font-size: 40px;
            font-weight: bold;
            cursor: pointer;
        }

        .image-fullscreen-close:hover {
            color: var(--button-bg);
        }

        /* Pending Approvals Section */
        .pending-approvals {
            margin-top: 30px;
            background: var(--warning-bg);
            border: 2px solid var(--warning-border);
            border-radius: 8px;
            padding: 20px;
        }

        .pending-user-item {
            background: var(--white);
            border: 1px solid var(--border-color);
            border-radius: 5px;
            padding: 15px;
            margin: 10px 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .pending-user-info {
            flex: 1;
        }

        .pending-user-name {
            font-weight: bold;
            font-size: 16px;
            margin-bottom: 5px;
        }

        .pending-user-data {
            color: var(--text-muted);
            font-size: 14px;
            margin: 3px 0;
        }

        .approve-btn {
            background: var(--success-green);
            color: var(--white);
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            font-weight: bold;
        }

        .approve-btn:hover {
            background: var(--success-green-hover);
        }

        /* Downloadable Quizzes Section */
        .downloadable-quizzes {
            margin-top: 30px;
        }

        /* Question type toggle buttons */
        .question-type-toggle {
            background: var(--option-bg);
            border: 1px solid var(--border-color);
            color: var(--text-color);
            padding: 8px 16px;
            margin: 0 5px 10px 0;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s ease;
        }

        .question-type-toggle:hover {
            background: var(--option-hover);
        }

        .question-type-toggle.active {
            background: var(--button-bg);
            color: var(--white);
            border-color: var(--button-bg);
        }

        .min-correct-container {
            background: var(--light-bg);
            padding: 15px;
            border-radius: 5px;
            margin-top: 10px;
        }

        /* Footer styles */
        .admin-footer {
            text-align: center;
            padding: 20px;
            margin-top: 30px;
            border-top: 1px solid var(--border-color);
            color: var(--text-muted);
            font-size: 14px;
        }

        .footer-version {
            margin-bottom: 10px;
        }

        .footer-update {
            display: none;
            background: var(--warning-bg);
            border: 1px solid var(--warning-border);
            color: var(--warning-color);
            padding: 10px 15px;
            border-radius: 5px;
            margin-top: 10px;
            display: inline-block;
        }

        .footer-update a {
            color: var(--button-bg);
            text-decoration: none;
            font-weight: bold;
        }

        .footer-update a:hover {
            text-decoration: underline;
        }

        .footer-update.hidden {
            display: none;
        }

        .footer-restart {
            margin-top: 10px;
            color: var(--text-muted);
        }

        .footer-restart.hidden {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🔧 Панель Адміністратора WebQuiz</h1>

        <!-- Authentication Section -->
        <div id="auth-section">
            <div class="form-group">
                <label for="master-key">Ключ:</label>
                <input type="password" id="master-key" placeholder="Введіть ключ">
            </div>
            <div class="actions">
                <button onclick="authenticate()">Увійти</button>
            </div>
        </div>

        <!-- Admin Panel (hidden until authenticated) -->
        <div id="admin-panel" class="hidden">

            <div class="form-group">
                <label>Доступні Файли Quiz:</label>
                <select id="quiz-select" class="quiz-select" multiple size="8">
                    <!-- Options populated by JavaScript -->
                </select>
                <div class="selection-hint">
                    Ctrl+клік для вибору декількох, Shift+клік для діапазону
                </div>
            </div>

            <div class="actions" id="single-quiz-actions">
                <button id="switch-btn" onclick="switchQuiz()" disabled>Переключитися на Вибраний Quiz</button>
                <button onclick="refreshQuizzes()">🔄</button>
                <button id="edit-btn" onclick="editSelectedQuiz()" disabled>✏️</button>
                <button id="duplicate-btn" onclick="duplicateSelectedQuiz()" disabled>📋</button>
            </div>

            <div class="actions hidden" id="multi-quiz-actions">
                <button id="unite-btn" onclick="uniteSelectedQuizzes()" class="btn-success">🔗 Об'єднати quizzes</button>
                <button onclick="refreshQuizzes()">🔄</button>
            </div>

            <div class="quiz-actions">
                <button onclick="createNewQuiz()">📝 Створити Новий Quiz</button>
                <button id="delete-btn" onclick="deleteSelectedQuiz()" disabled class="btn-danger">🗑️ Видалити Quiz</button>
            </div>

            <!-- Pending Approvals Section (only shown when registration.approve is true) -->
            <div id="pending-approvals-section" class="pending-approvals hidden">
                <h3 style="margin-top: 0;">⏳ Очікуючі Підтвердження</h3>
                <div id="pending-users-list">
                    <p style="text-align: center; color: var(--text-muted);">Немає користувачів, що очікують підтвердження</p>
                </div>
            </div>

            <!-- Downloadable Quizzes Section -->
            <div id="downloadable-quizzes-section" class="downloadable-quizzes hidden">
                <div class="form-group">
                    <label>Доступні Quiz для Завантаження:</label>
                    <div id="downloadable-quiz-list" class="quiz-list">
                        <!-- Downloadable quizzes will be populated by JavaScript -->
                    </div>
                </div>
            </div>

            <!-- Network Access Information -->
            <div class="network-info" id="network-info">
                <div id="access-urls" class="info-section">
                    <strong>URL для доступу з інших пристроїв:</strong>
                    <div id="url-list" class="url-list">
                        Визначення мережевих інтерфейсів...
                    </div>
                </div>
            </div>

            <!-- SSH Tunnel Section -->
            <div class="tunnel-info" id="tunnel-section" style="display: none;">
                <h3>SSH Tunnel</h3>
                <div class="info-section">
                    <strong>Server:</strong> <span id="tunnel-server"></span>
                </div>
                <div id="tunnel-socket-name-section" class="info-section" style="display: none;">
                    <strong>Socket Name:</strong> <span id="tunnel-socket-name"></span>
                </div>
                <div id="tunnel-public-key-section" class="info-section" style="display: none;">
                    <strong>Public Key:</strong>
                    <div style="display: flex; align-items: center; gap: 10px; margin-top: 5px;">
                        <textarea id="tunnel-public-key" readonly style="flex: 1; font-family: monospace; font-size: 12px; padding: 8px; min-height: 30px; resize: vertical; background: #f5f5f5; border: 1px solid #ddd; border-radius: 4px;"></textarea>
                        <button id="copy-public-key-btn" onclick="copyPublicKey()" style="align-self: flex-start; padding: 8px 12px; white-space: nowrap;">📋 Copy</button>
                    </div>
                </div>
                <div class="info-section">
                    <button id="tunnel-connect-btn" onclick="toggleTunnel()" style="margin-top: 10px;">Connect</button>
                </div>
                <div id="tunnel-error" class="tunnel-error" style="display: none;"></div>
            </div>

            <div class="back-link">
                <a href="/">← Назад до Quiz</a>
                <span style="margin: 0 10px;">|</span>
                <a href="/files/">📁 File Manager</a>
                <span style="margin: 0 10px;">|</span>
                <a href="/live-stats/">📊 Live Stats</a>
            </div>

            <!-- Footer -->
            <div class="admin-footer">
                <div class="footer-version" id="footer-version">
                    WebQuiz v<span id="version-number">...</span>
                    <span id="footer-docs-link" style="margin-left: 15px;"></span>
                </div>
                <div id="footer-update" class="footer-update hidden"></div>
                <div id="footer-restart" class="footer-restart hidden">
                    New version installed (v<span id="new-version-number"></span>), restart required
                </div>
            </div>
        </div>

        <!-- Messages -->
        <div id="message-area"></div>
    </div>

    <!-- Quiz Editor Modal -->
    <div id="quiz-editor-modal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2 id="modal-title">Створити Новий Quiz</h2>
                <span class="close" onclick="closeQuizEditor()">&times;</span>
            </div>

            <div class="form-group">
                <label for="quiz-filename">Ім'я Файлу Quiz:</label>
                <input type="text" id="quiz-filename" placeholder="Введіть ім'я файлу (без розширення .yaml)" style="width: 100%;">
            </div>

            <div class="editor-content">
                <!-- Wizard Form -->
                <div id="wizard-form">
                    <div class="form-group">
                        <label>Назва Quiz (необов'язково):</label>
                        <input type="text" id="quiz-title" placeholder="наприклад, Математичний Quiz" style="width: 100%;">
                    </div>
                    <div class="form-group">
                        <label style="display: flex; align-items: center;">
                            <input type="checkbox" id="show-right-answer" checked style="margin-right: 10px;" onchange="toggleShowAnswersOnCompletion()">
                            Показувати правильні відповіді
                        </label>
                    </div>
                    <div class="form-group" id="show-answers-on-completion-group" style="display: none;">
                        <label style="display: flex; align-items: center;">
                            <input type="checkbox" id="show-answers-on-completion" style="margin-right: 10px;">
                            Показувати відповіді після завершення всіма
                        </label>
                    </div>
                    <div class="form-group">
                        <label style="display: flex; align-items: center;">
                            <input type="checkbox" id="randomize-questions" style="margin-right: 10px;">
                            Рандомізувати порядок питань
                        </label>
                    </div>
                    <div class="form-group">
                        <div id="questions-container">
                            <!-- Questions will be added dynamically -->
                        </div>
                        <button type="button" onclick="addQuestion()">➕ Додати Питання</button>
                    </div>
                </div>
            </div>

            <div class="actions-sticky">
                <button onclick="saveQuiz()">💾 Зберегти Quiz</button>
                <button id="save-continue-btn" onclick="saveQuizAndContinue()">💾 Зберегти і Продовжити</button>
                <button onclick="closeQuizEditor()">❌ Скасувати</button>
            </div>
        </div>
    </div>

    <!-- Image Picker Modal -->
    <div id="image-picker-modal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2>📷 Вибрати Зображення</h2>
                <span class="close" onclick="closeImagePicker()">&times;</span>
            </div>

            <div id="image-picker-content">
                <div id="image-grid" class="image-grid">
                    Завантаження зображень...
                </div>
            </div>
        </div>
    </div>

    <!-- Fullscreen Image Preview Modal -->
    <div id="image-fullscreen-modal" class="image-fullscreen-modal" onclick="closeFullscreenPreview()">
        <span class="image-fullscreen-close">&times;</span>
        <img id="fullscreen-image" src="" alt="Full size preview">
    </div>

    <!-- File Picker Modal -->
    <div id="file-picker-modal" class="modal">
        <div class="modal-content" style="max-width: 600px;">
            <div class="modal-header">
                <h2>📎 Вибрати Файл</h2>
                <span class="close" onclick="closeFilePicker()">&times;</span>
            </div>

            <div id="file-picker-content">
                <div id="file-list" class="file-list">
                    Завантаження файлів...
                </div>
            </div>
        </div>
    </div>

    <script>
        let currentMasterKey = '';
        let selectedQuizzes = [];  // Array of selected quiz filenames
        let currentQuiz = '';

        // HTML escape function to prevent quote truncation in form inputs
        function escapeHtml(text) {
            if (text === null || text === undefined) {
                return '';
            }
            const map = {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#39;'
            };
            return String(text).replace(/[&<>"']/g, m => map[m]);
        }

        // Toggle visibility of show_answers_on_completion based on show_right_answer state
        function toggleShowAnswersOnCompletion() {
            const showRightAnswer = document.getElementById('show-right-answer').checked;
            const showAnswersOnCompletionGroup = document.getElementById('show-answers-on-completion-group');

            // Only show the option when show_right_answer is FALSE
            if (showRightAnswer) {
                showAnswersOnCompletionGroup.style.display = 'none';
                // Also uncheck it when hiding
                document.getElementById('show-answers-on-completion').checked = false;
            } else {
                showAnswersOnCompletionGroup.style.display = 'block';
            }
        }

        async function authenticate() {
            const masterKey = document.getElementById('master-key').value.trim();
            if (!masterKey) {
                showMessage('Будь ласка, введіть ключ', 'error');
                return;
            }

            try {
                const response = await fetch('/api/admin/auth', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({master_key: masterKey}),
                    credentials: 'same-origin'  // Include cookies for session
                });

                const data = await response.json();

                if (response.ok) {
                    currentMasterKey = 'session';  // Session is now managed by cookie
                    document.getElementById('auth-section').style.display = 'none';
                    document.getElementById('admin-panel').classList.remove('hidden');
                    showMessage('Успішна автентифікація!', 'success');
                    await loadQuizzes();
                    displayNetworkInfo();
                    displayDownloadableQuizzes();
                    connectToAdminWebSocket(); // Connect to admin WebSocket for approvals
                    displayVersion(); // Display version in footer
                    checkForUpdates(); // Check for updates
                } else {
                    showMessage(data.error || 'Автентифікація невдала', 'error');
                }
            } catch (error) {
                showMessage('Помилка з\'єднання: ' + error.message, 'error');
            }
        }

        async function loadQuizzes() {
            try {
                const response = await fetch('/api/admin/list-quizzes', {
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    currentQuiz = data.current_quiz;
                    displayQuizzes(data.quizzes);
                } else {
                    showMessage(data.error || 'Не вдалося завантажити quiz', 'error');
                }
            } catch (error) {
                showMessage('Помилка завантаження quiz: ' + error.message, 'error');
            }
        }

        function displayQuizzes(quizzes) {
            const quizSelect = document.getElementById('quiz-select');

            if (quizzes.length === 0) {
                quizSelect.innerHTML = '<option disabled>Файли quiz не знайдені</option>';
                return;
            }

            quizSelect.innerHTML = '';
            quizzes.forEach(quiz => {
                const option = document.createElement('option');
                const filename = quiz.filename;
                const title = quiz.title;
                option.value = filename;

                // Build display text: filename with optional title
                let displayText = filename;
                if (title) {
                    displayText = `${filename} - ${title}`;
                }
                if (filename === currentQuiz) {
                    displayText += ' (поточний)';
                    option.classList.add('current-quiz');
                }
                option.textContent = displayText;
                quizSelect.appendChild(option);
            });

            // Add change event listener
            quizSelect.onchange = handleQuizSelectionChange;

            // Update button visibility based on current selection state
            updateButtonVisibility();
        }

        function handleQuizSelectionChange() {
            const quizSelect = document.getElementById('quiz-select');
            selectedQuizzes = Array.from(quizSelect.selectedOptions).map(opt => opt.value);
            updateButtonVisibility();
        }

        function updateButtonVisibility() {
            const singleActions = document.getElementById('single-quiz-actions');
            const multiActions = document.getElementById('multi-quiz-actions');
            const switchBtn = document.getElementById('switch-btn');
            const editBtn = document.getElementById('edit-btn');
            const duplicateBtn = document.getElementById('duplicate-btn');
            const deleteBtn = document.getElementById('delete-btn');

            const count = selectedQuizzes.length;

            if (count === 0) {
                // No selection - show single actions, all disabled
                singleActions.classList.remove('hidden');
                multiActions.classList.add('hidden');
                switchBtn.disabled = true;
                editBtn.disabled = true;
                duplicateBtn.disabled = true;
                deleteBtn.disabled = true;
            } else if (count === 1) {
                // Single selection - show standard buttons
                singleActions.classList.remove('hidden');
                multiActions.classList.add('hidden');

                const selected = selectedQuizzes[0];
                switchBtn.disabled = false;
                switchBtn.textContent = selected === currentQuiz
                    ? 'Перезапустити Поточний Quiz'
                    : 'Переключитися на Вибраний Quiz';
                editBtn.disabled = false;
                duplicateBtn.disabled = false;
                deleteBtn.disabled = selected === currentQuiz;
            } else {
                // Multiple selection - show unite button, hide switch/edit/duplicate
                singleActions.classList.add('hidden');
                multiActions.classList.remove('hidden');

                // Delete enabled if none of selected is current quiz
                deleteBtn.disabled = selectedQuizzes.includes(currentQuiz);
            }
        }

        async function switchQuiz() {
            if (selectedQuizzes.length !== 1) {
                showMessage('Будь ласка, виберіть один quiz', 'warning');
                return;
            }

            const selectedQuiz = selectedQuizzes[0];
            const isRestart = selectedQuiz === currentQuiz;

            const switchBtn = document.getElementById('switch-btn');
            switchBtn.disabled = true;
            switchBtn.textContent = isRestart ? 'Restarting...' : 'Switching...';

            try {
                const response = await fetch('/api/admin/switch-quiz', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        quiz_filename: selectedQuiz
                    }),
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    const action = isRestart ? 'restarted' : 'switched to';
                    showMessage(`Successfully ${action} "${selectedQuiz}". CSV file: ${data.csv_file}`, 'success');
                    currentQuiz = selectedQuiz;

                    // Refresh the quiz list to update current indicators
                    await loadQuizzes();

                    // Reset selection
                    selectedQuizzes = [];
                    switchBtn.textContent = 'Переключитися на Вибраний Quiz';
                } else {
                    showMessage(data.error || `Failed to ${isRestart ? 'restart' : 'switch'} quiz`, 'error');
                    switchBtn.disabled = false;
                    switchBtn.textContent = isRestart ? 'Restart Current Quiz' : 'Switch to Selected Quiz';
                }
            } catch (error) {
                showMessage(`Error ${isRestart ? 'restarting' : 'switching'} quiz: ` + error.message, 'error');
                switchBtn.disabled = false;
                switchBtn.textContent = isRestart ? 'Restart Current Quiz' : 'Switch to Selected Quiz';
            }
        }

        async function refreshQuizzes() {
            await loadQuizzes();
            showMessage('Список quiz оновлено', 'success');
        }

        function showMessage(text, type) {
            const messageArea = document.getElementById('message-area');
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${type}`;
            messageDiv.textContent = text;

            messageArea.appendChild(messageDiv);

            // Auto-remove after 5 seconds
            setTimeout(() => {
                if (messageDiv.parentNode) {
                    messageDiv.parentNode.removeChild(messageDiv);
                }
            }, 5000);
        }

        // Allow Enter key to authenticate
        document.getElementById('master-key').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                authenticate();
            }
        });

        // Quiz Editor Variables
        let isEditMode = false;
        let editingQuizName = '';
        let questionCounter = 1;

        // Quiz Editor Functions
        function createNewQuiz() {
            isEditMode = false;
            editingQuizName = '';
            document.getElementById('modal-title').textContent = 'Створити Новий Quiz';
            document.getElementById('quiz-filename').value = '';
            document.getElementById('quiz-filename').disabled = false;
            resetQuizEditor();
            document.getElementById('quiz-editor-modal').style.display = 'block';
        }

        async function editSelectedQuiz() {
            if (selectedQuizzes.length !== 1) {
                showMessage('Будь ласка, виберіть один quiz для редагування', 'warning');
                return;
            }

            const selectedQuiz = selectedQuizzes[0];
            isEditMode = true;
            editingQuizName = selectedQuiz;
            document.getElementById('modal-title').textContent = `Редагувати Quiz: ${selectedQuiz}`;
            document.getElementById('quiz-filename').value = selectedQuiz.replace('.yaml', '');
            document.getElementById('quiz-filename').disabled = true;

            try {
                const response = await fetch(`/api/admin/quiz/${selectedQuiz}`, {
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    // Load quiz data into editor
                    if (data.parsed) {
                        loadQuizDataToWizard(data.parsed);
                    }
                    document.getElementById('quiz-editor-modal').style.display = 'block';
                } else {
                    showMessage(data.error || 'Не вдалося завантажити quiz', 'error');
                }
            } catch (error) {
                showMessage('Помилка завантаження quiz: ' + error.message, 'error');
            }
        }

        async function duplicateSelectedQuiz() {
            if (selectedQuizzes.length !== 1) {
                showMessage('Будь ласка, виберіть один quiz для дублювання', 'warning');
                return;
            }

            const selectedQuiz = selectedQuizzes[0];
            const newFilename = prompt(`Введіть ім'я для дубльованого quiz:`, selectedQuiz.replace('.yaml', '_copy'));
            if (!newFilename) {
                return;
            }

            try {
                // First get the original quiz content
                const getResponse = await fetch(`/api/admin/quiz/${selectedQuiz}`, {
                    credentials: 'same-origin'
                });

                const getResult = await getResponse.json();

                if (!getResponse.ok) {
                    showMessage(getResult.error || 'Не вдалося завантажити оригінальний quiz', 'error');
                    return;
                }

                // Create new quiz with the same content
                const createResponse = await fetch('/api/admin/create-quiz', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        filename: newFilename,
                        mode: 'text',
                        content: getResult.content
                    }),
                    credentials: 'same-origin'
                });

                const createResult = await createResponse.json();

                if (createResponse.ok) {
                    showMessage(`Quiz duplicated successfully as "${createResult.filename}"`, 'success');
                    await loadQuizzes();
                } else {
                    showMessage(createResult.error || 'Не вдалося дублювати quiz', 'error');
                }
            } catch (error) {
                showMessage('Помилка дублювання quiz: ' + error.message, 'error');
            }
        }

        async function deleteSelectedQuiz() {
            if (selectedQuizzes.length === 0) {
                showMessage('Будь ласка, виберіть quiz для видалення', 'warning');
                return;
            }

            // Check if any selected is current quiz
            if (selectedQuizzes.includes(currentQuiz)) {
                showMessage('Неможливо видалити поточний активний quiz', 'error');
                return;
            }

            const message = selectedQuizzes.length === 1
                ? `Ви впевнені, що хочете видалити "${selectedQuizzes[0]}"?`
                : `Ви впевнені, що хочете видалити ${selectedQuizzes.length} quiz(ів)?`;

            if (!confirm(message + ' Ця дія не може бути скасована.')) {
                return;
            }

            // Delete each quiz sequentially
            const errors = [];
            let successCount = 0;

            for (const quiz of selectedQuizzes) {
                try {
                    const response = await fetch(`/api/admin/quiz/${quiz}`, {
                        method: 'DELETE',
                        credentials: 'same-origin'
                    });

                    if (response.ok) {
                        successCount++;
                    } else {
                        const data = await response.json();
                        errors.push(`${quiz}: ${data.error || 'Помилка'}`);
                    }
                } catch (error) {
                    errors.push(`${quiz}: ${error.message}`);
                }
            }

            if (errors.length === 0) {
                showMessage(`Успішно видалено ${successCount} quiz(ів)`, 'success');
            } else if (successCount > 0) {
                showMessage(`Видалено ${successCount} quiz(ів). Помилки: ${errors.join(', ')}`, 'warning');
            } else {
                showMessage(`Помилка видалення: ${errors.join(', ')}`, 'error');
            }

            selectedQuizzes = [];
            await loadQuizzes();
        }

        async function uniteSelectedQuizzes() {
            if (selectedQuizzes.length < 2) {
                showMessage('Будь ласка, виберіть принаймні 2 quiz для об\'єднання', 'warning');
                return;
            }

            // Suggest name based on first quiz
            const suggestedName = selectedQuizzes[0].replace('.yaml', '_united');
            const newFilename = prompt(
                `Введіть ім'я для об'єднаного quiz (${selectedQuizzes.length} quizzes):`,
                suggestedName
            );

            if (!newFilename) {
                return;
            }

            const uniteBtn = document.getElementById('unite-btn');
            uniteBtn.disabled = true;
            uniteBtn.textContent = 'Об\'єднання...';

            try {
                const response = await fetch('/api/admin/unite-quizzes', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        quiz_filenames: selectedQuizzes,
                        new_name: newFilename
                    }),
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    let message = `Quiz успішно об'єднано в "${data.filename}". Загалом питань: ${data.total_questions}`;
                    if (data.warning) {
                        message += `. ${data.warning}`;
                    }
                    showMessage(message, 'success');
                    selectedQuizzes = [];
                    await loadQuizzes();
                } else {
                    showMessage(data.error || 'Не вдалося об\'єднати quizzes', 'error');
                }
            } catch (error) {
                showMessage('Помилка об\'єднання quiz: ' + error.message, 'error');
            } finally {
                uniteBtn.disabled = false;
                uniteBtn.textContent = '🔗 Об\'єднати quizzes';
            }
        }

        function closeQuizEditor() {
            document.getElementById('quiz-editor-modal').style.display = 'none';
            resetQuizEditor();
        }

        function resetQuizEditor() {
            questionCounter = 1;

            // Clear content
            document.getElementById('questions-container').innerHTML = '';

            // Add initial question
            addQuestion();
        }

        function addQuestion(collapsed = false) {
            const container = document.getElementById('questions-container');
            const questionDiv = document.createElement('div');
            questionDiv.className = collapsed ? 'question-item collapsed' : 'question-item';
            questionDiv.dataset.questionId = questionCounter;
            questionDiv.draggable = true;

            questionDiv.innerHTML = `
                <div class="question-header" onclick="toggleQuestionCollapse(${questionCounter}, event)">
                    <div class="question-header-left">
                        <span class="drag-handle" title="Перетягніть для зміни порядку">☰</span>
                        <span class="question-collapse-icon">▼</span>
                        <span class="question-number">${questionCounter}.</span>
                        <span class="question-indicators"></span>
                        <span class="question-preview"></span>
                    </div>
                    <div class="question-header-buttons">
                        <button type="button" onclick="moveQuestion(${questionCounter}, 'up', event)" title="Перемістити вгору">↑</button>
                        <button type="button" onclick="moveQuestion(${questionCounter}, 'down', event)" title="Перемістити вниз">↓</button>
                        <button type="button" onclick="removeQuestion(${questionCounter}, event)" class="btn-danger" title="Видалити">×</button>
                    </div>
                </div>
                <div class="question-body">
                    <div class="form-group">
                        <label>Текст Питання (необов'язково, якщо є зображення):</label>
                        <input type="text" class="question-text" placeholder="Введіть текст питання" style="width: 100%;" oninput="updateQuestionPreview(this)">
                    </div>
                    <div class="form-group">
                        <label>Зображення Питання (необов'язково, якщо є текст):</label>
                        <div style="display: flex; align-items: center; gap: 5px;">
                            <input type="text" class="question-image" placeholder="напр., /imgs/diagram.png" style="width: 100%;" oninput="updateQuestionImagePreview(this); updateQuestionPreview(this)">
                            <button type="button" onclick="openImagePicker('question-image', ${questionCounter})" style="padding: 5px 8px; font-size: 16px;" title="Select image">📷</button>
                        </div>
                        <div class="image-preview-container">
                            <img class="image-preview" src="" alt="Preview" onclick="openFullscreenPreview(this.src)" title="Click to enlarge">
                        </div>
                    </div>
                    <div class="form-group">
                        <label>Файл для Завантаження (необов'язково):</label>
                        <div style="display: flex; align-items: center; gap: 5px;">
                            <input type="text" class="question-file" placeholder="напр., data.xlsx" style="width: 100%;" oninput="updateQuestionPreview(this)">
                            <button type="button" onclick="openFilePicker(${questionCounter})" style="padding: 5px 8px; font-size: 16px;" title="Select file">📎</button>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>Тип Питання:</label>
                        <div style="margin: 10px 0;">
                            <button type="button" class="question-type-toggle active" data-type="single" onclick="toggleQuestionType(${questionCounter}, 'single')">📝 Одна правильна відповідь</button>
                            <button type="button" class="question-type-toggle" data-type="multiple" onclick="toggleQuestionType(${questionCounter}, 'multiple')">☑️ Кілька правильних відповідей</button>
                            <button type="button" class="question-type-toggle" data-type="text" onclick="toggleQuestionType(${questionCounter}, 'text')">✍️ Текстова відповідь</button>
                        </div>
                    </div>
                    <div class="choice-question-fields">
                        <div class="form-group">
                            <label>Варіанти Відповідей:</label>
                            <div class="options-container">
                                <div class="option-item">
                                    <input type="radio" name="correct-${questionCounter}" value="0" checked>
                                    <input type="text" class="option-text" placeholder="Варіант 1" oninput="updateOptionImagePreview(this)">
                                    <button type="button" onclick="openImagePicker('option-text', ${questionCounter}, 0)" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                                    <button type="button" onclick="removeOption(this)">×</button>
                                </div>
                                <div class="option-item">
                                    <input type="radio" name="correct-${questionCounter}" value="1">
                                    <input type="text" class="option-text" placeholder="Варіант 2" oninput="updateOptionImagePreview(this)">
                                    <button type="button" onclick="openImagePicker('option-text', ${questionCounter}, 1)" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                                    <button type="button" onclick="removeOption(this)">×</button>
                                </div>
                            </div>
                            <button type="button" onclick="addOption(${questionCounter})">+ Додати Варіант</button>
                        </div>
                        <div class="form-group min-correct-container" style="display: none;">
                            <label for="min-correct-${questionCounter}">Мінімум правильних відповідей:</label>
                            <input type="number" id="min-correct-${questionCounter}" class="min-correct-input" min="1" placeholder="Усі правильні" style="width: 80px;">
                        </div>
                    </div>
                    <div class="text-question-fields" style="display: none;">
                        <div class="form-group">
                            <label>Початкове Значення (показується користувачу):</label>
                            <textarea class="default-value-input" placeholder="Введіть початкове значення для відображення..." style="width: 100%; min-height: 60px; font-family: monospace;">0</textarea>
                        </div>
                        <div class="form-group">
                            <label>Правильна Відповідь (показується при помилці):</label>
                            <textarea class="correct-value-input" placeholder="Введіть правильну відповідь..." style="width: 100%; min-height: 60px; font-family: monospace;">1000</textarea>
                        </div>
                        <div class="form-group">
                            <label>Перевірка (Python код):</label>
                            <div style="display: flex; gap: 10px; margin-bottom: 5px;">
                                <select class="checker-template-select" onchange="insertCheckerTemplate(${questionCounter}, this)" style="flex: 1;">
                                    <option value="">-- Оберіть шаблон --</option>
                                </select>
                            </div>
                            <textarea class="checker-input" style="width: 100%; min-height: 120px; font-family: monospace;">assert 900 < to_int(user_answer) < 1100, "Вийшли за рамки"</textarea>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="points-${questionCounter}" style="display: inline-block;">Бали за питання:</label>
                        <input type="number" id="points-${questionCounter}" class="points-input" min="1" value="1" placeholder="1" style="width: 80px;" oninput="updateQuestionPreview(this)">
                    </div>
                </div>
            `;

            container.appendChild(questionDiv);
            setupDragEvents(questionDiv);
            questionCounter++;
            updateQuestionNumbers();

            // Scroll the new question into view and focus if not collapsed
            if (!collapsed) {
                questionDiv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });

                // Focus on the question text input
                const questionTextInput = questionDiv.querySelector('.question-text');
                if (questionTextInput) {
                    setTimeout(() => questionTextInput.focus(), 300);
                }
            }
        }

        // Drag and drop functionality
        let draggedQuestion = null;

        function setupDragEvents(questionDiv) {
            questionDiv.addEventListener('dragstart', handleDragStart);
            questionDiv.addEventListener('dragend', handleDragEnd);
            questionDiv.addEventListener('dragover', handleDragOver);
            questionDiv.addEventListener('dragenter', handleDragEnter);
            questionDiv.addEventListener('dragleave', handleDragLeave);
            questionDiv.addEventListener('drop', handleDrop);
        }

        function handleDragStart(e) {
            draggedQuestion = this;
            this.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', this.dataset.questionId);
        }

        function handleDragEnd(e) {
            this.classList.remove('dragging');
            document.querySelectorAll('.question-item').forEach(item => {
                item.classList.remove('drag-over');
            });
            draggedQuestion = null;
        }

        function handleDragOver(e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
        }

        function handleDragEnter(e) {
            e.preventDefault();
            if (this !== draggedQuestion) {
                this.classList.add('drag-over');
            }
        }

        function handleDragLeave(e) {
            this.classList.remove('drag-over');
        }

        function handleDrop(e) {
            e.preventDefault();
            this.classList.remove('drag-over');

            if (draggedQuestion && this !== draggedQuestion) {
                const container = document.getElementById('questions-container');
                const allQuestions = Array.from(container.children);
                const draggedIndex = allQuestions.indexOf(draggedQuestion);
                const dropIndex = allQuestions.indexOf(this);

                if (draggedIndex < dropIndex) {
                    this.parentNode.insertBefore(draggedQuestion, this.nextSibling);
                } else {
                    this.parentNode.insertBefore(draggedQuestion, this);
                }

                updateQuestionNumbers();
            }
        }

        function toggleQuestionCollapse(questionId, event) {
            // Don't toggle if clicking on buttons or drag handle
            if (event && (event.target.closest('.question-header-buttons') || event.target.closest('.drag-handle'))) {
                return;
            }
            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (questionDiv) {
                questionDiv.classList.toggle('collapsed');
            }
        }

        function updateQuestionPreview(input) {
            const questionDiv = input.closest('.question-item');
            if (!questionDiv) return;

            const previewSpan = questionDiv.querySelector('.question-preview');
            const indicatorsSpan = questionDiv.querySelector('.question-indicators');
            if (!previewSpan) return;

            const questionText = questionDiv.querySelector('.question-text').value.trim();
            const questionImage = questionDiv.querySelector('.question-image').value.trim();
            const questionFile = questionDiv.querySelector('.question-file').value.trim();
            const pointsInput = questionDiv.querySelector('.points-input');
            const points = pointsInput ? parseInt(pointsInput.value) || 1 : 1;

            // Set preview text (full text, no truncation)
            previewSpan.textContent = questionText || '';

            // Set indicators for image, file, and points
            if (indicatorsSpan) {
                let indicators = '';
                if (questionImage) {
                    indicators += '<span class="question-indicator" title="Має зображення">🖼️</span>';
                }
                if (questionFile) {
                    indicators += '<span class="question-indicator" title="Має файл">📎</span>';
                }
                if (points > 1) {
                    indicators += `<span class="question-indicator points-indicator" title="${points} балів"> 🏆${points}</span>`;
                }
                indicatorsSpan.innerHTML = indicators;
            }
        }

        function removeQuestion(questionId, event) {
            if (event) event.stopPropagation();

            // Show confirmation dialog
            if (!confirm('Ви впевнені, що хочете видалити це питання?')) {
                return;
            }

            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (questionDiv) {
                questionDiv.remove();
                updateQuestionNumbers();
            }
        }

        function moveQuestion(questionId, direction, event) {
            if (event) event.stopPropagation();
            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (!questionDiv) return;

            const container = document.getElementById('questions-container');
            const allQuestions = Array.from(container.children);
            const currentIndex = allQuestions.indexOf(questionDiv);

            let moved = false;
            if (direction === 'up' && currentIndex > 0) {
                // Move up
                container.insertBefore(questionDiv, allQuestions[currentIndex - 1]);
                updateQuestionNumbers();
                moved = true;
            } else if (direction === 'down' && currentIndex < allQuestions.length - 1) {
                // Move down
                container.insertBefore(allQuestions[currentIndex + 1], questionDiv);
                updateQuestionNumbers();
                moved = true;
            }

            // Animate scroll to the moved question
            if (moved) {
                setTimeout(() => {
                    questionDiv.scrollIntoView({
                        behavior: 'smooth',
                        block: 'center',
                        inline: 'nearest'
                    });

                    // Add a brief highlight animation
                    questionDiv.style.transition = 'background-color 0.3s ease';
                    const originalBg = getComputedStyle(questionDiv).backgroundColor;
                    questionDiv.style.backgroundColor = 'var(--option-selected)';

                    setTimeout(() => {
                        questionDiv.style.backgroundColor = originalBg;
                        setTimeout(() => {
                            questionDiv.style.transition = '';
                        }, 300);
                    }, 300);
                }, 50);
            }
        }

        function updateQuestionNumbers() {
            const container = document.getElementById('questions-container');
            const questions = container.children;

            // Store checked states before updating names
            const checkedStates = [];
            for (let i = 0; i < questions.length; i++) {
                const questionDiv = questions[i];
                const radioButtons = questionDiv.querySelectorAll('input[type="radio"]');
                let checkedIndex = -1;
                radioButtons.forEach((radio, index) => {
                    if (radio.checked) {
                        checkedIndex = index;
                    }
                });
                checkedStates[i] = checkedIndex;
            }

            // Update numbers and radio button names
            for (let i = 0; i < questions.length; i++) {
                const questionDiv = questions[i];
                const questionNumber = i + 1;

                // Update the visual question number in header
                const numberSpan = questionDiv.querySelector('.question-number');
                if (numberSpan) {
                    numberSpan.textContent = `${questionNumber}.`;
                }

                // Update radio button names to ensure correct grouping
                const radioButtons = questionDiv.querySelectorAll('input[type="radio"]');
                radioButtons.forEach((radio, index) => {
                    radio.name = `correct-${questionNumber}`;
                    // Restore checked state
                    radio.checked = (index === checkedStates[i]);
                });
            }

            // Update button visibility
            updateMoveButtonVisibility();
        }

        function updateMoveButtonVisibility() {
            const container = document.getElementById('questions-container');
            const questions = container.children;

            for (let i = 0; i < questions.length; i++) {
                const questionDiv = questions[i];
                const upButton = questionDiv.querySelector('button[onclick*="up"]');
                const downButton = questionDiv.querySelector('button[onclick*="down"]');

                if (upButton) {
                    upButton.style.display = i === 0 ? 'none' : 'inline-block';
                }

                if (downButton) {
                    downButton.style.display = i === questions.length - 1 ? 'none' : 'inline-block';
                }
            }
        }

        function toggleQuestionType(questionId, type) {
            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (!questionDiv) return;

            const toggleButtons = questionDiv.querySelectorAll('.question-type-toggle');
            const optionInputs = questionDiv.querySelectorAll('.choice-question-fields input[type="radio"], .choice-question-fields input[type="checkbox"]');
            const minCorrectContainer = questionDiv.querySelector('.min-correct-container');
            const choiceFields = questionDiv.querySelector('.choice-question-fields');
            const textFields = questionDiv.querySelector('.text-question-fields');

            // Update toggle button states
            toggleButtons.forEach(btn => {
                if (btn.dataset.type === type) {
                    btn.classList.add('active');
                } else {
                    btn.classList.remove('active');
                }
            });

            // Show/hide appropriate fields
            if (type === 'text') {
                // Text input question
                choiceFields.style.display = 'none';
                textFields.style.display = 'block';
                // Load checker templates
                loadCheckerTemplates(questionId);
            } else {
                // Choice question (single or multiple)
                choiceFields.style.display = 'block';
                textFields.style.display = 'none';

                // Convert input types
                if (type === 'multiple') {
                    // Convert to checkboxes
                    optionInputs.forEach(input => {
                        if (input.type === 'radio') {
                            input.type = 'checkbox';
                            input.name = `correct-${questionId}-multiple`;
                        }
                    });
                    minCorrectContainer.style.display = 'block';
                } else {
                    // Convert to radio buttons
                    optionInputs.forEach((input, index) => {
                        if (input.type === 'checkbox') {
                            input.type = 'radio';
                            input.name = `correct-${questionId}`;
                            // Keep only first checked item for radio mode
                            input.checked = index === 0;
                        }
                    });
                    minCorrectContainer.style.display = 'none';
                }
            }
        }

        // Cache for checker templates
        let checkerTemplatesCache = null;

        async function loadCheckerTemplates(questionId) {
            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (!questionDiv) return;

            const select = questionDiv.querySelector('.checker-template-select');
            if (!select) return;

            // Check if already loaded
            if (select.options.length > 1) return;

            // Load from cache or fetch
            if (!checkerTemplatesCache) {
                try {
                    const response = await fetch('/api/admin/list-checker-templates');
                    if (response.ok) {
                        const data = await response.json();
                        checkerTemplatesCache = data.templates || [];
                    } else {
                        checkerTemplatesCache = [];
                    }
                } catch (e) {
                    console.error('Failed to load checker templates:', e);
                    checkerTemplatesCache = [];
                }
            }

            // Populate select
            checkerTemplatesCache.forEach(template => {
                const option = document.createElement('option');
                option.value = template.code;
                option.textContent = template.name;
                select.appendChild(option);
            });
        }

        function insertCheckerTemplate(questionId, selectElement) {
            if (!selectElement.value) return;

            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            if (!questionDiv) return;

            const checkerInput = questionDiv.querySelector('.checker-input');
            if (checkerInput) {
                checkerInput.value = selectElement.value;
            }

            // Reset select
            selectElement.selectedIndex = 0;
        }

        function addOption(questionId) {
            const questionDiv = document.querySelector(`[data-question-id="${questionId}"]`);
            const optionsContainer = questionDiv.querySelector('.options-container');
            const optionIndex = optionsContainer.children.length;

            // Determine current question type
            const isMultiple = questionDiv.querySelector('.question-type-toggle[data-type="multiple"]').classList.contains('active');
            const inputType = isMultiple ? 'checkbox' : 'radio';
            const inputName = isMultiple ? `correct-${questionId}-multiple` : `correct-${questionId}`;

            const optionDiv = document.createElement('div');
            optionDiv.className = 'option-item';
            optionDiv.innerHTML = `
                <input type="${inputType}" name="${inputName}" value="${optionIndex}">
                <input type="text" class="option-text" placeholder="Варіант ${optionIndex + 1}" oninput="updateOptionImagePreview(this)">
                <button type="button" onclick="openImagePicker('option-text', ${questionId}, ${optionIndex})" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                <button type="button" onclick="removeOption(this)">×</button>
            `;

            optionsContainer.appendChild(optionDiv);
        }

        function removeOption(button) {
            const optionDiv = button.parentElement;
            const optionsContainer = optionDiv.parentElement;

            if (optionsContainer.children.length > 2) {
                optionDiv.remove();

                // Re-index radio buttons and update values
                Array.from(optionsContainer.children).forEach((option, index) => {
                    const radio = option.querySelector('input[type="radio"]');
                    radio.value = index;
                });
            } else {
                showMessage('Питання має мати принаймні 2 варіанти', 'warning');
            }
        }

        function loadQuizDataToWizard(quizData) {
            const container = document.getElementById('questions-container');
            container.innerHTML = '';
            questionCounter = 1;

            // Populate title field
            document.getElementById('quiz-title').value = quizData.title || '';

            // Populate show_right_answer field
            document.getElementById('show-right-answer').checked = quizData.show_right_answer !== false;

            // Populate randomize_questions field
            document.getElementById('randomize-questions').checked = quizData.randomize_questions === true;

            // Populate show_answers_on_completion field
            document.getElementById('show-answers-on-completion').checked = quizData.show_answers_on_completion === true;

            // Update visibility of show_answers_on_completion based on show_right_answer
            toggleShowAnswersOnCompletion();

            if (quizData.questions) {
                quizData.questions.forEach(question => {
                    const questionDiv = document.createElement('div');
                    // Start collapsed when editing existing quiz
                    questionDiv.className = 'question-item collapsed';
                    questionDiv.dataset.questionId = questionCounter;
                    questionDiv.draggable = true;

                    // Check if this is a text question (has checker)
                    const isTextQuestion = 'checker' in question;
                    const isMultipleChoice = !isTextQuestion && Array.isArray(question.correct_answer);
                    const correctAnswers = isMultipleChoice ? question.correct_answer : [question.correct_answer || 0];
                    const inputType = isMultipleChoice ? 'checkbox' : 'radio';
                    const inputName = isMultipleChoice ? `correct-${questionCounter}-multiple` : `correct-${questionCounter}`;

                    // Build options HTML (for choice questions only)
                    let optionsHtml = '';
                    if (!isTextQuestion && question.options) {
                        question.options.forEach((option, index) => {
                            const isCorrect = correctAnswers.includes(index);
                            const isImageOption = option && option.startsWith('/imgs/');
                            optionsHtml += `
                                <div class="option-item">
                                    <input type="${inputType}" name="${inputName}" value="${index}" ${isCorrect ? 'checked' : ''}>
                                    <input type="text" class="option-text" value="${escapeHtml(option)}" placeholder="Варіант ${index + 1}" oninput="updateOptionImagePreview(this)">
                                    ${isImageOption ? `<img class="option-image-preview" src="${option}" alt="Option preview" title="Click to enlarge" onclick="openFullscreenPreview(this.src)">` : ''}
                                    <button type="button" onclick="openImagePicker('option-text', ${questionCounter}, ${index})" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                                    <button type="button" onclick="removeOption(this)">×</button>
                                </div>
                            `;
                        });
                    } else if (!isTextQuestion) {
                        // Default empty options for new choice question
                        optionsHtml = `
                            <div class="option-item">
                                <input type="radio" name="${inputName}" value="0" checked>
                                <input type="text" class="option-text" placeholder="Варіант 1" oninput="updateOptionImagePreview(this)">
                                <button type="button" onclick="openImagePicker('option-text', ${questionCounter}, 0)" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                                <button type="button" onclick="removeOption(this)">×</button>
                            </div>
                            <div class="option-item">
                                <input type="radio" name="${inputName}" value="1">
                                <input type="text" class="option-text" placeholder="Варіант 2" oninput="updateOptionImagePreview(this)">
                                <button type="button" onclick="openImagePicker('option-text', ${questionCounter}, 1)" style="padding: 2px 5px; font-size: 12px;" title="Select image">📷</button>
                                <button type="button" onclick="removeOption(this)">×</button>
                            </div>
                        `;
                    }

                    const minCorrectValue = question.min_correct || '';
                    const minCorrectDisplay = isMultipleChoice ? 'block' : 'none';
                    const pointsValue = question.points || 1;

                    // Build preview text (full text, no truncation)
                    const previewText = question.question || '';

                    // Build indicators for image, file, and points
                    let indicatorsHtml = '';
                    if (question.image) {
                        indicatorsHtml += '<span class="question-indicator" title="Має зображення">🖼️</span>';
                    }
                    if (question.file) {
                        indicatorsHtml += '<span class="question-indicator" title="Має файл">📎</span>';
                    }
                    if (pointsValue > 1) {
                        indicatorsHtml += `<span class="question-indicator points-indicator" title="${pointsValue} балів">🏆 ${pointsValue}</span>`;
                    }

                    questionDiv.innerHTML = `
                        <div class="question-header" onclick="toggleQuestionCollapse(${questionCounter}, event)">
                            <div class="question-header-left">
                                <span class="drag-handle" title="Перетягніть для зміни порядку">☰</span>
                                <span class="question-collapse-icon">▼</span>
                                <span class="question-number">${questionCounter}.</span>
                                <span class="question-indicators">${indicatorsHtml}</span>
                                <span class="question-preview">${escapeHtml(previewText)}</span>
                            </div>
                            <div class="question-header-buttons">
                                <button type="button" onclick="moveQuestion(${questionCounter}, 'up', event)" title="Перемістити вгору">↑</button>
                                <button type="button" onclick="moveQuestion(${questionCounter}, 'down', event)" title="Перемістити вниз">↓</button>
                                <button type="button" onclick="removeQuestion(${questionCounter}, event)" class="btn-danger" title="Видалити">×</button>
                            </div>
                        </div>
                        <div class="question-body">
                            <div class="form-group">
                                <label>Текст Питання (необов'язково, якщо є зображення):</label>
                                <input type="text" class="question-text" value="${escapeHtml(question.question || '')}" placeholder="Введіть текст питання" style="width: 100%;" oninput="updateQuestionPreview(this)">
                            </div>
                            <div class="form-group">
                                <label>Зображення Питання (необов'язково, якщо є текст):</label>
                                <div style="display: flex; align-items: center; gap: 5px;">
                                    <input type="text" class="question-image" value="${escapeHtml(question.image || '')}" placeholder="напр., /imgs/diagram.png" style="width: 100%;" oninput="updateQuestionImagePreview(this); updateQuestionPreview(this)">
                                    <button type="button" onclick="openImagePicker('question-image', ${questionCounter})" style="padding: 5px 8px; font-size: 16px;" title="Select image">📷</button>
                                </div>
                                <div class="image-preview-container${question.image ? ' has-image' : ''}">
                                    <img class="image-preview" src="${question.image || ''}" alt="Preview" onclick="openFullscreenPreview(this.src)" title="Click to enlarge">
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Файл для Завантаження (необов'язково):</label>
                                <div style="display: flex; align-items: center; gap: 5px;">
                                    <input type="text" class="question-file" value="${escapeHtml(question.file || '')}" placeholder="напр., data.xlsx" style="width: 100%;" oninput="updateQuestionPreview(this)">
                                    <button type="button" onclick="openFilePicker(${questionCounter})" style="padding: 5px 8px; font-size: 16px;" title="Select file">📎</button>
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Тип Питання:</label>
                                <div style="margin: 10px 0;">
                                    <button type="button" class="question-type-toggle ${!isMultipleChoice && !isTextQuestion ? 'active' : ''}" data-type="single" onclick="toggleQuestionType(${questionCounter}, 'single')">📝 Одна правильна відповідь</button>
                                    <button type="button" class="question-type-toggle ${isMultipleChoice ? 'active' : ''}" data-type="multiple" onclick="toggleQuestionType(${questionCounter}, 'multiple')">☑️ Кілька правильних відповідей</button>
                                    <button type="button" class="question-type-toggle ${isTextQuestion ? 'active' : ''}" data-type="text" onclick="toggleQuestionType(${questionCounter}, 'text')">✍️ Текстова відповідь</button>
                                </div>
                            </div>
                            <div class="choice-question-fields" style="display: ${isTextQuestion ? 'none' : 'block'};">
                                <div class="form-group">
                                    <label>Варіанти Відповідей:</label>
                                    <div class="options-container">
                                        ${optionsHtml}
                                    </div>
                                    <button type="button" onclick="addOption(${questionCounter})">+ Додати Варіант</button>
                                </div>
                                <div class="form-group min-correct-container" style="display: ${minCorrectDisplay};">
                                    <label for="min-correct-${questionCounter}">Мінімум правильних відповідей:</label>
                                    <input type="number" id="min-correct-${questionCounter}" class="min-correct-input" min="1" value="${minCorrectValue}" placeholder="Усі правильні" style="width: 80px;">
                                </div>
                            </div>
                            <div class="text-question-fields" style="display: ${isTextQuestion ? 'block' : 'none'};">
                                <div class="form-group">
                                    <label>Початкове Значення (показується користувачу):</label>
                                    <textarea class="default-value-input" placeholder="Введіть початкове значення для відображення..." style="width: 100%; min-height: 60px; font-family: monospace;">${escapeHtml(question.default_value || '')}</textarea>
                                </div>
                                <div class="form-group">
                                    <label>Правильна Відповідь (показується при помилці):</label>
                                    <textarea class="correct-value-input" placeholder="Введіть правильну відповідь..." style="width: 100%; min-height: 60px; font-family: monospace;">${escapeHtml(question.correct_value || '')}</textarea>
                                </div>
                                <div class="form-group">
                                    <label>Перевірка (Python код):</label>
                                    <div style="display: flex; gap: 10px; margin-bottom: 5px;">
                                        <select class="checker-template-select" onchange="insertCheckerTemplate(${questionCounter}, this)" style="flex: 1;">
                                            <option value="">-- Оберіть шаблон --</option>
                                        </select>
                                    </div>
                                    <textarea class="checker-input" style="width: 100%; min-height: 120px; font-family: monospace;">${escapeHtml(question.checker)}</textarea>
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="points-${questionCounter}" style="display: inline-block;">Бали за питання:</label>
                                <input type="number" id="points-${questionCounter}" class="points-input" min="1" value="${pointsValue}" placeholder="1" style="width: 80px;" oninput="updateQuestionPreview(this)">
                            </div>
                        </div>
                    `;

                    container.appendChild(questionDiv);
                    setupDragEvents(questionDiv);
                    questionCounter++;
                });
                updateQuestionNumbers();
            }
        }

        function getWizardData() {
            const questions = [];
            const questionDivs = document.querySelectorAll('.question-item');

            questionDivs.forEach((div, index) => {
                const questionText = div.querySelector('.question-text').value.trim();
                const questionImage = div.querySelector('.question-image').value.trim();
                const questionFile = div.querySelector('.question-file').value.trim();

                // Either question text OR image must be provided
                const hasQuestionContent = questionText || questionImage;
                if (!hasQuestionContent) return;

                // Determine question type
                const isText = div.querySelector('.question-type-toggle[data-type="text"]').classList.contains('active');
                const isMultiple = div.querySelector('.question-type-toggle[data-type="multiple"]').classList.contains('active');

                let questionData;

                if (isText) {
                    // Text input question (detected by checker/correct_value, no type field needed)
                    questionData = {};

                    // Get text question fields
                    const defaultValueInput = div.querySelector('.default-value-input');
                    const correctValueInput = div.querySelector('.correct-value-input');
                    const checkerInput = div.querySelector('.checker-input');

                    if (defaultValueInput && defaultValueInput.value) {
                        questionData.default_value = defaultValueInput.value;
                    }
                    if (correctValueInput && correctValueInput.value) {
                        questionData.correct_value = correctValueInput.value;
                    }
                    if (checkerInput && checkerInput.value.trim()) {
                        questionData.checker = checkerInput.value;
                    }
                } else {
                    // Choice question (single or multiple)
                    const options = Array.from(div.querySelectorAll('.option-text')).map(input => input.value.trim());

                    // Check if we have valid options
                    if (!options.every(opt => opt) || options.length === 0) return;

                    questionData = {
                        options: options
                    };

                    if (isMultiple) {
                        // Multiple choice - collect all checked checkboxes
                        const checkedCheckboxes = Array.from(div.querySelectorAll('.choice-question-fields input[type="checkbox"]:checked'));
                        const correctAnswers = checkedCheckboxes.map(cb => parseInt(cb.value)).sort((a, b) => a - b);

                        if (correctAnswers.length > 0) {
                            questionData.correct_answer = correctAnswers;

                            // Add min_correct if specified
                            const minCorrectInput = div.querySelector('.min-correct-input');
                            if (minCorrectInput && minCorrectInput.value.trim()) {
                                const minCorrect = parseInt(minCorrectInput.value);
                                if (minCorrect > 0 && minCorrect <= correctAnswers.length) {
                                    questionData.min_correct = minCorrect;
                                }
                            }
                        } else {
                            // Default to first option if no checkboxes selected
                            questionData.correct_answer = [0];
                        }
                    } else {
                        // Single choice - get checked radio button
                        const correctRadio = div.querySelector('.choice-question-fields input[type="radio"]:checked');
                        questionData.correct_answer = correctRadio ? parseInt(correctRadio.value) : 0;
                    }
                }

                // Include question text if provided
                if (questionText) {
                    questionData.question = questionText;
                }

                // Include image if provided
                if (questionImage) {
                    questionData.image = questionImage;
                }

                // Include file if provided
                if (questionFile) {
                    questionData.file = questionFile;
                }

                // Include points if different from default (1)
                const pointsInput = div.querySelector('.points-input');
                if (pointsInput && pointsInput.value.trim()) {
                    const points = parseInt(pointsInput.value);
                    if (points > 1) {
                        questionData.points = points;
                    }
                }

                questions.push(questionData);
            });

            const quizData = { questions };

            // Include title if provided
            const quizTitle = document.getElementById('quiz-title').value.trim();
            if (quizTitle) {
                quizData.title = quizTitle;
            }

            // Include show_right_answer setting
            quizData.show_right_answer = document.getElementById('show-right-answer').checked;

            // Include randomize_questions setting
            quizData.randomize_questions = document.getElementById('randomize-questions').checked;

            // Include show_answers_on_completion setting
            quizData.show_answers_on_completion = document.getElementById('show-answers-on-completion').checked;

            return quizData;
        }

        async function saveQuiz() {
            const filename = document.getElementById('quiz-filename').value.trim();

            if (!filename) {
                showMessage('Будь ласка, введіть ім\'я файлу', 'error');
                return;
            }

            const quizData = getWizardData();
            if (!quizData.questions || quizData.questions.length === 0) {
                showMessage('Будь ласка, додайте принаймні одне питання', 'error');
                return;
            }

            try {
                const url = isEditMode ? `/api/admin/quiz/${editingQuizName}` : '/api/admin/create-quiz';
                const method = isEditMode ? 'PUT' : 'POST';

                const response = await fetch(url, {
                    method,
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        filename,
                        mode: 'wizard',
                        quiz_data: quizData
                    })
                });

                const data = await response.json();

                if (response.ok) {
                    showMessage(data.message, 'success');
                    closeQuizEditor();
                    await loadQuizzes();
                } else {
                    showMessage(data.error || 'Не вдалося зберегти quiz', 'error');
                }
            } catch (error) {
                showMessage('Помилка збереження quiz: ' + error.message, 'error');
            }
        }

        async function saveQuizAndContinue() {
            const filename = document.getElementById('quiz-filename').value.trim();

            if (!filename) {
                showMessage('Будь ласка, введіть ім\'я файлу', 'error');
                return;
            }

            const quizData = getWizardData();
            if (!quizData.questions || quizData.questions.length === 0) {
                showMessage('Будь ласка, додайте принаймні одне питання', 'error');
                return;
            }

            const button = document.getElementById('save-continue-btn');
            const originalText = '💾 Зберегти і Продовжити';
            button.disabled = true;
            button.innerHTML = '⏳ Збереження...';
            button.style.backgroundColor = '';

            let success = false;

            try {
                const url = isEditMode ? `/api/admin/quiz/${editingQuizName}` : '/api/admin/create-quiz';
                const method = isEditMode ? 'PUT' : 'POST';

                const response = await fetch(url, {
                    method,
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        filename,
                        mode: 'wizard',
                        quiz_data: quizData
                    })
                });

                const data = await response.json();

                if (response.ok) {
                    success = true;
                    showMessage(data.message, 'success');
                    // If this was a new quiz, switch to edit mode
                    if (!isEditMode) {
                        isEditMode = true;
                        editingQuizName = filename + '.yaml';
                        document.getElementById('modal-title').textContent = `Редагувати Quiz: ${editingQuizName}`;
                        document.getElementById('quiz-filename').disabled = true;
                    }
                    // Reload quiz list in background
                    loadQuizzes();
                } else {
                    showMessage(data.error || 'Не вдалося зберегти quiz', 'error');
                }
            } catch (error) {
                showMessage('Помилка збереження quiz: ' + error.message, 'error');
            }

            // Show result state
            if (success) {
                button.innerHTML = '✅ Збережено';
                button.style.backgroundColor = '#28a745';
            } else {
                button.innerHTML = '❌ Помилка';
                button.style.backgroundColor = '#dc3545';
            }

            // Return to default state after delay
            setTimeout(() => {
                button.disabled = false;
                button.innerHTML = originalText;
                button.style.backgroundColor = '';
            }, 1500);
        }

        // Network information display using server-generated data
        function displayNetworkInfo() {
            if (typeof NETWORK_INFO === 'undefined') {
                document.getElementById('wifi-name').textContent = 'Мережева інформація недоступна';
                document.getElementById('url-list').innerHTML = '<div class="url-item">Network detection failed</div>';
                return;
            }

            // Generate URL list from server data
            let urlHtml = '';

            if (NETWORK_INFO.urls && NETWORK_INFO.urls.length > 0) {
                NETWORK_INFO.urls.forEach(url => {
                    urlHtml += `
                        <div class="url-item">
                            <div class="label"><a href="${url.quiz_url}" target="_blank">${url.quiz_url}</a></div>
                        </div>
                    `;
                });
            } else {
                urlHtml += `
                    <div class="url-item">
                        <div class="label">⚠️ Зовнішні Мережеві Інтерфейси Не Знайдені</div>
                        <div class="url">
                            Сервер доступний тільки локально. Перевірте мережеві налаштування або параметри файрвола.
                        </div>
                    </div>
                `;
            }

            document.getElementById('url-list').innerHTML = urlHtml;
        }

        // Image picker functionality
        let currentImageTarget = null;

        async function openImagePicker(fieldType, questionId, optionIndex = null) {
            try {
                // Store the target information
                currentImageTarget = { fieldType, questionId, optionIndex };

                // Load images from server
                const response = await fetch('/api/admin/list-images', {
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    displayImageGrid(data.images);
                    document.getElementById('image-picker-modal').style.display = 'block';
                } else {
                    showMessage(data.error || 'Не вдалося завантажити зображення', 'error');
                }
            } catch (error) {
                showMessage('Помилка завантаження зображень: ' + error.message, 'error');
            }
        }

        function displayImageGrid(images) {
            const gridContainer = document.getElementById('image-grid');

            if (!images || images.length === 0) {
                gridContainer.innerHTML = `
                    <div style="text-align: center; padding: 40px; color: var(--text-muted);">
                        <p>Зображення не знайдені в директорії quizzes/imgs</p>
                        <small>Додайте файли зображень до директорії quizzes/imgs, щоб побачити їх тут</small>
                    </div>
                `;
                return;
            }

            let gridHtml = '';
            images.forEach(image => {
                gridHtml += `
                    <div class="image-item" onclick="selectImage('${image.path}')" title="${image.filename}">
                        <img src="${image.path}" alt="${image.filename}" loading="lazy">
                        <div class="image-filename">${image.filename}</div>
                    </div>
                `;
            });

            gridContainer.innerHTML = gridHtml;
        }

        function selectImage(imagePath) {
            if (!currentImageTarget) {
                showMessage('Поле не вибрано', 'error');
                return;
            }

            // Find the target input field based on stored information
            let targetInput = null;

            if (currentImageTarget.fieldType === 'question-image') {
                // Find question image field by question ID
                const questionDiv = document.querySelector(`[data-question-id="${currentImageTarget.questionId}"]`);
                if (questionDiv) {
                    targetInput = questionDiv.querySelector('.question-image');
                }
            } else if (currentImageTarget.fieldType === 'option-text') {
                // Find option text field by question ID and option index
                const questionDiv = document.querySelector(`[data-question-id="${currentImageTarget.questionId}"]`);
                if (questionDiv) {
                    const optionInputs = questionDiv.querySelectorAll('.option-text');
                    if (optionInputs[currentImageTarget.optionIndex]) {
                        targetInput = optionInputs[currentImageTarget.optionIndex];
                    }
                }
            }

            if (targetInput) {
                targetInput.value = imagePath;
                // Trigger preview update
                if (currentImageTarget.fieldType === 'question-image') {
                    updateQuestionImagePreview(targetInput);
                } else if (currentImageTarget.fieldType === 'option-text') {
                    updateOptionImagePreview(targetInput);
                }
                closeImagePicker();
                showMessage(`Зображення вибрано: ${imagePath}`, 'success');
            } else {
                showMessage('Поле вводу не знайдено', 'error');
            }
        }

        function closeImagePicker() {
            document.getElementById('image-picker-modal').style.display = 'none';
            currentImageTarget = null;
        }

        // File picker functionality
        let currentFileQuestionId = null;

        async function openFilePicker(questionId) {
            try {
                currentFileQuestionId = questionId;

                // Load files from server
                const response = await fetch('/api/admin/list-files', {
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    displayFileList(data.files);
                    document.getElementById('file-picker-modal').style.display = 'block';
                } else {
                    showMessage(data.error || 'Не вдалося завантажити файли', 'error');
                }
            } catch (error) {
                showMessage('Помилка завантаження файлів: ' + error.message, 'error');
            }
        }

        function formatFileSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
        }

        function displayFileList(files) {
            const listContainer = document.getElementById('file-list');

            if (!files || files.length === 0) {
                listContainer.innerHTML = `
                    <div style="text-align: center; padding: 40px; color: var(--text-muted);">
                        <p>Файли не знайдені в директорії quizzes/attach</p>
                        <small>Додайте файли до директорії quizzes/attach, щоб побачити їх тут</small>
                    </div>
                `;
                return;
            }

            let listHtml = '';
            files.forEach(file => {
                listHtml += `
                    <div class="file-item" onclick="selectFile('${file.path}')" title="${file.filename}">
                        <div class="file-item-info">
                            <span class="file-item-icon">📄</span>
                            <span class="file-item-name">${file.filename}</span>
                        </div>
                        <span class="file-item-size">${formatFileSize(file.size)}</span>
                    </div>
                `;
            });

            listContainer.innerHTML = listHtml;
        }

        function selectFile(filePath) {
            if (currentFileQuestionId === null) {
                showMessage('Питання не вибрано', 'error');
                return;
            }

            // Extract just the filename from the path (remove /attach/ prefix)
            const filename = filePath.replace(/^\/attach\//, '');

            // Find the question div by question ID
            const questionDiv = document.querySelector(`[data-question-id="${currentFileQuestionId}"]`);
            if (questionDiv) {
                const fileInput = questionDiv.querySelector('.question-file');
                if (fileInput) {
                    fileInput.value = filename;
                    closeFilePicker();
                    showMessage(`Файл вибрано: ${filename}`, 'success');
                } else {
                    showMessage('Поле вводу файлу не знайдено', 'error');
                }
            } else {
                showMessage('Питання не знайдено', 'error');
            }
        }

        function closeFilePicker() {
            document.getElementById('file-picker-modal').style.display = 'none';
            currentFileQuestionId = null;
        }

        // Image preview functions
        function updateQuestionImagePreview(input) {
            const imagePath = input.value.trim();
            const previewContainer = input.closest('.form-group').querySelector('.image-preview-container');
            const previewImg = previewContainer.querySelector('.image-preview');

            if (imagePath && imagePath.startsWith('/imgs/')) {
                previewImg.src = imagePath;
                previewImg.onerror = function() {
                    previewContainer.classList.remove('has-image');
                };
                previewImg.onload = function() {
                    previewContainer.classList.add('has-image');
                };
            } else {
                previewContainer.classList.remove('has-image');
                previewImg.src = '';
            }
        }

        function updateOptionImagePreview(input) {
            const imagePath = input.value.trim();
            const optionItem = input.closest('.option-item');
            let previewImg = optionItem.querySelector('.option-image-preview');

            if (imagePath && imagePath.startsWith('/imgs/')) {
                if (!previewImg) {
                    // Create preview image if it doesn't exist
                    previewImg = document.createElement('img');
                    previewImg.className = 'option-image-preview';
                    previewImg.alt = 'Option preview';
                    previewImg.title = 'Click to enlarge';
                    previewImg.onclick = function() { openFullscreenPreview(this.src); };
                    // Insert after the input field
                    input.parentNode.insertBefore(previewImg, input.nextSibling);
                }
                previewImg.src = imagePath;
                previewImg.style.display = 'inline-block';
                previewImg.onerror = function() {
                    this.style.display = 'none';
                };
            } else if (previewImg) {
                previewImg.style.display = 'none';
            }
        }

        function openFullscreenPreview(src) {
            if (!src) return;
            const modal = document.getElementById('image-fullscreen-modal');
            const fullscreenImg = document.getElementById('fullscreen-image');
            fullscreenImg.src = src;
            modal.style.display = 'block';
            // Prevent body scroll
            document.body.style.overflow = 'hidden';
        }

        function closeFullscreenPreview() {
            const modal = document.getElementById('image-fullscreen-modal');
            modal.style.display = 'none';
            document.body.style.overflow = '';
        }

        // Close fullscreen preview on Escape key
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                closeFullscreenPreview();
            }
        });

        // Downloadable Quizzes Functions
        function displayDownloadableQuizzes() {
            if (typeof DOWNLOADABLE_QUIZZES !== 'undefined' && DOWNLOADABLE_QUIZZES.length > 0) {
                const section = document.getElementById('downloadable-quizzes-section');
                const quizList = document.getElementById('downloadable-quiz-list');

                section.classList.remove('hidden');

                let html = '';
                DOWNLOADABLE_QUIZZES.forEach((quiz, index) => {
                    html += `
                        <div class="downloadable-quiz-item">
                            <div class="downloadable-quiz-info">
                                <div class="downloadable-quiz-name">${quiz.name}</div>
                                <div class="downloadable-quiz-url">${quiz.download_path}</div>
                                <small style="color: var(--text-muted);">Папка: ${quiz.folder}</small>
                            </div>
                            <button class="download-btn" onclick="downloadQuiz(${index})" id="download-btn-${index}">
                                📥 Завантажити
                            </button>
                        </div>
                    `;
                });
                quizList.innerHTML = html;
            }
        }

        function downloadQuiz(quizIndex) {
            // Validate inputs
            if (typeof DOWNLOADABLE_QUIZZES === 'undefined' || !DOWNLOADABLE_QUIZZES[quizIndex]) {
                showMessage('❌ Quiz не знайдено', 'error');
                return;
            }

            const quiz = DOWNLOADABLE_QUIZZES[quizIndex];
            const button = document.getElementById(`download-btn-${quizIndex}`);

            if (!button) {
                showMessage('❌ Кнопка не знайдена', 'error');
                return;
            }

            // Show confirmation
            const confirmed = confirm(`Завантажити quiz "${quiz.name}"?\n\nЦе завантажить та розпакує файли з:\n${quiz.download_path}\n\nФайли будуть перезаписані в директорії quizzes.`);
            if (!confirmed) {
                return;
            }

            // Disable button and show loading state
            button.disabled = true;
            button.innerHTML = '⏳ Завантаження...';

            // Use async IIFE to handle async operations
            (async () => {
                try {
                    const response = await fetch('/api/admin/download-quiz', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-Admin-Key': currentMasterKey
                        },
                        body: JSON.stringify({
                            name: quiz.name,
                            download_path: quiz.download_path,
                            folder: quiz.folder
                        }),
                        credentials: 'same-origin'
                    });

                    const data = await response.json();

                    if (response.ok && data.success) {
                        showMessage(`✅ ${data.message}`, 'success');
                        // Refresh quiz list to show newly downloaded quizzes
                        await loadQuizzes();
                    } else {
                        showMessage(`❌ Помилка завантаження: ${data.error}`, 'error');
                    }
                } catch (error) {
                    console.error('Download quiz error:', error);
                    showMessage(`❌ Помилка мережі: ${error.message}`, 'error');
                } finally {
                    // Re-enable button
                    button.disabled = false;
                    button.innerHTML = '📥 Завантажити';
                }
            })();
        }

        // Admin WebSocket for Pending Approvals
        let adminWebSocket = null;
        let pendingUsers = {};

        function connectToAdminWebSocket() {
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = `${protocol}//${window.location.host}/ws/admin`;

            adminWebSocket = new WebSocket(wsUrl);

            adminWebSocket.onopen = () => {
                console.log('Admin WebSocket connected');
            };

            adminWebSocket.onmessage = (event) => {
                try {
                    const data = JSON.parse(event.data);
                    handleAdminWebSocketMessage(data);
                } catch (error) {
                    console.error('Error parsing admin WebSocket message:', error);
                }
            };

            adminWebSocket.onclose = () => {
                console.log('Admin WebSocket disconnected');
                // Reconnect after 5 seconds
                setTimeout(connectToAdminWebSocket, 5000);
            };

            adminWebSocket.onerror = (error) => {
                console.error('Admin WebSocket error:', error);
            };
        }

        function handleAdminWebSocketMessage(data) {
            if (data.type === 'initial_state') {
                // Initial state - show/hide section based on requires_approval
                if (data.requires_approval) {
                    document.getElementById('pending-approvals-section').classList.remove('hidden');
                    pendingUsers = data.pending_users || {};
                    displayPendingUsers();
                }
                // Handle tunnel initial state
                if (data.tunnel) {
                    updateTunnelUI(data.tunnel);
                }
            } else if (data.type === 'tunnel_status') {
                // Tunnel status update
                if (data.tunnel) {
                    updateTunnelUI(data.tunnel);
                }
            } else if (data.type === 'new_registration') {
                // New user registered - data now contains user_id, username, registration_fields
                pendingUsers[data.user_id] = {
                    username: data.username,
                    registration_fields: data.registration_fields || {}
                };
                document.getElementById('pending-approvals-section').classList.remove('hidden');
                displayPendingUsers();
                showMessage(`Новий користувач: ${data.username}`, 'success');
            } else if (data.type === 'registration_updated') {
                // User updated registration data - data now contains user_id, username, registration_fields
                pendingUsers[data.user_id] = {
                    username: data.username,
                    registration_fields: data.registration_fields || {}
                };
                displayPendingUsers();
                showMessage(`Користувач ${data.username} оновив дані`, 'success');
            } else if (data.type === 'user_approved') {
                // User was approved
                const user_id = data.user_id;
                if (pendingUsers[user_id]) {
                    delete pendingUsers[user_id];
                    displayPendingUsers();
                }
            }
        }

        function fieldNameToLabel(fieldName) {
            // Convert field name to label: "моля_парола" -> "Моля Парола"
            return fieldName
                .split('_')
                .map(word => word.charAt(0).toUpperCase() + word.slice(1))
                .join(' ');
        }

        function displayPendingUsers() {
            const listContainer = document.getElementById('pending-users-list');
            const userIds = Object.keys(pendingUsers);

            if (userIds.length === 0) {
                listContainer.innerHTML = '<p style="text-align: center; color: var(--text-muted);">Немає користувачів, що очікують підтвердження</p>';
                return;
            }

            let html = '';
            for (const user_id of userIds) {
                const user = pendingUsers[user_id];
                html += `
                    <div class="pending-user-item" id="pending-user-${user_id}">
                        <div class="pending-user-info">
                            <div class="pending-user-name">👤 ${user.username}</div>
                `;

                // Add registration fields (only custom fields from server)
                for (const [key, value] of Object.entries(user.registration_fields || {})) {
                    const label = fieldNameToLabel(key);
                    html += `<div class="pending-user-data">${label}: ${value}</div>`;
                }

                html += `
                        </div>
                        <button class="approve-btn" onclick="approveUser('${user_id}')">✓ Підтвердити</button>
                    </div>
                `;
            }

            listContainer.innerHTML = html;
        }

        async function approveUser(userId) {
            if (!currentMasterKey) {
                showMessage('Потрібна автентифікація', 'error');
                return;
            }

            try {
                const response = await fetch('/api/admin/approve-user', {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ user_id: userId }),
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (response.ok) {
                    showMessage(`Користувача підтверджено!`, 'success');
                    // Remove from pending list
                    if (pendingUsers[userId]) {
                        delete pendingUsers[userId];
                        displayPendingUsers();
                    }
                } else {
                    showMessage(data.error || 'Помилка підтвердження', 'error');
                }
            } catch (error) {
                showMessage('Помилка з\'єднання: ' + error.message, 'error');
            }
        }

        // Auto-authenticate function that shows admin panel
        function showAdminPanel(message) {
            document.getElementById('auth-section').style.display = 'none';
            document.getElementById('admin-panel').classList.remove('hidden');
            showMessage(message, 'success');
            loadQuizzes();
            displayNetworkInfo();
            displayDownloadableQuizzes();
            connectToAdminWebSocket();
            displayVersion();
            checkForUpdates();
        }

        // Check for existing session cookie on page load
        async function checkExistingSession() {
            try {
                const response = await fetch('/api/admin/check-session', {
                    method: 'GET',
                    credentials: 'same-origin'
                });

                if (response.ok) {
                    // Valid session found - auto-authenticate
                    currentMasterKey = 'session'; // Placeholder, actual auth is via cookie
                    showAdminPanel('Сесію відновлено');
                    return true;
                }
            } catch (error) {
                // Session check failed, fall through to other auth methods
            }
            return false;
        }

        // Initialize authentication
        (async function initAuth() {
            // First, try to restore existing session
            const hasSession = await checkExistingSession();
            if (hasSession) return;

            // Fall back to trusted IP auto-authentication
            if (typeof IS_TRUSTED_IP !== 'undefined' && IS_TRUSTED_IP) {
                currentMasterKey = 'trusted-ip';
                showAdminPanel('Авто-автентифікація з довіреного IP');
            }
        })();

        // Version display functionality
        function displayVersion() {
            const versionSpan = document.getElementById('version-number');
            const docsLinkSpan = document.getElementById('footer-docs-link');

            if (typeof WEBQUIZ_VERSION !== 'undefined') {
                versionSpan.textContent = WEBQUIZ_VERSION;

                // Add documentation link
                const docUrl = `https://github.com/oduvan/webquiz/releases/download/v${WEBQUIZ_VERSION}/webquiz-documentation-uk.pdf`;
                docsLinkSpan.innerHTML = `| <a href="${docUrl}" target="_blank" style="color: var(--button-bg); text-decoration: none;">📄 Документація</a>`;
            } else {
                versionSpan.textContent = 'unknown';
                docsLinkSpan.innerHTML = '';
            }
        }

        // Version check functionality
        async function checkForUpdates() {
            // Only check if version is defined
            if (typeof WEBQUIZ_VERSION === 'undefined') {
                return;
            }

            try {
                const response = await fetch('https://pypi.org/pypi/webquiz/json', {
                    method: 'GET',
                    headers: {
                        'Accept': 'application/json'
                    }
                });

                if (!response.ok) {
                    return; // Silently fail
                }

                const data = await response.json();
                const latestVersion = data.info.version;
                const currentVersion = WEBQUIZ_VERSION;

                // Parse versions into arrays of integers
                const parseVersion = (version) => {
                    return version.split('.').map(part => parseInt(part, 10) || 0);
                };

                const currentParts = parseVersion(currentVersion);
                const latestParts = parseVersion(latestVersion);

                // Compare versions
                const maxLength = Math.max(currentParts.length, latestParts.length);
                let isNewer = false;

                for (let i = 0; i < maxLength; i++) {
                    const current = currentParts[i] || 0;
                    const latest = latestParts[i] || 0;

                    if (latest > current) {
                        isNewer = true;
                        break;
                    } else if (latest < current) {
                        break;
                    }
                }

                // Show update notification if newer version available
                if (isNewer) {
                    const updateElement = document.getElementById('footer-update');
                    updateElement.classList.remove('hidden');
                    updateElement.innerHTML = `⬆️ Update available: <a href="https://github.com/oduvan/webquiz/releases/tag/v${latestVersion}" target="_blank">v${latestVersion}</a>`;
                }
            } catch (error) {
                // Silently fail - don't show any error messages
                return;
            }
        }

        // Package version check (file vs memory)
        async function checkPackageVersionMismatch() {
            try {
                const response = await fetch('/api/admin/version-check');
                if (!response.ok) {
                    return;
                }

                const data = await response.json();
                if (data.restart_required) {
                    // Hide update notification when restart is required
                    const updateElement = document.getElementById('footer-update');
                    updateElement.classList.add('hidden');

                    const restartElement = document.getElementById('footer-restart');
                    const newVersionSpan = document.getElementById('new-version-number');
                    newVersionSpan.textContent = data.file_version;
                    restartElement.classList.remove('hidden');
                }
            } catch (error) {
                // Silently fail
                return;
            }
        }

        // Periodically check for package version mismatch (every 5 minutes)
        setInterval(checkPackageVersionMismatch, 300000);

        // Initial check after page load
        setTimeout(checkPackageVersionMismatch, 2000);

        // Tunnel Management Functions
        function updateTunnelUI(tunnelData) {
            const tunnelSection = document.getElementById('tunnel-section');

            // Only hide tunnel section if explicitly not configured (initial load)
            if (!tunnelData) {
                tunnelSection.style.display = 'none';
                return;
            }

            // If configured is explicitly false, hide section
            if (tunnelData.configured === false) {
                tunnelSection.style.display = 'none';
                return;
            }

            // Show tunnel section (for both initial load and status updates)
            tunnelSection.style.display = 'block';

            // Update server name (only if provided, to preserve during status updates)
            if (tunnelData.server) {
                document.getElementById('tunnel-server').textContent = tunnelData.server;
            }

            // Update socket name if provided
            const socketNameSection = document.getElementById('tunnel-socket-name-section');
            if (tunnelData.socket_name) {
                document.getElementById('tunnel-socket-name').textContent = tunnelData.socket_name;
                socketNameSection.style.display = 'block';
            } else {
                socketNameSection.style.display = 'none';
            }

            // Display public key if tunnel is configured
            const publicKeySection = document.getElementById('tunnel-public-key-section');
            if (tunnelData.configured && tunnelData.keys_status === 'ok' && typeof TUNNEL_PUBLIC_KEY !== 'undefined') {
                document.getElementById('tunnel-public-key').value = TUNNEL_PUBLIC_KEY;
                publicKeySection.style.display = 'block';
            } else {
                publicKeySection.style.display = 'none';
            }

            // Update connect button and error display
            const connectBtn = document.getElementById('tunnel-connect-btn');
            const errorSection = document.getElementById('tunnel-error');
            const urlList = document.getElementById('url-list');

            if (tunnelData.connected) {
                connectBtn.textContent = 'Disconnect';
                connectBtn.disabled = false;
                errorSection.style.display = 'none';

                // Add tunnel URL to main URL list if not already present
                if (tunnelData.url && !document.getElementById('tunnel-url-item')) {
                    const tunnelUrlItem = document.createElement('div');
                    tunnelUrlItem.id = 'tunnel-url-item';
                    tunnelUrlItem.className = 'url-item';
                    tunnelUrlItem.style.backgroundColor = '#e8f5e9';
                    tunnelUrlItem.style.borderColor = '#81c784';
                    tunnelUrlItem.innerHTML = `
                        <div class="label">
                            <strong>🌐 Зовнішній URL:</strong>
                            <a href="${tunnelData.url}" target="_blank">${tunnelData.url}</a>
                        </div>
                    `;
                    urlList.insertBefore(tunnelUrlItem, urlList.firstChild);
                }
            } else {
                connectBtn.textContent = 'Connect';
                connectBtn.disabled = tunnelData.keys_status !== 'ok';

                // Remove tunnel URL from main URL list
                const existingTunnelItem = document.getElementById('tunnel-url-item');
                if (existingTunnelItem) {
                    existingTunnelItem.remove();
                }

                if (tunnelData.error) {
                    errorSection.textContent = 'Error: ' + tunnelData.error;
                    errorSection.style.display = 'block';
                } else {
                    errorSection.style.display = 'none';
                }
            }
        }

        function copyPublicKey() {
            const textarea = document.getElementById('tunnel-public-key');
            const copyBtn = document.getElementById('copy-public-key-btn');

            try {
                // Try modern clipboard API first (works on HTTPS/localhost)
                if (navigator.clipboard && window.isSecureContext) {
                    navigator.clipboard.writeText(textarea.value).then(() => {
                        // Visual feedback
                        const originalText = copyBtn.textContent;
                        copyBtn.textContent = '✅ Copied!';
                        copyBtn.style.background = '#4CAF50';
                        copyBtn.style.color = 'white';

                        setTimeout(() => {
                            copyBtn.textContent = originalText;
                            copyBtn.style.background = '';
                            copyBtn.style.color = '';
                        }, 2000);
                    }).catch(error => {
                        showMessage('Failed to copy: ' + error.message, 'error');
                    });
                } else {
                    // Fallback for non-secure contexts (HTTP over IP)
                    textarea.select();
                    textarea.setSelectionRange(0, 99999); // For mobile devices

                    const successful = document.execCommand('copy');

                    if (successful) {
                        // Visual feedback
                        const originalText = copyBtn.textContent;
                        copyBtn.textContent = '✅ Copied!';
                        copyBtn.style.background = '#4CAF50';
                        copyBtn.style.color = 'white';

                        setTimeout(() => {
                            copyBtn.textContent = originalText;
                            copyBtn.style.background = '';
                            copyBtn.style.color = '';
                        }, 2000);

                        // Deselect
                        window.getSelection().removeAllRanges();
                    } else {
                        showMessage('Failed to copy to clipboard. Please copy manually.', 'error');
                    }
                }
            } catch (error) {
                showMessage('Failed to copy: ' + error.message, 'error');
            }
        }

        async function toggleTunnel() {
            const connectBtn = document.getElementById('tunnel-connect-btn');
            const isConnected = connectBtn.textContent === 'Disconnect';

            try {
                connectBtn.disabled = true;

                const endpoint = isConnected ? '/api/admin/tunnel/disconnect' : '/api/admin/tunnel/connect';

                const response = await fetch(endpoint, {
                    method: 'POST',
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (!response.ok) {
                    throw new Error(data.error || 'Operation failed');
                }

                if (isConnected) {
                    showMessage('Tunnel disconnected', 'success');
                } else {
                    showMessage('Tunnel connected! Public URL: ' + data.url, 'success');
                }

            } catch (error) {
                showMessage('Tunnel operation failed: ' + error.message, 'error');
                connectBtn.disabled = false;
            }
        }

    </script>

</body>
</html>
