<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}TelePush{% endblock %}</title>
    <link href="{{ url_for('static', filename='bootstrap-icons.min.css') }}" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
    <link href="{{ url_for('static', filename='style.css') }}?v={{ config.TELEPUSH_VERSION }}" rel="stylesheet">
    {% block extra_css %}{% endblock %}
    <script>
        // Применяем тему до рендера body — без вспышки.
        (function() {
            try {
                var t = localStorage.getItem('tp_theme') || 'calm';
                if (t === 'amoled' || t === 'light') {
                    document.documentElement.classList.add('theme-' + t);
                }
            } catch(e) {}
        })();
    </script>
    <script>
        // Глобальная сеть ошибок панели: любой необработанный JS-сбой (падение
        // onclick кнопки/галочки, сорванный fetch, проглоченный console.error)
        // + «хлебные крошки» последних действий → /api/report_bug → remote_logs.
        // В <head> ДО app.js — ловит и ошибки самого app.js. Анти-флуд (дедуп+кап),
        // маскировка телефонов/id. Один делегированный слушатель = все кнопки/галочки.
        (function() {
            var sent = 0, seen = {}, crumbs = [], MAXSENT = 25;
            function mask(s) { return String(s).replace(/\d{9,}/g, function(m) { return m.slice(0, 3) + '***'; }); }
            function desc(el) {
                if (!el || el === document || el === window || !el.tagName) return '';
                try {
                    var tag = el.tagName.toLowerCase();
                    var id = el.id ? '#' + el.id : '';
                    var lbl = (el.getAttribute('data-tab') || el.getAttribute('aria-label') || el.getAttribute('title') || el.getAttribute('data-tip') || '');
                    var txt = (el.textContent || '').trim().replace(/\s+/g, ' ').slice(0, 28);
                    var kind = el.type === 'checkbox' ? (el.checked ? '[v]' : '[ ]') : '';
                    return (tag + id + (lbl ? ' "' + lbl + '"' : (txt ? ' "' + txt + '"' : '')) + kind).slice(0, 60);
                } catch(e) { return ''; }
            }
            function push(action, el) {
                var d = desc(el);
                if (!d) return;
                crumbs.push(action + ':' + d);
                if (crumbs.length > 12) crumbs.shift();
            }
            function report(kind, msg) {
                try {
                    var m = mask(msg).slice(0, 360);
                    var key = kind + ':' + m.slice(0, 100);
                    if (seen[key]) return;
                    seen[key] = 1;
                    if (sent >= MAXSENT) return;
                    sent++;
                    var tab = '';
                    try { var a = document.querySelector('.nav-link.active'); tab = a ? (a.getAttribute('data-tab') || '') : ''; } catch(e) {}
                    fetch('/api/report_bug', {
                        method: 'POST', credentials: 'same-origin',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({
                            src: 'panel',
                            text: '[panel-' + kind + '] tab=' + tab + ' ' + m,
                            crumbs: mask(crumbs.join(' > ')).slice(0, 300),
                            url: location.href, ua: navigator.userAgent
                        })
                    }).catch(function() {});
                } catch(e) {}
            }
            window.addEventListener('error', function(e) {
                if (!e || !e.message) return; // пропускаем resource-load ошибки (img/script 404)
                report('error', e.message + (e.filename ? ' @' + String(e.filename).split('/').pop() + ':' + e.lineno : '') + (e.error && e.error.stack ? ' | ' + String(e.error.stack).slice(0, 200) : ''));
            });
            window.addEventListener('unhandledrejection', function(e) {
                var r = e && e.reason;
                report('reject', (r && (r.stack || r.message)) || String(r));
            });
            var _ce = console.error.bind(console);
            console.error = function() {
                try {
                    var a = Array.prototype.slice.call(arguments);
                    var err = a.find(function(x) { return x && x.stack; });
                    if (err) report('console', String(a[0]).slice(0, 60) + ' :: ' + (err.stack || err.message));
                } catch(e) {}
                return _ce.apply(console, arguments);
            };
            document.addEventListener('click', function(e) {
                var t = e.target;
                push('click', (t && t.closest) ? (t.closest('button, a, [onclick], [role=button], .nav-link, label') || t) : t);
            }, true);
            document.addEventListener('change', function(e) {
                var t = e.target;
                if (t && (t.type === 'checkbox' || t.type === 'radio' || t.tagName === 'SELECT')) push('change', t);
            }, true);
            window.__tpReport = report;
        })();
    </script>
