{% extends "base.html" %}

{% block title %}Panel bezpieczeństwa - Admin{% endblock %}

{% block extra_css %}
<style>
    .security-header {
        margin-bottom: var(--spacing-xl);
    }

    .security-header h1 {
        font-size: var(--font-size-2xl);
        color: var(--text-primary);
        margin-bottom: var(--spacing-xs);
    }

    .security-header p {
        color: var(--text-secondary);
    }

    .stats-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: var(--spacing-lg);
        margin-bottom: var(--spacing-xl);
    }

    .stat-card {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        padding: var(--spacing-lg);
        text-align: center;
    }

    .stat-card.alert {
        border-color: #fcd34d;
        background: #fffbeb;
    }

    .stat-card.danger {
        border-color: #fca5a5;
        background: #fef2f2;
    }

    .stat-value {
        font-size: var(--font-size-3xl);
        font-weight: 700;
        color: var(--text-primary);
    }

    .stat-label {
        font-size: var(--font-size-sm);
        color: var(--text-secondary);
        margin-top: var(--spacing-xs);
    }

    .section {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        padding: var(--spacing-xl);
        margin-bottom: var(--spacing-xl);
    }

    .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: var(--spacing-lg);
        padding-bottom: var(--spacing-md);
        border-bottom: 1px solid var(--border);
    }

    .section-header h2 {
        font-size: var(--font-size-lg);
        color: var(--text-primary);
        margin: 0;
    }

    .data-table {
        width: 100%;
        border-collapse: collapse;
    }

    .data-table th {
        text-align: left;
        padding: var(--spacing-sm) var(--spacing-md);
        background: var(--background);
        font-weight: 600;
        font-size: var(--font-size-sm);
        color: var(--text-secondary);
        border-bottom: 1px solid var(--border);
    }

    .data-table td {
        padding: var(--spacing-sm) var(--spacing-md);
        border-bottom: 1px solid var(--border);
        font-size: var(--font-size-sm);
    }

    .data-table tr:last-child td {
        border-bottom: none;
    }

    .badge {
        display: inline-block;
        padding: 2px 8px;
        border-radius: var(--radius);
        font-size: var(--font-size-xs);
        font-weight: 500;
    }

    .badge-new {
        background: #fee2e2;
        color: #991b1b;
    }

    .badge-acknowledged {
        background: #fef3c7;
        color: #92400e;
    }

    .badge-resolved {
        background: #dcfce7;
        color: #166534;
    }

    .badge-low {
        background: #e0e7ff;
        color: #3730a3;
    }

    .badge-medium {
        background: #fef3c7;
        color: #92400e;
    }

    .badge-high {
        background: #fee2e2;
        color: #991b1b;
    }

    .badge-critical {
        background: #7f1d1d;
        color: white;
    }

    .btn-sm {
        padding: var(--spacing-xs) var(--spacing-sm);
        font-size: var(--font-size-xs);
        border: none;
        border-radius: var(--radius);
        cursor: pointer;
        text-decoration: none;
    }

    .btn-primary {
        background: var(--primary);
        color: white;
    }

    .btn-secondary {
        background: var(--background);
        color: var(--text-primary);
        border: 1px solid var(--border);
    }

    .btn-danger {
        background: var(--error);
        color: white;
    }

    .action-buttons {
        display: flex;
        gap: var(--spacing-xs);
    }

    .empty-state {
        text-align: center;
        padding: var(--spacing-xl);
        color: var(--text-secondary);
    }

    .ip-address {
        font-family: monospace;
        font-size: var(--font-size-xs);
        background: var(--background);
        padding: 2px 6px;
        border-radius: var(--radius);
    }

    .timestamp {
        font-size: var(--font-size-xs);
        color: var(--text-secondary);
    }

    .alert-type {
        text-transform: uppercase;
        font-size: var(--font-size-xs);
        font-weight: 600;
    }

    .locked-row {
        background: #fef2f2;
    }

    .tabs {
        display: flex;
        gap: var(--spacing-md);
        margin-bottom: var(--spacing-lg);
        border-bottom: 1px solid var(--border);
        padding-bottom: var(--spacing-md);
    }

    .tab {
        padding: var(--spacing-sm) var(--spacing-md);
        border: none;
        background: none;
        color: var(--text-secondary);
        cursor: pointer;
        font-size: var(--font-size-sm);
        font-weight: 500;
        border-radius: var(--radius);
    }

    .tab.active {
        background: var(--primary);
        color: white;
    }

    .tab-content {
        display: none;
    }

    .tab-content.active {
        display: block;
    }

    /* Security mechanisms styles */
    .mechanisms-list {
        display: flex;
        flex-direction: column;
        gap: var(--spacing-md);
    }

    .mechanism-item {
        display: flex;
        align-items: center;
        gap: var(--spacing-lg);
        padding: var(--spacing-md) var(--spacing-lg);
        background: var(--background);
        border-radius: var(--radius);
        border-left: 4px solid transparent;
    }

    .mechanism-item.stars-5 { border-left-color: #22c55e; }
    .mechanism-item.stars-4 { border-left-color: #3b82f6; }
    .mechanism-item.stars-3 { border-left-color: #f59e0b; }

    .mechanism-stars {
        font-size: 1rem;
        color: #fbbf24;
        min-width: 100px;
        letter-spacing: 2px;
    }

    .mechanism-name {
        flex: 1;
        font-weight: 500;
        color: var(--text-primary);
    }

    .mechanism-desc {
        flex: 2;
        font-size: var(--font-size-sm);
        color: var(--text-secondary);
    }

    .mechanism-status {
        font-size: var(--font-size-xs);
        padding: 2px 8px;
        border-radius: var(--radius);
        font-weight: 500;
    }

    .mechanism-status.active {
        background: #dcfce7;
        color: #166534;
    }

    .mechanism-status.inactive {
        background: #fee2e2;
        color: #991b1b;
    }

    /* GeoIP stats */
    .geoip-stats {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
        gap: var(--spacing-md);
        margin-bottom: var(--spacing-xl);
    }

    .geoip-stat {
        background: var(--background);
        padding: var(--spacing-lg);
        border-radius: var(--radius);
        text-align: center;
    }

    .geoip-stat-value {
        font-size: var(--font-size-2xl);
        font-weight: 700;
        color: var(--text-primary);
    }

    .geoip-stat-label {
        font-size: var(--font-size-xs);
        color: var(--text-secondary);
        margin-top: var(--spacing-xs);
    }

    .country-breakdown {
        display: flex;
        flex-wrap: wrap;
        gap: var(--spacing-sm);
        margin-top: var(--spacing-lg);
    }

    .country-badge {
        display: inline-flex;
        align-items: center;
        gap: var(--spacing-xs);
        padding: var(--spacing-xs) var(--spacing-md);
        background: var(--background);
        border-radius: var(--radius);
        font-size: var(--font-size-sm);
    }

    .country-flag {
        font-size: 1.2em;
    }

    .country-count {
        font-weight: 600;
        color: var(--text-primary);
    }
</style>
{% endblock %}

{% block content %}
<div class="security-header">
    <h1>🛡️ Panel bezpieczeństwa</h1>
    <p>Monitoring alertów, audit log i zarządzanie bezpieczeństwem</p>
</div>

<!-- Stats -->
<div class="stats-grid">
    <div class="stat-card {% if stats.new_alerts > 0 %}alert{% endif %}">
        <div class="stat-value">{{ stats.new_alerts }}</div>
        <div class="stat-label">Nowe alerty</div>
    </div>
    <div class="stat-card {% if stats.locked_accounts > 0 %}danger{% endif %}">
        <div class="stat-value">{{ stats.locked_accounts }}</div>
        <div class="stat-label">Zablokowane konta</div>
    </div>
    <div class="stat-card">
        <div class="stat-value">{{ stats.users_with_2fa }}/{{ stats.total_admins }}</div>
        <div class="stat-label">Admini z 2FA</div>
    </div>
    <div class="stat-card">
        <div class="stat-value">{{ stats.alert_breakdown.values()|sum if stats.alert_breakdown else 0 }}</div>
        <div class="stat-label">Wszystkie alerty</div>
    </div>
</div>

<!-- Tabs -->
<div class="tabs">
    <button class="tab active" onclick="showTab('mechanisms')">Mechanizmy</button>
    <button class="tab" onclick="showTab('geoip')">GeoIP</button>
    <button class="tab" onclick="showTab('alerts')">Alerty</button>
    <button class="tab" onclick="showTab('audit')">Audit log</button>
    <button class="tab" onclick="showTab('locked')">Zablokowane konta</button>
</div>

<!-- Mechanisms Tab -->
<div id="tab-mechanisms" class="tab-content active">
    <div class="section">
        <div class="section-header">
            <h2>🔐 Mechanizmy bezpieczeństwa</h2>
        </div>
        <p style="color: var(--text-secondary); margin-bottom: var(--spacing-lg);">
            Lista wszystkich aktywnych mechanizmów ochrony systemu, posortowana według ważności (5★ = krytyczne).
        </p>

        <div class="mechanisms-list">
            <!-- 5 stars - CRITICAL -->
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Uwierzytelnianie dwuskładnikowe (2FA)</span>
                <span class="mechanism-desc">TOTP przez aplikacje mobilne (Google/Microsoft Authenticator)</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Ochrona przed CSRF</span>
                <span class="mechanism-desc">Tokeny CSRF w formularzach (Flask-WTF)</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Szyfrowanie połączeń (HTTPS/TLS)</span>
                <span class="mechanism-desc">Let's Encrypt SSL z automatycznym odnowieniem</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Hashowanie haseł</span>
                <span class="mechanism-desc">Bezpieczne przechowywanie z Werkzeug (bcrypt)</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Ochrona przed SQL Injection</span>
                <span class="mechanism-desc">Parametryzowane zapytania przez SQLAlchemy ORM</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-5">
                <span class="mechanism-stars">★★★★★</span>
                <span class="mechanism-name">Ochrona przed XSS</span>
                <span class="mechanism-desc">Automatyczne escapowanie w szablonach Jinja2</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>

            <!-- 4 stars - IMPORTANT -->
            <div class="mechanism-item stars-4">
                <span class="mechanism-stars">★★★★☆</span>
                <span class="mechanism-name">Blokowanie geograficzne (GeoIP)</span>
                <span class="mechanism-desc">Blokada krajów wysokiego ryzyka: RU, CN, KP, IR, BY, SY, VE, CU</span>
                <span class="mechanism-status {{ 'active' if geoip_enabled else 'inactive' }}">{{ 'Aktywne' if geoip_enabled else 'Nieaktywne' }}</span>
            </div>
            <div class="mechanism-item stars-4">
                <span class="mechanism-stars">★★★★☆</span>
                <span class="mechanism-name">Rate Limiting</span>
                <span class="mechanism-desc">Ograniczenie żądań przez Flask-Limiter z Redis</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-4">
                <span class="mechanism-stars">★★★★☆</span>
                <span class="mechanism-name">Blokada konta</span>
                <span class="mechanism-desc">Automatyczna blokada po 5 nieudanych logowaniach</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-4">
                <span class="mechanism-stars">★★★★☆</span>
                <span class="mechanism-name">Audit Log</span>
                <span class="mechanism-desc">Śledzenie wszystkich działań administracyjnych</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-4">
                <span class="mechanism-stars">★★★★☆</span>
                <span class="mechanism-name">Bezpieczne sesje</span>
                <span class="mechanism-desc">Zarządzanie sesjami przez Flask-Login</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>

            <!-- 3 stars - ADDITIONAL -->
            <div class="mechanism-item stars-3">
                <span class="mechanism-stars">★★★☆☆</span>
                <span class="mechanism-name">Honeypot endpoints</span>
                <span class="mechanism-desc">Wykrywanie skanerów i botów (/.env, /wp-admin, /phpmyadmin)</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-3">
                <span class="mechanism-stars">★★★☆☆</span>
                <span class="mechanism-name">Security Alerting</span>
                <span class="mechanism-desc">Powiadomienia email o krytycznych zdarzeniach</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
            <div class="mechanism-item stars-3">
                <span class="mechanism-stars">★★★☆☆</span>
                <span class="mechanism-name">Security Logging</span>
                <span class="mechanism-desc">Centralne logowanie zdarzeń bezpieczeństwa</span>
                <span class="mechanism-status active">Aktywne</span>
            </div>
        </div>
    </div>
</div>

<!-- GeoIP Tab -->
<div id="tab-geoip" class="tab-content">
    <div class="section">
        <div class="section-header">
            <h2>🌍 Statystyki GeoIP Blocking</h2>
            <div style="text-align: right; font-size: var(--font-size-xs); color: var(--text-secondary);">
                <div>Ostatnia aktualizacja: <span id="geoip-timestamp" style="font-family: monospace; font-weight: 500;">{{ generated_at.strftime('%H:%M:%S') }}</span></div>
                <div style="margin-top: 4px;">
                    <span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: #22c55e; margin-right: 4px; animation: pulse 2s infinite;"></span>
                    Auto-refresh: <span id="geoip-countdown">5:00</span>
                </div>
            </div>
        </div>

        {% if geoip_enabled %}
        <div class="geoip-stats">
            <div class="geoip-stat">
                <div class="geoip-stat-value" id="geoip-today">{{ geoip_stats.today }}</div>
                <div class="geoip-stat-label">Zablokowanych dziś</div>
            </div>
            <div class="geoip-stat">
                <div class="geoip-stat-value" id="geoip-month">{{ geoip_stats.this_month }}</div>
                <div class="geoip-stat-label">W tym miesiącu</div>
            </div>
            <div class="geoip-stat">
                <div class="geoip-stat-value" id="geoip-year">{{ geoip_stats.this_year }}</div>
                <div class="geoip-stat-label">W tym roku</div>
            </div>
            <div class="geoip-stat">
                <div class="geoip-stat-value" id="geoip-total">{{ geoip_stats.total }}</div>
                <div class="geoip-stat-label">Od początku</div>
            </div>
        </div>

        <h3 style="margin-bottom: var(--spacing-md);">Zablokowane kraje</h3>
        <p style="color: var(--text-secondary); font-size: var(--font-size-sm); margin-bottom: var(--spacing-md);">
            Blokowane: 🇷🇺 Rosja, 🇨🇳 Chiny, 🇰🇵 Korea Północna, 🇮🇷 Iran, 🇧🇾 Białoruś, 🇸🇾 Syria, 🇻🇪 Wenezuela, 🇨🇺 Kuba
        </p>

        <div class="country-breakdown" id="country-breakdown">
        {% if geoip_stats.by_country %}
            {% for country in geoip_stats.by_country %}
            <div class="country-badge">
                <span class="country-flag">{{ country.flag }}</span>
                <span>{{ country.name }}</span>
                <span class="country-count">{{ country.count }}</span>
            </div>
            {% endfor %}
        {% else %}
            <div class="empty-state">
                <p>Brak zablokowanych połączeń</p>
            </div>
        {% endif %}
        </div>
        {% else %}
        <div class="empty-state" style="background: #fef3c7; border-radius: var(--radius-lg); padding: var(--spacing-xl);">
            <p style="color: #92400e;">⚠️ GeoIP Blocking jest wyłączone</p>
            <p style="color: #78716c; font-size: var(--font-size-sm);">Ustaw GEOIP_ENABLED=true w .env aby włączyć</p>
        </div>
        {% endif %}
    </div>
</div>

<!-- Alerts Tab -->
<div id="tab-alerts" class="tab-content">
    <div class="section">
        <div class="section-header">
            <h2>🚨 Alerty bezpieczeństwa</h2>
        </div>

        {% if alerts %}
        <table class="data-table">
            <thead>
                <tr>
                    <th>Typ</th>
                    <th>Ważność</th>
                    <th>IP</th>
                    <th>Użytkownik</th>
                    <th>Status</th>
                    <th>Data</th>
                    <th>Akcje</th>
                </tr>
            </thead>
            <tbody>
                {% for alert in alerts %}
                <tr>
                    <td><span class="alert-type">{{ alert.alert_type }}</span></td>
                    <td><span class="badge badge-{{ alert.severity }}">{{ alert.severity }}</span></td>
                    <td><span class="ip-address">{{ alert.ip_address or '-' }}</span></td>
                    <td>{{ alert.user_email or '-' }}</td>
                    <td><span class="badge badge-{{ alert.status }}">{{ alert.status }}</span></td>
                    <td><span class="timestamp">{{ alert.created_at.strftime('%Y-%m-%d %H:%M') }}</span></td>
                    <td>
                        {% if alert.status == 'new' %}
                        <div class="action-buttons">
                            <form method="POST" action="{{ url_for('acknowledge_security_alert', alert_id=alert.id) }}" style="display:inline;">
                                {{ csrf_token() }}
                                <button type="submit" class="btn-sm btn-secondary">Potwierdź</button>
                            </form>
                            <form method="POST" action="{{ url_for('resolve_security_alert', alert_id=alert.id) }}" style="display:inline;">
                                {{ csrf_token() }}
                                <button type="submit" class="btn-sm btn-primary">Rozwiąż</button>
                            </form>
                        </div>
                        {% elif alert.status == 'acknowledged' %}
                        <form method="POST" action="{{ url_for('resolve_security_alert', alert_id=alert.id) }}" style="display:inline;">
                            {{ csrf_token() }}
                            <button type="submit" class="btn-sm btn-primary">Rozwiąż</button>
                        </form>
                        {% else %}
                        <span class="timestamp">Rozwiązany</span>
                        {% endif %}
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <div class="empty-state">
            <p>✅ Brak alertów bezpieczeństwa</p>
        </div>
        {% endif %}
    </div>
</div>

<!-- Audit Log Tab -->
<div id="tab-audit" class="tab-content">
    <div class="section">
        <div class="section-header">
            <h2>📋 Audit log</h2>
        </div>

        {% if audit_logs %}
        <table class="data-table">
            <thead>
                <tr>
                    <th>Użytkownik</th>
                    <th>Akcja</th>
                    <th>Encja</th>
                    <th>IP</th>
                    <th>Data</th>
                </tr>
            </thead>
            <tbody>
                {% for log in audit_logs %}
                <tr>
                    <td>{{ log.user_email }}</td>
                    <td><code>{{ log.action }}</code></td>
                    <td>
                        {{ log.entity_type }}
                        {% if log.entity_id %}:{{ log.entity_id }}{% endif %}
                        {% if log.entity_name %}<br><small>{{ log.entity_name }}</small>{% endif %}
                    </td>
                    <td><span class="ip-address">{{ log.ip_address or '-' }}</span></td>
                    <td><span class="timestamp">{{ log.created_at.strftime('%Y-%m-%d %H:%M') }}</span></td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <div class="empty-state">
            <p>Brak wpisów w audit log</p>
        </div>
        {% endif %}
    </div>
</div>

<!-- Locked Accounts Tab -->
<div id="tab-locked" class="tab-content">
    <div class="section">
        <div class="section-header">
            <h2>🔒 Zablokowane konta</h2>
        </div>

        {% if locked_accounts %}
        <table class="data-table">
            <thead>
                <tr>
                    <th>Email</th>
                    <th>Nieudane próby</th>
                    <th>Zablokowane do</th>
                    <th>Akcje</th>
                </tr>
            </thead>
            <tbody>
                {% for user in locked_accounts %}
                <tr class="locked-row">
                    <td>{{ user.email }}</td>
                    <td>{{ user.failed_login_attempts }}</td>
                    <td><span class="timestamp">{{ user.locked_until.strftime('%Y-%m-%d %H:%M') }}</span></td>
                    <td>
                        <form method="POST" action="{{ url_for('unlock_account', user_id=user.id) }}" style="display:inline;">
                            {{ csrf_token() }}
                            <button type="submit" class="btn-sm btn-danger" onclick="return confirm('Odblokować konto {{ user.email }}?')">
                                Odblokuj
                            </button>
                        </form>
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <div class="empty-state">
            <p>✅ Brak zablokowanych kont</p>
        </div>
        {% endif %}
    </div>
</div>

{% endblock %}

{% block extra_js %}
function showTab(tabName) {
    // Hide all tabs
    document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
    document.querySelectorAll('.tab').forEach(el => el.classList.remove('active'));

    // Show selected tab
    document.getElementById('tab-' + tabName).classList.add('active');
    event.target.classList.add('active');
}

// GeoIP auto-refresh every 5 minutes
let geoipCountdown = 300;

function updateGeoipCountdown() {
    const minutes = Math.floor(geoipCountdown / 60);
    const seconds = geoipCountdown % 60;
    const countdownEl = document.getElementById('geoip-countdown');
    if (countdownEl) {
        countdownEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
    }

    if (geoipCountdown <= 0) {
        refreshGeoipStats();
        geoipCountdown = 300;
    } else {
        geoipCountdown--;
    }
}

async function refreshGeoipStats() {
    try {
        const response = await fetch('/api/admin/security/geoip-stats');
        if (response.ok) {
            const data = await response.json();

            // Update timestamp
            const timestamp = new Date(data.timestamp);
            const timestampEl = document.getElementById('geoip-timestamp');
            if (timestampEl) {
                timestampEl.textContent = timestamp.toLocaleTimeString('pl-PL');
            }

            if (data.enabled) {
                // Update stats
                const todayEl = document.getElementById('geoip-today');
                const monthEl = document.getElementById('geoip-month');
                const yearEl = document.getElementById('geoip-year');
                const totalEl = document.getElementById('geoip-total');

                if (todayEl) todayEl.textContent = data.today;
                if (monthEl) monthEl.textContent = data.this_month;
                if (yearEl) yearEl.textContent = data.this_year;
                if (totalEl) totalEl.textContent = data.total;

                // Update country breakdown
                const breakdownEl = document.getElementById('country-breakdown');
                if (breakdownEl && data.by_country) {
                    if (data.by_country.length > 0) {
                        breakdownEl.innerHTML = data.by_country.map(c =>
                            `<div class="country-badge">
                                <span class="country-flag">${c.flag}</span>
                                <span>${c.name}</span>
                                <span class="country-count">${c.count}</span>
                            </div>`
                        ).join('');
                    } else {
                        breakdownEl.innerHTML = '<div class="empty-state"><p>Brak zablokowanych połączeń</p></div>';
                    }
                }
            }
        }
    } catch (error) {
        console.error('Failed to refresh GeoIP stats:', error);
    }
}

// Start countdown
setInterval(updateGeoipCountdown, 1000);

// Refresh when page becomes visible
document.addEventListener('visibilitychange', function() {
    if (!document.hidden) {
        refreshGeoipStats();
        geoipCountdown = 300;
    }
});
{% endblock %}
