{% extends 'base.html' %}
{% block title %}Patching — Config exclusions{% endblock %}
{% block content %}
<div class="flex justify-between items-center mb-4">
    <div>
        <h2 class="text-xl font-bold text-cyber-accent">Config exclusions — par serveur</h2>
        <p class="text-xs text-gray-500 mt-1">Exclusions de packages lors du <code>yum update</code>. Stockées dans iTop (champ <code>patch_excludes</code>) et poussées en temps réel.</p>
    </div>
    <div class="flex gap-2">
        <a href="/quickwin/config" class="btn-sm bg-cyber-border text-gray-300 px-3 py-2">Packages reboot (QuickWin)</a>
    </div>
</div>

{% if msg %}
<div class="mb-3 p-2 rounded text-sm bg-green-900/30 text-cyber-green">{{ msg }}</div>
{% endif %}

<!-- KPIs -->
<div class="flex gap-2 mb-4">
    <div class="card p-3 text-center" style="flex:1"><div class="text-2xl font-bold text-cyber-accent">{{ stats.total_servers }}</div><div class="text-xs text-gray-500">Serveurs total</div></div>
    <div class="card p-3 text-center" style="flex:1"><div class="text-2xl font-bold text-cyber-green">{{ stats.with_excludes }}</div><div class="text-xs text-gray-500">Avec exclusions</div></div>
    <div class="card p-3 text-center" style="flex:1"><div class="text-2xl font-bold text-cyber-yellow">{{ stats.total_servers - stats.with_excludes }}</div><div class="text-xs text-gray-500">Sans exclusions</div></div>
    <div class="card p-3 text-center" style="flex:1"><div class="text-2xl font-bold text-cyber-blue">{{ total }}</div><div class="text-xs text-gray-500">Filtrés</div></div>
</div>

<!-- Filtres -->
<div class="card p-3 mb-4">
    <form method="GET" class="flex gap-2 items-center flex-wrap">
        <input type="text" name="search" value="{{ filters.search }}" placeholder="Hostname..." class="text-xs py-1 px-2" style="width:200px">
        <select name="domain" class="text-xs py-1 px-2" style="width:150px">
            <option value="">Tous domaines</option>
            {% for d in domains %}<option value="{{ d.code }}" {% if filters.domain == d.code %}selected{% endif %}>{{ d.name }}</option>{% endfor %}
        </select>
        <select name="env" class="text-xs py-1 px-2" style="width:130px">
            <option value="">Tous envs</option>
            {% for e in envs %}<option value="{{ e.code }}" {% if filters.env == e.code %}selected{% endif %}>{{ e.name }}</option>{% endfor %}
        </select>
        <select name="zone" class="text-xs py-1 px-2" style="width:100px">
            <option value="">Toutes zones</option>
            {% for z in zones %}<option value="{{ z }}" {% if filters.zone == z %}selected{% endif %}>{{ z }}</option>{% endfor %}
        </select>
        <select name="tier" class="text-xs py-1 px-2" style="width:90px">
            <option value="">Tier</option>
            {% for t in ['tier0','tier1','tier2','tier3'] %}<option value="{{ t }}" {% if filters.tier == t %}selected{% endif %}>{{ t }}</option>{% endfor %}
        </select>
        <select name="os" class="text-xs py-1 px-2" style="width:100px">
            <option value="">Tous OS</option>
            <option value="linux" {% if filters.os == 'linux' %}selected{% endif %}>Linux</option>
            <option value="windows" {% if filters.os == 'windows' %}selected{% endif %}>Windows</option>
        </select>
        <select name="application" class="text-xs py-1 px-2" style="width:220px">
            <option value="">Toutes solutions applicatives</option>
            {% for a in applications %}<option value="{{ a.application_name }}" {% if filters.application == a.application_name %}selected{% endif %}>{{ a.application_name }} ({{ a.c }})</option>{% endfor %}
        </select>
        <select name="has_excludes" class="text-xs py-1 px-2" style="width:140px">
            <option value="">Tous</option>
            <option value="yes" {% if filters.has_excludes == 'yes' %}selected{% endif %}>Avec exclusions</option>
            <option value="no" {% if filters.has_excludes == 'no' %}selected{% endif %}>Sans exclusions</option>
        </select>
        <button type="submit" class="btn-primary px-3 py-1 text-xs">Filtrer</button>
        <a href="/patching/config-exclusions" class="text-xs text-gray-500 hover:text-cyber-accent">Reset</a>
    </form>