</head>
<body>
    <div class="app-layout">
        <!-- Sidebar -->
        <aside class="sidebar" id="sidebar">
            <button id="sidebar-toggle" class="sidebar-toggle-btn" onclick="toggleSidebar()" title="Свернуть/развернуть боковое меню">
                <i class="bi bi-layout-sidebar-inset"></i>
            </button>
            <div class="sidebar-brand">
                <img src="{{ url_for('static', filename='logo.svg') }}" alt="TelePush" style="width:36px;height:36px;">
                <div class="brand-text">
                    <h1>TelePush</h1>
                    <span class="version" id="brand-version" title="">v{{ config.TELEPUSH_VERSION }}</span>
                </div>
            </div>

            <nav class="sidebar-nav">
                <ul style="list-style:none;padding:0;">
                    <!-- «Аналитика» перенесена в раздел «Настройки». -->
                    <li class="nav-section">Аккаунты</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="accounts" onclick="showTab('accounts')">
                            <i class="bi bi-phone"></i> Менеджер аккаунтов
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="proxy" onclick="showTab('proxy')">
                            <i class="bi bi-shield-lock"></i> Прокси
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="profiles" onclick="showTab('profiles')">
                            <i class="bi bi-person-badge"></i> Заполнение профилей
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="reauth" onclick="showTab('reauth')">
                            <i class="bi bi-arrow-repeat"></i> Переавторизация
                        </a>
                    </li>

                    <li class="nav-section">Рассылка</li>
                    <li class="nav-item">
                        <a class="nav-link active" data-tab="spam" onclick="showTab('spam')">
                            <i class="bi bi-megaphone"></i> По чатам
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="dm" onclick="showTab('dm')">
                            <i class="bi bi-person-lines-fill"></i> По ЛС
                        </a>
                    </li>
                    <!-- Прогревовые шаблоны — настройка во вкладке «Прогрев». -->
                    <!-- Автоответчик доступен как подсекция вкладки «По ЛС». -->

                    <li class="nav-section">Подписка / инвайт</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="join" onclick="showTab('join')">
                            <i class="bi bi-box-arrow-in-right"></i> Вступление
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="invite" onclick="showTab('invite')">
                            <i class="bi bi-person-plus"></i> Инвайт
                        </a>
                    </li>
                    <li class="nav-section">Парсинг и мониторинг</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="parser" onclick="showTab('parser')">
                            <i class="bi bi-search"></i> Парсинг
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="monitor" onclick="showTab('monitor')">
                            <i class="bi bi-broadcast"></i> Мониторинг
                        </a>
                    </li>

                    <li class="nav-section">AI-инструменты</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="warmup" onclick="showTab('warmup')">
                            <i class="bi bi-fire"></i> Прогрев
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="stories" onclick="showTab('stories')">
                            <i class="bi bi-camera-reels"></i> Истории
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="neuro-comments" onclick="showTab('neuro-comments')">
                            <i class="bi bi-chat-quote"></i> Нейрокомменты
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="chatter" onclick="showTab('chatter')">
                            <i class="bi bi-chat-dots"></i> Нейро-чаттер
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="imitation" onclick="showTab('imitation')">
                            <i class="bi bi-person-walking"></i> Имитация активности
                        </a>
                    </li>

                    <li class="nav-section">Накрутка</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="boost" onclick="showTab('boost')">
                            <i class="bi bi-graph-up-arrow"></i> Накрутка
                        </a>
                    </li>

                    <li class="nav-section">Чекер</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="checker" onclick="showTab('checker')">
                            <i class="bi bi-shield-check"></i> Чекер аккаунтов
                        </a>
                    </li>

                    <li class="nav-section">Очистка</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="cleanup" onclick="showTab('cleanup')">
                            <i class="bi bi-eraser"></i> Очистка ТГ
                        </a>
                    </li>

                    <li class="nav-section">Конвертеры</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="conv-t2s" onclick="showTab('conv-t2s')">
                            <i class="bi bi-file-earmark-arrow-down"></i> tdata → session
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="conv-s2t" onclick="showTab('conv-s2t')">
                            <i class="bi bi-file-earmark-arrow-up"></i> session → tdata
                        </a>
                    </li>

                    <li class="nav-section">Настройки</li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="settings" onclick="showTab('settings')">
                            <i class="bi bi-gear"></i> Настройки
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="analytics" onclick="showTab('analytics')">
                            <i class="bi bi-graph-up"></i> Аналитика
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="guide" onclick="showTab('guide')">
                            <i class="bi bi-book"></i> Инструкция
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="profile" onclick="showTab('profile')">
                            <i class="bi bi-person-badge"></i> Профиль
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-tab="support" onclick="showTab('support')">
                            <i class="bi bi-life-preserver"></i> Поддержка
                        </a>
                    </li>

                </ul>
            </nav>

            <!-- Sidebar footer -->
            <div style="padding:16px 20px;border-top:1px solid var(--border);font-size:0.75rem;color:var(--text-muted);">
                <div class="d-flex align-center justify-between" style="margin-bottom:8px;">
                    <span><span class="pulse-dot"></span> Онлайн</span>
                    <a onclick="showTab('support')" style="color:var(--accent-light);cursor:pointer;text-decoration:none;">
                        <i class="bi bi-headset"></i> Поддержка
                    </a>
                </div>
                <button onclick="openLogsWindow()" class="btn btn-outline btn-sm" id="open-logs-btn" style="width:100%;font-size:0.72rem;position:relative;display:flex;align-items:center;justify-content:center;gap:6px;">
                    <i class="bi bi-terminal"></i> <span>Открыть логи</span>
                    <span id="logs-badge" style="display:none;background:#ef4444;color:#fff;font-size:0.62rem;font-weight:700;padding:1px 6px;border-radius:9px;line-height:1.4;font-variant-numeric:tabular-nums;box-shadow:0 0 8px rgba(239,68,68,0.45);">0</span>
                </button>
                <div id="logs-badge-hint" style="display:none;font-size:0.65rem;color:var(--text-muted);margin-top:6px;line-height:1.4;text-align:center;">
                    <i class="bi bi-arrow-up" style="color:#ef4444;"></i>
                    <span id="logs-badge-hint-text">Новые ошибки/предупреждения</span>
                </div>
            </div>
        </aside>

        <!-- Main -->
        <main class="main-content">
            <!-- Topbar — Ctrl+K поиск + последние действия + AI помощник. -->
            <div id="tp-topbar" style="display:flex;align-items:center;gap:8px;margin:0 0 10px;padding:5px 8px;background:var(--bg-card);border:1px solid var(--border);border-radius:8px;">
                <button onclick="openGlobalSearch()" data-tip="Глобальный поиск (Ctrl+K)" style="display:flex;align-items:center;gap:8px;background:transparent;border:1px solid var(--border);border-radius:7px;padding:5px 10px;color:var(--text-muted);cursor:pointer;font-size:0.76rem;min-width:220px;">
                    <i class="bi bi-search"></i>
                    <span>Поиск или команда…</span>
                    <span style="margin-left:auto;font-size:0.66rem;background:var(--bg);padding:1px 5px;border-radius:4px;border:1px solid var(--border);">Ctrl+K</span>
                </button>
                <div id="topbar-recent" style="flex:1;font-size:0.76rem;color:var(--text-muted);cursor:pointer;padding:5px 10px;border-radius:7px;border:1px solid var(--border);background:transparent;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" onclick="toggleRecentActivity()" data-tip="Последние действия (клик — история)">
                    <i class="bi bi-activity"></i> <span id="topbar-recent-text">Загрузка…</span>
                </div>
                <button id="tp-ai-btn" onclick="toggleAiChat()" data-tip="AI помощник" style="background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;border:none;border-radius:7px;padding:5px 12px;cursor:pointer;font-size:0.76rem;display:flex;align-items:center;gap:6px;">
                    <i class="bi bi-stars"></i> AI
                </button>
            </div>

            <!-- Broadcast announcement баннер от админа -->
            <div id="broadcast-banner" style="display:none;border-radius:12px;padding:14px 18px;margin:0 0 16px;border:1px solid;">
                <div style="display:flex;align-items:flex-start;gap:12px;">
                    <i id="broadcast-icon" class="bi" style="font-size:1.4rem;flex-shrink:0;"></i>
                    <div style="flex:1;">
                        <div id="broadcast-title" style="font-size:0.92rem;font-weight:700;margin-bottom:4px;"></div>
                        <div id="broadcast-text" style="font-size:0.82rem;line-height:1.55;white-space:pre-wrap;"></div>
                    </div>
                    <button onclick="dismissBroadcast()" style="background:transparent;border:none;color:inherit;font-size:1.1rem;cursor:pointer;opacity:0.7;flex-shrink:0;" title="Скрыть до следующего сообщения">×</button>
                </div>
            </div>

            <!-- Temp launch warning (только если exe реально из архива) -->
            <div id="temp-launch-banner" style="display:none;background:linear-gradient(135deg,#2a0d14,#3b1c1c);border:2px solid #ef4444;border-radius:12px;padding:16px 20px;margin:0 0 16px;">
                <div style="display:flex;align-items:flex-start;gap:12px;">
                    <i class="bi bi-exclamation-triangle-fill" style="color:#ef4444;font-size:1.6rem;flex-shrink:0;"></i>
                    <div style="flex:1;">
                        <div style="font-size:0.95rem;font-weight:700;color:#fca5a5;margin-bottom:6px;">
                            Программа запущена из временной папки архива!
                        </div>
                        <div style="font-size:0.78rem;color:#fecaca;line-height:1.55;margin-bottom:8px;">
                            Текущая папка: <code id="temp-launch-path" style="background:rgba(0,0,0,0.3);padding:2px 6px;border-radius:4px;font-size:0.72rem;word-break:break-all;"></code>
                        </div>
                        <div style="font-size:0.82rem;color:#fff;line-height:1.7;">
                            Распакуй архив в постоянную папку (например <code style="background:rgba(0,0,0,0.3);padding:1px 4px;border-radius:3px;">C:\TelePush\</code>) и запусти TelePush.exe оттуда — иначе при закрытии архива все данные пропадут.
                        </div>
                    </div>
                </div>
            </div>

            <!-- Баннер обновления лаунчера: показывается при лаунчере < 2.1.6
                 (авто-update лаунчера на сервере отключён из-за зацикливаний). -->
            <div class="update-banner" id="launcher-update-banner" style="display:none;background:linear-gradient(135deg,#0a1d3b,#0d2a4f);border:1px solid #2563eb;">
                <div>
                    <i class="bi bi-arrow-up-circle" style="color:#60a5fa;margin-right:6px;"></i>
                    <strong>Новая версия лаунчера</strong>
                    <span style="font-size:0.75rem;color:var(--text-muted);margin-left:8px;">Спрашивает «установить обновление?» перед скачиванием</span>
                </div>
                <div style="display:flex;gap:8px;align-items:center;flex-wrap:nowrap;">
                    <a href="https://telepush.org/api/download/launcher" target="_blank" rel="noopener"
                       class="btn btn-success btn-sm"
                       style="text-decoration:none;">
                        <i class="bi bi-download"></i> Скачать
                    </a>
                    <button class="btn btn-outline btn-sm" onclick="dismissLauncherBanner()" style="font-size:0.72rem;">
                        Позже
                    </button>
                </div>
            </div>

            <!-- Update banner (hidden by default) -->
            <div class="update-banner" id="update-banner" style="display:none;">
                <div>
                    <i class="bi bi-arrow-up-circle" style="color:var(--success);margin-right:6px;"></i>
                    <strong>Доступно обновление</strong> <span id="update-version" style="color:var(--success);font-weight:700;"></span>
                    <span id="update-changelog" style="font-size:0.75rem;color:var(--text-muted);margin-left:8px;"></span>
                </div>
                <div style="display:flex;gap:8px;align-items:center;flex-wrap:nowrap;">
                    <button class="btn btn-success btn-sm" onclick="installUpdate()">
                        <i class="bi bi-download"></i> Обновить
                    </button>
                    <a href="https://telepush.org/api/download?v=latest" target="_blank" rel="noopener"
                       title="Если автообновление не работает — скачай zip вручную и распакуй поверх папки TelePush (папку data/ не трогай)"
                       style="font-size:0.72rem;color:var(--text-muted);text-decoration:underline;white-space:nowrap;">
                        или скачать вручную
                    </a>
                </div>
            </div>

            <!-- Drag-and-drop overlay для ручного обновления: клиент бросает
                 скачанный ZIP в окно, лаунчер установит при следующем запуске. -->
            <div id="update-dropzone" style="display:none;position:fixed;inset:0;z-index:9998;background:rgba(124,58,237,0.18);backdrop-filter:blur(8px);align-items:center;justify-content:center;pointer-events:none;">
                <div style="background:linear-gradient(135deg,#1a0d2e,#2d1554);border:2px dashed #a78bfa;border-radius:20px;padding:48px 64px;text-align:center;box-shadow:0 0 40px rgba(167,139,250,0.4);">
                    <i class="bi bi-arrow-down-circle" style="font-size:64px;color:#a78bfa;display:block;margin-bottom:16px;"></i>
                    <div style="font-size:1.4rem;font-weight:700;color:#fff;margin-bottom:8px;">Брось ZIP сюда</div>
                    <div style="font-size:0.85rem;color:#c4b5fd;">TelePush_X.Y.Z.zip — лаунчер установит при перезапуске</div>
                </div>
            </div>

            <!-- Expired license banner (hidden by default) -->
            <div id="expired-banner" style="display:none;background:linear-gradient(135deg,#1c0f0f,#2a1010);border:1px solid #3b1c1c;border-radius:12px;padding:20px 24px;margin:0 0 16px;text-align:center;">
                <div style="font-size:1.8rem;margin-bottom:8px;color:#ff7b7b;"><i class="bi bi-lock-fill"></i></div>
                <div style="font-size:1.05rem;font-weight:700;color:#f87171;margin-bottom:6px;">Срок лицензии истёк</div>
                <div style="font-size:0.82rem;color:#9ca3af;margin-bottom:16px;">Модули заблокированы. Продлите ключ для продолжения работы.</div>
                <div style="margin-bottom:12px;">
                    <input type="text" id="renew-tg-username" class="form-control" placeholder="Ваш @username в Telegram" style="max-width:280px;margin:0 auto;text-align:center;font-size:0.82rem;">
                </div>
                <div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap;">
                    <button class="btn btn-outline btn-sm" onclick="recheckLicense()" id="btn-recheck">
                        <i class="bi bi-arrow-clockwise"></i> Перепроверить
                    </button>
                    <button class="btn btn-accent btn-sm" onclick="requestRenewal()" id="btn-renew">
                        <i class="bi bi-key"></i> Запросить продление
                    </button>
                    <a href="https://t.me/TP_supports" target="_blank" class="btn btn-outline btn-sm" style="text-decoration:none;">
                        <i class="bi bi-telegram"></i> Написать в поддержку
                    </a>
                </div>
                <div style="margin-top:10px;font-size:0.72rem;color:var(--text-muted);">
                    «Перепроверить» — заставит софт заново спросить сервер. Если ключ только что продлили — обычно помогает.
                </div>
                <div id="renew-result" style="margin-top:10px;font-size:0.82rem;display:none;"></div>
            </div>

            {% block content %}{% endblock %}
        </main>
    </div>


        <!-- Глобальная statusbar внизу: что софт делает прямо сейчас. -->
        <div id="tp-statusbar" style="position:fixed;bottom:0;left:0;right:0;height:28px;background:rgba(20,20,30,0.96);border-top:1px solid var(--border);display:flex;align-items:center;gap:14px;padding:0 14px;font-size:0.7rem;color:var(--text-muted);z-index:90;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);">
            <span id="sb-conn-dot" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--success);" title="Соединение с сервером"></span>
            <span id="sb-jobs" style="white-space:nowrap;">Загрузка...</span>
            <span style="opacity:0.4;">·</span>
            <span id="sb-accounts" style="white-space:nowrap;"></span>
            <span style="opacity:0.4;">·</span>
            <span id="sb-proxies" style="white-space:nowrap;"></span>
            <span style="flex:1;"></span>
            <span id="sb-version" style="opacity:0.65;font-family:'JetBrains Mono',monospace;font-size:0.65rem;">v—</span>
            <span style="opacity:0.4;">·</span>
            <span id="sb-hwid" style="opacity:0.6;font-family:'JetBrains Mono',monospace;font-size:0.65rem;" title="HWID этого ПК — для саппорта"></span>
        </div>
        <!-- Padding снизу для main чтобы statusbar не перекрывал последние карточки -->
        <style>.main-content { padding-bottom: 36px; }</style>

        <!-- Onboarding Overlay -->
        <div id="onboarding-overlay" class="onboarding-overlay hidden">
            <div class="onboarding-overlay__card">
                <div id="onboarding-content"></div>
            </div>
        </div>

        <!-- Telegram Messenger Panel -->
        <div id="tg-panel" style="position:fixed;top:0;right:-420px;width:420px;height:100vh;background:var(--bg-card);border-left:1px solid var(--border);z-index:200;transition:right 0.3s ease;display:flex;flex-direction:column;">
            <!-- Header -->
            <div id="tg-header" style="padding:10px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;min-height:48px;">
                <button id="tg-back-btn" onclick="loadTgDialogs()" style="display:none;background:none;border:none;color:var(--accent-light);cursor:pointer;font-size:1rem;padding:4px;"><i class="bi bi-arrow-left"></i></button>
                <i class="bi bi-telegram" id="tg-header-icon" style="color:#229ED9;font-size:1.1rem;"></i>
                <div style="flex:1;min-width:0;">
                    <div id="tg-header-title" style="font-weight:600;font-size:0.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">Telegram</div>
                    <div id="tg-header-sub" style="font-size:0.65rem;color:var(--text-muted);display:none;"></div>
                </div>
                <button id="tg-info-btn" onclick="showTgUserInfo()" style="display:none;background:none;border:none;color:var(--accent-light);cursor:pointer;font-size:1rem;padding:4px;" title="Информация"><i class="bi bi-info-circle"></i></button>
                <button onclick="toggleTgPanel()" style="background:none;border:none;color:#64748b;cursor:pointer;font-size:1rem;"><i class="bi bi-x-lg"></i></button>
            </div>
            <!-- Tabs -->
            <div id="tg-tabs" style="display:flex;border-bottom:1px solid var(--border);">
                <button class="tg-tab active" onclick="tgShowTab(this,'chats')" style="flex:1;padding:8px;background:none;border:none;color:#a78bfa;font-size:0.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid #7c3aed;">Чаты</button>
                <button class="tg-tab" onclick="tgShowTab(this,'replies')" style="flex:1;padding:8px;background:none;border:none;color:#64748b;font-size:0.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid transparent;">Входящие</button>
                <button class="tg-tab" onclick="tgShowTab(this,'log')" style="flex:1;padding:8px;background:none;border:none;color:#64748b;font-size:0.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid transparent;">Лог</button>
            </div>
            <!-- Warning -->
            <div style="padding:8px 12px;background:var(--surface-warning-bg);border-bottom:1px solid var(--surface-warning-border);font-size:0.68rem;color:var(--warning);line-height:1.4;">
                <i class="bi bi-exclamation-triangle" style="margin-right:4px;"></i>
                Не открывайте Telegram на этом же аккаунте (ни на телефоне, ни в десктопе) пока идёт работа — сессия может быть разорвана.
            </div>
            <!-- Content -->
            <div id="tg-chats" style="flex:1;overflow-y:auto;display:flex;flex-direction:column;"></div>
            <div id="tg-replies" style="flex:1;overflow-y:auto;padding:8px;display:none;"></div>
            <div id="tg-log" style="flex:1;overflow-y:auto;padding:8px;font-family:monospace;font-size:0.72rem;color:#64748b;display:none;"></div>
        </div>

    <!-- Show console button (when hidden) -->
    <div class="toast-container" id="toast-container"></div>

    <script src="{{ url_for('static', filename='app.js') }}?v={{ config.TELEPUSH_VERSION }}"></script>
    <script src="{{ url_for('static', filename='lib/gsap.min.js') }}"></script>
    <script src="{{ url_for('static', filename='gsap-enhance.js') }}?v={{ config.TELEPUSH_VERSION }}"></script>

