{% extends "base.html" %}
{% block page_title %}Tactiques d'attaque{% endblock %}

{% block content %}
<!-- ═══ Tactiques d'attaque — 4 panneaux de détection spécialisés ═══ -->

<!-- ── KPIs ── -->
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4">
    <div class="kpi-card"><div class="kpi-label">Brute-force IPs</div><div class="kpi-value text-red-400" id="kpi-bf">—</div></div>
    <div class="kpi-card"><div class="kpi-label">JA4 rotation IPs</div><div class="kpi-value text-orange-400" id="kpi-rot">—</div></div>
    <div class="kpi-card"><div class="kpi-label">IPs récurrentes</div><div class="kpi-value text-yellow-400" id="kpi-rec">—</div></div>
    <div class="kpi-card"><div class="kpi-label">Alertes 24h</div><div class="kpi-value text-purple-400" id="kpi-alerts">—</div></div>
</div>

<!-- ── Brute-force / Credential stuffing ── -->
<div class="section-card border-red-600/40 mb-4">
    <div class="section-header">
        <span class="section-title">
            <svg class="w-4 h-4 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
            Brute-force / Credential Stuffing
        </span>
        <div class="relative">
            <button class="doc-btn">ⓘ</button>
            <div class="doc-panel right-0 w-72">
                <strong>Détection brute-force</strong><br>
                IPs envoyant ≥10 requêtes POST/heure sur des endpoints d'authentification.
                Signale les tentatives de credential stuffing, brute-force de mots de passe,
                ou abus d'API. Données issues de <code>view_form_bruteforce_detected</code>.
            </div>
        </div>
    </div>
    <div class="section-body p-0">
        <div class="overflow-x-auto">
            <table class="data-table">
                <thead><tr><th>IP</th><th>Host</th><th class="text-right">POST/h</th><th class="text-right">Paths distincts</th><th>Première vue</th><th>Dernière vue</th></tr></thead>
                <tbody id="bf-body"><tr><td colspan="6" class="text-center text-gray-500 py-8">Chargement…</td></tr></tbody>
            </table>
        </div>
    </div>
</div>

<!-- ── JA4 Rotation (évasion) ── -->
<div class="section-card border-orange-600/40 mb-4">
    <div class="section-header">
        <span class="section-title">
            <svg class="w-4 h-4 text-orange-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
            Rotation de fingerprint JA4
        </span>
        <div class="relative">
            <button class="doc-btn">ⓘ</button>
            <div class="doc-panel right-0 w-72">
                <strong>Détection d'évasion JA4</strong><br>
                IPs utilisant ≥2 fingerprints JA4 distincts en 24h. Technique d'évasion
                classique : rotation de la configuration TLS pour contourner les blocages
                par fingerprint. Données issues de <code>view_host_ip_ja4_rotation</code>.
            </div>
        </div>
    </div>
    <div class="section-body p-0">
        <div class="overflow-x-auto">
            <table class="data-table">
                <thead><tr><th>IP</th><th>Host</th><th class="text-right">JA4 distincts</th><th>Fingerprints</th><th class="text-right">Hits</th><th>Fenêtre</th></tr></thead>
                <tbody id="rot-body"><tr><td colspan="6" class="text-center text-gray-500 py-8">Chargement…</td></tr></tbody>
            </table>
        </div>
    </div>
</div>

<!-- ── Récurrence (menaces persistantes) ── -->
<div class="section-card border-yellow-600/40 mb-4">
    <div class="section-header">
        <span class="section-title">
            <svg class="w-4 h-4 text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
            Menaces persistantes (récurrence)
        </span>
        <div class="relative">
            <button class="doc-btn">ⓘ</button>
            <div class="doc-panel right-0 w-72">
                <strong>IPs récurrentes</strong><br>
                IPs détectées comme anomalies sur plusieurs fenêtres temporelles distinctes.
                La récurrence augmente la confiance dans la classification malveillante.
                Score agravé par <code>log1p(recurrence) × 0.005</code>.
                Données issues de <code>view_ip_recurrence</code>.
            </div>
        </div>
    </div>
    <div class="section-body p-0">
        <div class="overflow-x-auto">
            <table class="data-table">
                <thead><tr><th>IP</th><th class="text-right">Récurrence</th><th class="text-right">Pire score</th><th>Pire menace</th><th>Première vue</th><th>Dernière vue</th><th>JA4 top</th><th>Host top</th></tr></thead>
                <tbody id="rec-body"><tr><td colspan="8" class="text-center text-gray-500 py-8">Chargement…</td></tr></tbody>
            </table>
        </div>
    </div>
</div>

<!-- ── Alertes temps réel ── -->
<div class="section-card border-purple-600/40 mb-4">
    <div class="section-header">
        <span class="section-title">
            <svg class="w-4 h-4 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/></svg>
            Alertes récentes (24h)
        </span>
        <div class="relative">
            <button class="doc-btn">ⓘ</button>
            <div class="doc-panel right-0 w-72">
                <strong>Flux d'alertes</strong><br>
                Dernières détections CRITICAL, HIGH et KNOWN_BOT sur les 24 dernières heures.
                Chaque alerte inclut le score, la raison SHAP, et le lien vers l'investigation IP.
            </div>
        </div>
    </div>
    <div class="section-body p-0">
        <div class="overflow-x-auto">
            <table class="data-table">
                <thead><tr><th>Date</th><th>IP</th><th class="text-right">Score</th><th>Menace</th><th>JA4</th><th>Host</th><th>ASN</th><th class="text-right">Hits</th><th>Raison</th></tr></thead>
                <tbody id="alert-body"><tr><td colspan="9" class="text-center text-gray-500 py-8">Chargement…</td></tr></tbody>
            </table>
        </div>
    </div>