</div>

<!-- Bulk actions -->
<div id="bulk-bar" class="card p-3 mb-2" style="display:none">
    <div class="flex gap-2 items-center flex-wrap mb-2">
        <span class="text-xs text-gray-400"><b id="bulk-count">0</b> sélectionné(s)</span>
        <span class="text-xs text-gray-500 font-bold ml-2">Exclusions :</span>
        <input type="text" id="bulk-pattern" placeholder="pattern (ex: oracle*, nginx*)" class="text-xs py-1 px-2" style="width:220px">
        <button onclick="bulkAction('add')" class="btn-sm bg-cyber-green text-black">Ajouter</button>
        <button onclick="bulkAction('remove')" class="btn-sm bg-red-900/40 text-cyber-red">Retirer</button>
        <button onclick="bulkAction('replace')" class="btn-sm bg-cyber-border text-cyber-accent">Remplacer tout</button>
    </div>
    <div class="flex gap-2 items-center flex-wrap">
        <span class="text-xs text-gray-500 font-bold">Solution applicative :</span>
        <select id="bulk-app" class="text-xs py-1 px-2" style="max-width:260px">
            <option value="">-- Aucune (désassocier) --</option>
            {% for a in all_apps %}<option value="{{ a.id }}">{{ a.nom_court }}</option>{% endfor %}
        </select>
        <button onclick="bulkChangeApp()" class="btn-sm bg-cyber-blue text-black">Appliquer à tous les sélectionnés</button>
    </div>
    <div id="bulk-result" class="text-xs text-gray-400 mt-2"></div>
</div>

<!-- Table -->
<div class="card overflow-x-auto">
    <table class="w-full table-cyber text-xs">
        <thead><tr>
            <th class="p-2 w-8"><input type="checkbox" id="check-all" onchange="toggleAll(this)"></th>
            <th class="text-left p-2">Hostname</th>
            <th class="text-left p-2">Solution applicative</th>
            <th class="p-2">Domaine</th>
            <th class="p-2">Env</th>
            <th class="p-2">Zone</th>
            <th class="p-2">Tier</th>
            <th class="p-2">OS</th>
            <th class="text-left p-2" style="min-width:300px">Exclusions</th>
            <th class="p-2">Action</th>
        </tr></thead>
        <tbody>
        {% for s in servers %}
        <tr id="row-{{ s.id }}" class="border-t border-cyber-border/30">
            <td class="p-2 text-center"><input type="checkbox" class="srv-check" value="{{ s.id }}" onchange="updateBulk()"></td>
            <td class="p-2 font-mono text-cyber-accent">{{ s.hostname }}</td>
            <td class="p-2 text-xs text-gray-300" title="{{ s.application_name or '' }}">{{ (s.application_name or '-')[:40] }}</td>
            <td class="p-2 text-center text-gray-400">{{ s.domain_name or '-' }}</td>
            <td class="p-2 text-center">{{ s.env_name or '-' }}</td>
            <td class="p-2 text-center">{{ s.zone_name or '-' }}</td>
            <td class="p-2 text-center">{{ s.tier or '-' }}</td>
            <td class="p-2 text-center">{{ s.os_family or '-' }}</td>
            <td class="p-2">
                <textarea id="excl-{{ s.id }}" rows="2" class="w-full font-mono text-xs" placeholder="ex: oracle* tomcat*  (un ou plusieurs patterns séparés par espace ou retour ligne)" style="resize:vertical;min-height:36px">{{ s.patch_excludes or '' }}</textarea>
            </td>
            <td class="p-2 text-center">
                <button onclick="saveExcl({{ s.id }})" class="btn-sm bg-cyber-border text-cyber-accent">Sauver</button>
                <span id="status-{{ s.id }}" class="text-xs ml-1"></span>
            </td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

<!-- Pagination -->
{% if total_pages > 1 %}
<div class="flex justify-center gap-2 mt-4">
    {% for p in range(1, total_pages + 1) %}
    <a href="?page={{ p }}{% for k,v in filters.items() %}{% if v %}&{{ k }}={{ v }}{% endif %}{% endfor %}"
       class="btn-sm {% if p == page %}bg-cyber-accent text-black{% else %}bg-cyber-border text-gray-300{% endif %} px-2 py-1">{{ p }}</a>
    {% endfor %}
</div>
{% endif %}

<script>
function toggleAll(cb) {
    document.querySelectorAll('.srv-check').forEach(c => c.checked = cb.checked);
    updateBulk();
}