<script>
// Консоль логов вынесена в отдельное окно (openLogsWindow). Старые
// addLog/setConsoleFilter/clearConsole/toggleConsole оставлены как no-op
// заглушки — на них завязано ~30 вызовов в app.js.
function addLog() { /* stub — логи в отдельном окне */ }
function setConsoleFilter() {}
function clearConsole() {}
function toggleConsole() { openLogsWindow(); }
function startConsoleDrag() {}
function _bumpTabBadge() {}

// Drag-and-drop ZIP обновления.
(function() {
    var dz = null;
    var dragCount = 0;
    function show() {
        if (!dz) dz = document.getElementById('update-dropzone');
        if (dz) { dz.style.display = 'flex'; dz.style.pointerEvents = 'auto'; }
    }
    function hide() {
        if (!dz) dz = document.getElementById('update-dropzone');
        if (dz) { dz.style.display = 'none'; dz.style.pointerEvents = 'none'; }
        dragCount = 0;
    }
    window.addEventListener('dragenter', function(e) {
        if (!e.dataTransfer || !e.dataTransfer.types) return;
        var hasFiles = false;
        for (var i = 0; i < e.dataTransfer.types.length; i++) {
            if (e.dataTransfer.types[i] === 'Files') { hasFiles = true; break; }
        }
        if (!hasFiles) return;
        e.preventDefault();
        dragCount++;
        show();
    });
    window.addEventListener('dragleave', function(e) {
        e.preventDefault();
        dragCount--;
        if (dragCount <= 0) hide();
    });
    window.addEventListener('dragover', function(e) {
        e.preventDefault();
    });
    window.addEventListener('drop', function(e) {
        e.preventDefault();
        hide();
        if (!e.dataTransfer || !e.dataTransfer.files || !e.dataTransfer.files.length) return;
        var file = e.dataTransfer.files[0];
        if (!file.name.toLowerCase().endsWith('.zip')) {
            if (typeof showToast === 'function') showToast('Нужен ZIP-архив TelePush', 'warning');
            return;
        }
        var sizeMB = (file.size / 1048576).toFixed(1);
        if (typeof showToast === 'function') showToast('Загружаю ' + file.name + ' (' + sizeMB + ' MB)...', 'info');
        var fd = new FormData();
        fd.append('file', file);
        fetch('/api/update/upload_zip', {method: 'POST', body: fd, credentials: 'same-origin'})
            .then(function(r) { return r.json(); })
            .then(function(d) {
                if (d.ok) {
                    if (typeof showToast === 'function') showToast(d.msg || 'Готово, перезапусти TelePush', 'success');
                } else {
                    if (typeof showToast === 'function') showToast(d.error || 'Не удалось сохранить', 'error');
                }
            })
            .catch(function(e) {
                if (typeof showToast === 'function') showToast('Ошибка загрузки: ' + e, 'error');
            });
    });
})();

