{% extends 'base.html' %}
{% block title %}Agents Qualys{% endblock %}
{% block content %}
<div class="flex justify-between items-center mb-4">
    <div>
        <h2 class="text-xl font-bold text-cyber-accent">Agents Qualys</h2>
        <p class="text-xs text-gray-500 mt-1">Activation keys et versions des agents déployés</p>
    </div>
    <div style="display:flex;gap:8px">
        <button id="btn-refresh-diff" class="btn-primary px-4 py-2 text-sm" onclick="refreshAgents('diff')" title="Pull seulement les assets modifies depuis le dernier sync" {% if sync_running %}disabled{% endif %}>
            Sync rapide (diff)
        </button>
        <button id="btn-refresh-full" class="btn-sm px-4 py-2 text-sm" style="background:#22c55e;color:#000;font-weight:bold" onclick="refreshAgents('full')" title="Pull complet (5-10 min). A faire 1x par jour" {% if sync_running %}disabled{% endif %}>
            Sync complète
        </button>
        <a href="/qualys/deploy" class="btn-sm bg-cyber-border text-gray-300 px-4 py-2">Déployer</a>
        <a href="/qualys/search" class="btn-sm bg-cyber-border text-gray-300 px-4 py-2">Recherche</a>
    </div>
</div>

{% if sync_running %}
<div class="card p-3 mb-4" style="border:1px solid #f59e0b;background:rgba(245,158,11,0.1)">
    <div class="flex justify-between items-center">
        <div>
            <span class="text-cyber-yellow font-bold">⏳ Synchronisation Qualys en cours</span>
            <span class="text-xs text-gray-400 ml-2">Les boutons de sync sont désactivés. Les données ci-dessous peuvent être en cours de mise à jour.</span>
        </div>
        <form method="POST" action="/qualys/agents/cancel" style="display:inline">
            <button class="btn-sm bg-cyber-red text-white px-3 py-1">Annuler</button>
        </form>
    </div>
</div>
{% endif %}

<!-- Overlay chargement -->
<div id="refresh-overlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:9999;justify-content:center;align-items:center">
    <div class="card p-6 text-center" style="min-width:320px">
        <div style="margin-bottom:12px">
            <svg style="display:inline;animation:spin 1s linear infinite;width:36px;height:36px" viewBox="0 0 24 24" fill="none" stroke="#00ffc8" stroke-width="2"><circle cx="12" cy="12" r="10" stroke-opacity="0.3"/><path d="M12 2a10 10 0 0 1 10 10" stroke-linecap="round"/></svg>
        </div>
        <div class="text-cyber-accent font-bold text-sm" id="refresh-title">Rafraîchissement en cours...</div>
        <div class="text-gray-400 text-xs mt-2" id="refresh-detail">Synchronisation des agents depuis l'API Qualys</div>
        <div class="text-gray-500 text-xs mt-3" id="refresh-timer">0s</div>
        <button id="btn-cancel" class="btn-secondary px-3 py-1 text-xs mt-4" onclick="cancelRefresh()">Annuler</button>
    </div>