</div>

<script>
/* ═══════════════════════════════════════════════════════════════════════
 *  Tactiques — chargement des 4 sources de données
 * ═══════════════════════════════════════════════════════════════════════ */
document.addEventListener('DOMContentLoaded', () => {
    Promise.all([
        fetch('/api/brute-force').then(r => r.json()),
        fetch('/api/ja4-rotation').then(r => r.json()),
        fetch('/api/recurrence').then(r => r.json()),
        fetch('/api/alerts?limit=50').then(r => r.json()),
    ]).then(([bf, rot, rec, alerts]) => {
        renderBruteForce(bf.data || []);
        renderRotation(rot.data || []);
        renderRecurrence(rec.data || []);
        renderAlerts(alerts.alerts || []);
    }).catch(err => console.error('Tactics load error:', err));
});

function renderBruteForce(data) {
    document.getElementById('kpi-bf').textContent = data.length;
    const body = document.getElementById('bf-body');
    if (!data.length) { body.innerHTML = '<tr><td colspan="6" class="text-center text-gray-500 py-8">Aucune tentative de brute-force détectée</td></tr>'; return; }
    body.innerHTML = data.map(r => `<tr class="cursor-pointer hover:bg-gray-800/60" onclick="location.href='/ip/${r.src_ip}'">
        <td>${fmtIP(r.src_ip)}</td><td class="text-gray-300">${escapeHtml(r.host||'')}</td>
        <td class="text-right font-mono text-red-400 font-bold">${r.post_count}</td>
        <td class="text-right">${r.distinct_paths}</td>
        <td class="text-gray-400 text-xs">${fmtDate(r.first_seen)}</td>
        <td class="text-gray-400 text-xs">${fmtDate(r.last_seen)}</td></tr>`).join('');
}

function renderRotation(data) {
    document.getElementById('kpi-rot').textContent = data.length;
    const body = document.getElementById('rot-body');
    if (!data.length) { body.innerHTML = '<tr><td colspan="6" class="text-center text-gray-500 py-8">Aucune rotation JA4 détectée</td></tr>'; return; }
    body.innerHTML = data.map(r => {
        const ja4s = (r.ja4_list || []).map(j => fmtJA4(j)).join(', ');
        return `<tr class="cursor-pointer hover:bg-gray-800/60" onclick="location.href='/ip/${r.src_ip}'">
            <td>${fmtIP(r.src_ip)}</td><td class="text-gray-300">${escapeHtml(r.host||'')}</td>
            <td class="text-right font-mono text-orange-400 font-bold">${r.distinct_ja4}</td>
            <td class="max-w-xs truncate">${ja4s}</td>
            <td class="text-right">${r.total_hits}</td>
            <td class="text-gray-400 text-xs">${fmtDate(r.window_start)}</td></tr>`;
    }).join('');
}

function renderRecurrence(data) {
    document.getElementById('kpi-rec').textContent = data.length;
    const body = document.getElementById('rec-body');
    if (!data.length) { body.innerHTML = '<tr><td colspan="8" class="text-center text-gray-500 py-8">Aucune IP récurrente</td></tr>'; return; }
    body.innerHTML = data.map(r => `<tr class="cursor-pointer hover:bg-gray-800/60" onclick="location.href='/ip/${r.src_ip}'">
        <td>${fmtIP(r.src_ip)}</td>
        <td class="text-right font-mono text-yellow-400 font-bold">${r.recurrence}×</td>
        <td class="text-right font-mono">${fmtScore(r.worst_score)}</td>
        <td>${threatBadge(r.worst_threat||r.worst_threat_level||'')}</td>
        <td class="text-gray-400 text-xs">${fmtDate(r.first_seen)}</td>
        <td class="text-gray-400 text-xs">${fmtDate(r.last_seen)}</td>
        <td>${r.top_ja4 ? fmtJA4(r.top_ja4) : ''}</td>
        <td class="text-gray-300">${escapeHtml(r.top_host||'')}</td></tr>`).join('');
}

function renderAlerts(data) {
    document.getElementById('kpi-alerts').textContent = data.length;
    const body = document.getElementById('alert-body');
    if (!data.length) { body.innerHTML = '<tr><td colspan="9" class="text-center text-gray-500 py-8">Aucune alerte récente</td></tr>'; return; }
    body.innerHTML = data.map(r => `<tr class="cursor-pointer hover:bg-gray-800/60" onclick="location.href='/ip/${r.src_ip}'">
        <td class="text-gray-400 text-xs whitespace-nowrap">${fmtDate(r.detected_at)}</td>
        <td>${fmtIP(r.src_ip)}</td>
        <td class="text-right font-mono">${fmtScore(r.anomaly_score)}</td>
        <td>${threatBadge(r.threat_level)}</td>
        <td>${fmtJA4(r.ja4)}</td>
        <td class="text-gray-300">${escapeHtml(r.host||'')}</td>
        <td class="text-gray-400 text-xs">${escapeHtml(r.asn_org||'')}</td>
        <td class="text-right">${r.hits||''}</td>
        <td class="text-gray-400 text-xs max-w-[200px] truncate" title="${escapeHtml(r.reason||'')}">${escapeHtml((r.reason||'').substring(0,60))}</td></tr>`).join('');
}
</script>
{% endblock %}