function _resetLogsBadge() {
    // Сброс бейджа: запомнить max_id текущего буфера, чтобы счётчик пошёл с нуля
    try {
        var _badgeMaxId = parseInt(window._logsBadgeMaxId || 0);
        if (_badgeMaxId > 0) {
            localStorage.setItem('logs_last_seen_id', String(_badgeMaxId));
        }
        var _b = document.getElementById('logs-badge');
        var _h = document.getElementById('logs-badge-hint');
        if (_b) _b.style.display = 'none';
        if (_h) _h.style.display = 'none';
    } catch(e) {}
}

function openLogsWindow() {
    _resetLogsBadge();
    // Надёжный путь — показываем логи В ТЕКУЩЕМ окне (оно точно рендерится: юзер
    // же видит панель). Отдельное pywebview-окно на части машин (Windows Server /
    // RDP-сессии, WebView2 без вторичных окон) молча не появляется: create_window
    // не кидает исключение, opened=true, а окна нет → клик «впустую». Модалка-iframe
    // на /logs переиспользует ту же страницу логов и работает везде.
    var ov = document.getElementById('logs-modal-overlay');
    var fr = document.getElementById('logs-modal-iframe');
    if (!ov || !fr) {
        // Разметки нет (старая страница) — деградируем к отдельному окну.
        popOutLogsWindow();
        return;
    }
    if (!fr.getAttribute('src')) fr.setAttribute('src', '/logs');
    ov.style.display = 'flex';
}