function updateBulk() {
    const ids = Array.from(document.querySelectorAll('.srv-check:checked')).map(c => parseInt(c.value));
    const bar = document.getElementById('bulk-bar');
    const count = document.getElementById('bulk-count');
    count.textContent = ids.length;
    bar.style.display = ids.length > 0 ? 'flex' : 'none';
    window._selectedIds = ids;
}

function saveExcl(id) {
    const inp = document.getElementById('excl-' + id);
    const status = document.getElementById('status-' + id);
    status.textContent = '…'; status.className = 'text-xs ml-1 text-gray-400';
    const fd = new FormData();
    fd.append('patch_excludes', inp.value);
    fetch('/patching/config-exclusions/' + id + '/save', {method: 'POST', credentials: 'same-origin', body: fd})
        .then(r => r.json())
        .then(d => {
            if (d.ok) {
                status.textContent = d.itop && d.itop.pushed ? '✓ iTop' : '⚠ local';
                status.className = 'text-xs ml-1 ' + (d.itop && d.itop.pushed ? 'text-cyber-green' : 'text-cyber-yellow');
                status.title = d.itop ? d.itop.msg : '';
            } else {
                status.textContent = '✗';
                status.className = 'text-xs ml-1 text-cyber-red';
                status.title = d.msg || '';
            }
        })
        .catch(e => { status.textContent = '✗'; status.className = 'text-xs ml-1 text-cyber-red'; status.title = e.message; });
}

function bulkChangeApp() {
    const ids = window._selectedIds || [];
    const app = document.getElementById('bulk-app').value;
    const appName = document.getElementById('bulk-app').selectedOptions[0].text;
    if (!ids.length) return alert('Aucun serveur sélectionné');
    if (!confirm('Changer solution applicative vers "' + appName + '" sur ' + ids.length + ' serveur(s) ?')) return;
    const res = document.getElementById('bulk-result');
    res.textContent = 'En cours...'; res.className = 'text-xs text-gray-400 mt-2';
    fetch('/patching/config-exclusions/bulk-application', {
        method: 'POST', credentials: 'same-origin',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({server_ids: ids, application_id: app})
    })
    .then(r => r.json())
    .then(d => {
        if (d.ok) {
            res.innerHTML = '✓ ' + d.updated + ' serveurs → ' + d.app_name + ' — iTop: <b class="text-cyber-green">' + d.itop_pushed + '</b> OK / <b class="text-cyber-red">' + d.itop_errors + '</b> KO';
            res.className = 'text-xs mt-2';
            setTimeout(() => location.reload(), 2000);
        } else {
            res.textContent = '✗ ' + (d.msg || 'Erreur'); res.className = 'text-xs text-cyber-red mt-2';
        }
    })
    .catch(e => { res.textContent = '✗ ' + e.message; res.className = 'text-xs text-cyber-red mt-2'; });
}

function bulkAction(action) {
    const ids = window._selectedIds || [];
    const pattern = document.getElementById('bulk-pattern').value.trim();
    if (!ids.length) return alert('Aucun serveur sélectionné');
    if (action !== 'replace' && !pattern) return alert('Saisir un pattern');
    const label = action === 'add' ? 'Ajouter' : action === 'remove' ? 'Retirer' : 'Remplacer tout par';
    if (!confirm(label + ' "' + pattern + '" sur ' + ids.length + ' serveur(s) ?')) return;
    const res = document.getElementById('bulk-result');
    res.textContent = 'En cours...'; res.className = 'text-xs text-gray-400 ml-2';
    fetch('/patching/config-exclusions/bulk', {
        method: 'POST', credentials: 'same-origin',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({server_ids: ids, pattern: pattern, action: action})
    })
    .then(r => r.json())
    .then(d => {
        if (d.ok) {
            res.innerHTML = '✓ ' + d.updated + ' serveurs mis à jour — iTop: <b class="text-cyber-green">' + d.itop_pushed + '</b> OK / <b class="text-cyber-red">' + d.itop_errors + '</b> KO';
            res.className = 'text-xs ml-2';
            setTimeout(() => location.reload(), 2000);
        } else {
            res.textContent = '✗ ' + (d.msg || 'Erreur'); res.className = 'text-xs text-cyber-red ml-2';
        }
    })
    .catch(e => { res.textContent = '✗ ' + e.message; res.className = 'text-xs text-cyber-red ml-2'; });
}
</script>
{% endblock %}