</div>
<style>@keyframes spin{to{transform:rotate(360deg)}}
.sortable-table th.sortable{cursor:pointer;user-select:none;position:relative;padding-right:18px}
.sortable-table th.sortable::after{content:'\2195';position:absolute;right:6px;color:#4b5563;font-size:10px}
.sortable-table th.sort-asc::after{content:'\2191';color:#00ffc8}
.sortable-table th.sort-desc::after{content:'\2193';color:#00ffc8}</style>
<script>
function sortTable(th, type){
    var table = th.closest('table');
    var tbody = table.querySelector('tbody');
    var ths = Array.from(table.querySelectorAll('thead th'));
    var col = ths.indexOf(th);
    var asc = !th.classList.contains('sort-asc');
    ths.forEach(function(t){ t.classList.remove('sort-asc','sort-desc'); });
    th.classList.add(asc ? 'sort-asc' : 'sort-desc');
    var rows = Array.from(tbody.querySelectorAll('tr'));
    rows.sort(function(a,b){
        var av = (a.cells[col] && a.cells[col].innerText || '').trim();
        var bv = (b.cells[col] && b.cells[col].innerText || '').trim();
        if(type === 'num'){
            var an = parseFloat(av.replace(/[^0-9.-]/g,'')) || 0;
            var bn = parseFloat(bv.replace(/[^0-9.-]/g,'')) || 0;
            return asc ? an - bn : bn - an;
        }
        return asc ? av.localeCompare(bv,'fr',{numeric:true}) : bv.localeCompare(av,'fr',{numeric:true});
    });
    rows.forEach(function(r){ tbody.appendChild(r); });
}
</script>

<!-- Message résultat -->
<div id="refresh-msg" style="display:none;padding:8px 16px;border-radius:6px;margin-bottom:12px;font-size:0.85rem"></div>

<script>

function cancelRefresh() {
    fetch('/qualys/agents/cancel', {method: 'POST'})
        .then(function(r){ return r.json(); })
        .then(function(d){
            var title = document.getElementById('refresh-title');
            if (title) title.textContent = 'Annulation en cours...';
        });
}

function refreshAgents(mode) {
    mode = mode || 'diff';
    var btnDiff = document.getElementById('btn-refresh-diff');
    var btnFull = document.getElementById('btn-refresh-full');
    var overlay = document.getElementById('refresh-overlay');
    var timer = document.getElementById('refresh-timer');
    var msgDiv = document.getElementById('refresh-msg');
    if (btnDiff) btnDiff.disabled = true;
    if (btnFull) btnFull.disabled = true;
    overlay.style.display = 'flex';
    msgDiv.style.display = 'none';
    var t0 = Date.now();
    var iv = setInterval(function(){ timer.textContent = Math.floor((Date.now()-t0)/1000) + 's'; }, 1000);
    fetch('/qualys/agents/refresh?mode=' + encodeURIComponent(mode), {method:'POST', credentials:'same-origin'})
        .then(function(r){ return r.json().then(function(d){ return {ok:r.ok, data:d}; }); })
        .then(function(res){
            clearInterval(iv);
            overlay.style.display = 'none';
            if (btnDiff) btnDiff.disabled = false;
            if (btnFull) btnFull.disabled = false;
            if(res.ok && res.data.ok){
                msgDiv.style.background = '#1a5a2e';
                msgDiv.style.color = '#8f8';
                msgDiv.textContent = 'Données rafraîchies : ' + res.data.msg;
                msgDiv.style.display = 'block';
                setTimeout(function(){ location.reload(); }, 1500);
            } else {
                msgDiv.style.background = '#5a1a1a';
                msgDiv.style.color = '#ff3366';
                msgDiv.textContent = 'Erreur : ' + (res.data.msg || 'Erreur inconnue');
                msgDiv.style.display = 'block';
            }
        })
        .catch(function(err){
            clearInterval(iv);
            overlay.style.display = 'none';
            if (btnDiff) btnDiff.disabled = false;
            if (btnFull) btnFull.disabled = false;
            msgDiv.style.background = '#5a1a1a';
            msgDiv.style.color = '#ff3366';
            msgDiv.textContent = 'Erreur réseau : ' + err.message;
            msgDiv.style.display = 'block';
        });
}
</script>

<!-- KPIs agents -->
<div style="display:flex;flex-wrap:nowrap;gap:8px;margin-bottom:16px;">
    <div class="card p-3 text-center" style="flex:1;min-width:0"><div class="text-2xl font-bold text-cyber-accent">{{ summary.total_assets or 0 }}</div><div class="text-xs text-gray-500">Total assets</div></div>
    <div class="card p-3 text-center" style="flex:1;min-width:0"><div class="text-2xl font-bold text-cyber-green">{{ summary.active or 0 }}</div><div class="text-xs text-gray-500">Agents actifs</div></div>
    <a href="#inactive-list" class="card p-3 text-center hover:bg-cyber-hover" style="flex:1;min-width:0"><div class="text-2xl font-bold text-cyber-red">{{ summary.inactive or 0 }}*</div><div class="text-xs text-gray-500">Agents inactifs</div></a>
    <div class="card p-3 text-center" style="flex:1;min-width:0"><div class="text-2xl font-bold text-cyber-red">{{ no_agent_servers|length }}</div><div class="text-xs text-gray-500">Sans agent (prod)</div></div>
</div>

<!-- Activation Keys -->
<div class="card p-4 mb-4">
    <h3 class="text-sm font-bold text-cyber-accent mb-3">Activation Keys</h3>
    <table class="w-full table-cyber text-xs sortable-table">
        <thead><tr>
            <th class="text-left p-2 sortable" onclick="sortTable(this)">Titre</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Statut</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Type</th>
            <th class="p-2 sortable" onclick="sortTable(this,'num')">Utilisés</th>
            <th class="text-left p-2 sortable" onclick="sortTable(this)">Clé</th>
        </tr></thead>
        <tbody>
        {% for k in keys %}
        <tr>
            <td class="p-2 font-bold text-cyber-accent">{{ k.title }}</td>
            <td class="p-2 text-center"><span class="badge {% if k.status == 'ACTIVE' %}badge-green{% else %}badge-red{% endif %}">{{ k.status }}</span></td>
            <td class="p-2 text-center text-gray-400">{{ k.type }}</td>
            <td class="p-2 text-center font-bold">{{ k.used }}</td>
            <td class="p-2 font-mono text-gray-500" style="font-size:10px;">{{ k.key }}</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

<!-- Statut agents -->
<div class="grid grid-cols-2 gap-4 mb-4">
    <div class="card p-4">
        <h3 class="text-sm font-bold text-cyber-accent mb-3">Statut des agents</h3>
        {% if summary.statuses %}
        <table class="w-full table-cyber text-xs sortable-table">
            <thead><tr><th class="text-left p-2 sortable" onclick="sortTable(this)">Statut</th><th class="p-2 sortable" onclick="sortTable(this,'num')">Nombre</th></tr></thead>
            <tbody>
            {% for s in summary.statuses %}
            <tr>
                <td class="p-2"><span class="badge {% if 'ACTIVE' in (s.agent_status or '').upper() or 'STATUS_ACTIVE' in (s.agent_status or '').upper() %}badge-green{% elif 'INACTIVE' in (s.agent_status or '').upper() %}badge-red{% else %}badge-gray{% endif %}">{{ s.agent_status }}</span></td>
                <td class="p-2 text-center font-bold">{{ s.cnt }}</td>
            </tr>
            {% endfor %}
            </tbody>
        </table>
        {% else %}
        <p class="text-gray-500 text-xs">Aucune donnée</p>
        {% endif %}
    </div>

    <div class="card p-4">
        <h3 class="text-sm font-bold text-cyber-accent mb-3">Versions déployées</h3>
        {% if summary.versions %}
        <table class="w-full table-cyber text-xs sortable-table">
            <thead><tr><th class="text-left p-2 sortable" onclick="sortTable(this)">Version</th><th class="p-2 sortable" onclick="sortTable(this,'num')">Nombre</th></tr></thead>
            <tbody>
            {% for v in summary.versions %}
            <tr>
                <td class="p-2 font-mono">{{ v.agent_version }}</td>
                <td class="p-2 text-center font-bold">{{ v.cnt }}</td>
            </tr>
            {% endfor %}
            </tbody>
        </table>
        {% else %}
        <p class="text-gray-500 text-xs">Aucune donnée</p>
        {% endif %}
    </div>
</div>

<!-- Serveurs sans agent Qualys -->
{% if no_agent_servers %}
<div class="card p-4 mb-4" x-data="{fHost:'', fOs:'', fDom:'', fEnv:'', fEtat:''}">
    <div class="flex justify-between items-center mb-3">
        <h3 class="text-sm font-bold text-cyber-red">Serveurs sans agent Qualys ({{ no_agent_servers|length }})</h3>
        <a href="/qualys/agents/export-no-agent" class="btn-sm bg-cyber-green text-black px-3 py-1 text-xs">Exporter CSV</a>
    </div>
    <div class="flex gap-2 mb-3">
        <input type="text" x-model="fHost" placeholder="Hostname..." class="text-xs py-1 px-2 flex-1 font-mono">
        <select x-model="fOs" class="text-xs py-1 px-2">
            <option value="">OS</option>
            <option value="linux">Linux</option>
            <option value="windows">Windows</option>
        </select>
        <select x-model="fDom" class="text-xs py-1 px-2">
            <option value="">Domaine</option>
            {% set doms = no_agent_servers|map(attribute='domain')|unique|sort %}
            {% for d in doms %}{% if d %}<option value="{{ d }}">{{ d }}</option>{% endif %}{% endfor %}
        </select>
        <select x-model="fEnv" class="text-xs py-1 px-2">
            <option value="">Env</option>
            {% set envs = no_agent_servers|map(attribute='env')|unique|sort %}
            {% for e in envs %}{% if e %}<option value="{{ e }}">{{ e }}</option>{% endif %}{% endfor %}
        </select>
        <select x-model="fEtat" class="text-xs py-1 px-2">
            <option value="">État</option>
            {% set etats = no_agent_servers|map(attribute='etat')|unique|sort %}
            {% for e in etats %}{% if e %}<option value="{{ e }}">{{ e }}</option>{% endif %}{% endfor %}
        </select>
        <button @click="fHost='';fOs='';fDom='';fEnv='';fEtat=''" class="text-xs text-gray-400 hover:text-cyber-accent">Reset</button>
    </div>
    <table class="w-full table-cyber text-xs sortable-table">
        <thead><tr>
            <th class="text-left p-2 sortable" onclick="sortTable(this)">Hostname</th>
            <th class="p-2 sortable" onclick="sortTable(this)">OS</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Version OS</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Domaine</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Env</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Zone</th>
            <th class="p-2 sortable" onclick="sortTable(this)">État</th>
        </tr></thead>
        <tbody id="noagent-body">
        {% for s in no_agent_servers %}
        <tr x-show="
            (fHost === '' || '{{ s.hostname }}'.toLowerCase().includes(fHost.toLowerCase()))
            && (fOs === '' || '{{ s.os_family or '' }}'.toLowerCase() === fOs.toLowerCase())
            && (fDom === '' || '{{ s.domain or '' }}' === fDom)
            && (fEnv === '' || '{{ s.env or '' }}' === fEnv)
            && (fEtat === '' || '{{ s.etat or '' }}' === fEtat)
        ">
            <td class="p-2 font-mono text-cyber-accent">{{ s.hostname }}</td>
            <td class="p-2 text-center">{{ s.os_family or '-' }}</td>
            <td class="p-2 text-center text-xs text-gray-300">{{ s.os_version or '-' }}</td>
            <td class="p-2 text-center text-gray-400">{{ s.domain or '-' }}</td>
            <td class="p-2 text-center">{{ s.env or '-' }}</td>
            <td class="p-2 text-center">{% if s.zone == 'DMZ' %}<span class="badge badge-red">DMZ</span>{% else %}{{ s.zone or '-' }}{% endif %}</td>
            <td class="p-2 text-center" title="{{ s.etat or '' }}"><span class="badge {% if s.etat == 'Production' %}badge-green{% elif s.etat in ('Obsolète','EOL') %}badge-red{% elif s.etat == 'Stock' %}badge-gray{% else %}badge-yellow{% endif %}">{% if s.etat == 'Obsolète' %}Décom.{% elif s.etat == 'EOL' %}EOL{% elif s.etat == 'Production' %}Prod{% else %}{{ (s.etat or '-')[:8] }}{% endif %}</span></td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
{% endif %}

<!-- Agents inactifs -->
{% if inactive_agents %}
<div id="inactive-list" class="card p-4 mb-4">
    <div class="flex justify-between items-center mb-3">
        <h3 class="text-sm font-bold text-cyber-red">* Agents inactifs ({{ inactive_agents|length }})</h3>
        <a href="/qualys/agents/export-inactive" class="btn-sm bg-cyber-green text-black px-3 py-1 text-xs">Exporter CSV</a>
    </div>
    <div class="card p-3 mb-3 text-xs text-gray-400" style="background:#111827;">
        <b>* Légende :</b> Ces serveurs ont un agent Qualys installé mais qui ne communique plus avec le cloud Qualys.
        Causes possibles : serveur éteint, flux réseau bloqué (port 443 vers qualysagent.qualys.eu), agent crashé, ou OS non supporté (RHEL 5 EOL).
        Tous ces agents sont en version <b>6.1.0.28</b> sur <b>RHEL 5.x</b> — dernier check-in le <b>14/11/2025</b>.
    </div>
    <table class="w-full table-cyber text-xs sortable-table">
        <thead><tr>
            <th class="text-left p-2 sortable" onclick="sortTable(this)">Hostname</th>
            <th class="p-2 sortable" onclick="sortTable(this)">OS</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Version agent</th>
            <th class="p-2 sortable" onclick="sortTable(this)">Dernier check-in</th>
            <th class="p-2 sortable" onclick="sortTable(this)">État</th>
            <th class="p-2">Action</th>
        </tr></thead>
        <tbody>
        {% for a in inactive_agents %}
        <tr>
            <td class="p-2 font-mono text-cyber-accent">{{ a.hostname }}</td>
            <td class="p-2 text-center text-gray-400">{{ a.os or '-' }}</td>
            <td class="p-2 text-center font-mono">{{ a.agent_version or '-' }}</td>
            <td class="p-2 text-center text-cyber-yellow">{% if a.last_checkin %}{{ (a.last_checkin|string)[:10] }}{% else %}-{% endif %}</td>
            <td class="p-2 text-center">{{ a.etat or '-' }}</td>
            <td class="p-2 text-center">
                {% if 'Windows' in (a.os or '') %}
                    <span class="text-gray-500 text-xs italic" title="Audit SSH non disponible pour Windows">Non géré</span>
                {% else %}
                    <a href="/qualys/agents/{{ a.hostname }}/audit-qualys" class="btn-sm bg-cyber-border text-cyber-accent px-2 py-1 text-xs hover:bg-cyber-hover" title="Audit SSH ciblé : status agent, version, disque, connectivité, logs">Troubleshooting</a>
                {% endif %}
            </td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
{% endif %}
{% endblock %}