function closeLogsModal() {
    var ov = document.getElementById('logs-modal-overlay');
    if (ov) ov.style.display = 'none';
}

// Попытка вынести логи в ОТДЕЛЬНОЕ окно (для машин где WebView2 это умеет).
// Модалку НЕ закрываем автоматически по opened=true: на проблемных машинах окно
// не появляется при opened=true, и авто-закрытие снова оставило бы юзера ни с чем.
function popOutLogsWindow() {
    _resetLogsBadge();
    fetch('/api/logs/open_window', { method: 'POST', credentials: 'same-origin' })
        .then(function(r) { return r.json(); })
        .then(function(d) {
            // Fallback: если pywebview не подхватил (запуск через браузер) —
            // открываем во вкладке.
            if (d && !d.opened && d.url) {
                window.open(d.url, 'TelePushLogs',
                    'width=960,height=620,menubar=no,toolbar=no,location=no,status=no');
            }
        })
        .catch(function() {});
}

// Бейдж WARN/ERROR на кнопке логов = новые WARN+ERROR с момента
// последнего открытия окна логов.
var _logsBadgeBootToken = null;
function pollLogsBadge() {
    if (document.hidden) return;  // окно скрыто — бейдж логов подождёт
    var since = parseInt(localStorage.getItem('logs_last_seen_id') || '0');
    fetch('/api/logs/warn_count?since=' + since, { credentials: 'same-origin' })
        .then(function(r) { return r.json(); })
        .then(function(d) {
            if (!d) return;
            // Перезапуск сервера → boot изменился → буфер очищен → сбрасываем
            // last_seen чтобы не считали отрицательные дельты.
            if (d.boot) {
                if (_logsBadgeBootToken === null) {
                    _logsBadgeBootToken = d.boot;
                } else if (_logsBadgeBootToken !== d.boot) {
                    _logsBadgeBootToken = d.boot;
                    localStorage.setItem('logs_last_seen_id', '0');
                }
            }
            window._logsBadgeMaxId = d.max_id || 0;
            var w = d.warn || 0;
            var e = d.err || 0;
            var total = w + e;
            var b = document.getElementById('logs-badge');
            var h = document.getElementById('logs-badge-hint');
            var ht = document.getElementById('logs-badge-hint-text');
            if (!b) return;
            if (total > 0) {
                b.textContent = total > 99 ? '99+' : String(total);
                b.style.display = 'inline-block';
                b.style.background = e > 0 ? '#ef4444' : '#f59e0b';
                b.style.boxShadow = e > 0
                    ? '0 0 8px rgba(239,68,68,0.45)'
                    : '0 0 8px rgba(245,158,11,0.4)';
                if (h) h.style.display = 'block';
                if (ht) {
                    if (e > 0 && w > 0) ht.textContent = e + ' ошиб., ' + w + ' предупр.';
                    else if (e > 0) ht.textContent = e === 1 ? '1 новая ошибка' : e + ' новых ошибок';
                    else ht.textContent = w === 1 ? '1 предупреждение' : w + ' предупреждений';
                }
            } else {
                b.style.display = 'none';
                if (h) h.style.display = 'none';
            }
        })
        .catch(function() {});
}
// Стартуем poll через 2с после загрузки (даём UI прогреться), затем каждые 4с
setTimeout(function() {
    pollLogsBadge();
    setInterval(pollLogsBadge, 4000);
}, 2000);
</script>

<!-- Окно логов внутри текущего окна. Надёжно на любом WebView2 — отдельное
     pywebview-окно на части машин (Windows Server / RDP) не появляется. -->
<div id="logs-modal-overlay" onclick="if(event.target===this)closeLogsModal()"
     style="display:none;position:fixed;inset:0;z-index:9000;background:rgba(3,3,9,0.72);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);align-items:center;justify-content:center;padding:24px;">
    <div style="width:min(1100px,96vw);height:min(86vh,820px);display:flex;flex-direction:column;background:#07070d;border:1px solid rgba(139,92,246,0.28);border-radius:14px;overflow:hidden;box-shadow:0 24px 80px rgba(0,0,0,0.6);">
        <div style="display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid rgba(139,92,246,0.16);background:rgba(12,12,20,0.6);flex-shrink:0;">
            <span style="display:inline-flex;align-items:center;gap:8px;font-size:0.82rem;font-weight:700;color:#e2e8f0;">
                <i class="bi bi-terminal-fill" style="color:#c4b5fd;"></i> Логи работы
            </span>
            <div style="margin-left:auto;display:flex;gap:6px;">
                <button onclick="popOutLogsWindow()" title="Вынести в отдельное окно (если поддерживается)"
                        style="display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);color:#94a3b8;border-radius:7px;padding:5px 10px;font-size:0.72rem;cursor:pointer;">
                    <i class="bi bi-box-arrow-up-right"></i><span>Отдельное окно</span>
                </button>
                <button onclick="closeLogsModal()" title="Закрыть (Esc)"
                        style="display:inline-flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);color:#cbd5e1;border-radius:7px;width:30px;height:30px;cursor:pointer;font-size:0.85rem;">
                    <i class="bi bi-x-lg"></i>
                </button>
            </div>
        </div>
        <iframe id="logs-modal-iframe" title="Логи" style="flex:1;width:100%;border:0;background:#050509;"></iframe>
    </div>
</div>
<script>
document.addEventListener('keydown', function(e) {
    if (e.key === 'Escape') {
        var ov = document.getElementById('logs-modal-overlay');
        if (ov && ov.style.display !== 'none') closeLogsModal();
    }
});
</script>

{% block extra_js %}{% endblock %}
</body>
</html>
