{% extends "base.html" %}
{% block title %}QuickWin #{{ run.id }}{% endblock %}

{% set STEPS = [
    ("draft", "Brouillon", "#94a3b8"),
    ("prereq", "Pr\u00e9requis", "#00d4ff"),
    ("snapshot", "Snapshot", "#a78bfa"),
    ("patching", "Patching", "#ffcc00"),
    ("result", "R\u00e9sultats", "#00ff88"),
    ("completed", "Termin\u00e9", "#10b981"),
] %}
{% set current_step_idx = namespace(val=0) %}
{% for s in STEPS %}{% if s[0] == run.status %}{% set current_step_idx.val = loop.index0 %}{% endif %}{% endfor %}
{% set can_modify = run.status in ('draft', 'prereq') %}

{% macro qs(hp=hp_page, pp=p_page) -%}
?hp_page={{ hp }}&p_page={{ pp }}&per_page={{ per_page }}&search={{ filters.search or '' }}&status={{ filters.status or '' }}&domain={{ filters.domain or '' }}
{%- endmacro %}

{% block content %}
<div class="flex items-center justify-between mb-4">
    <div>
        <a href="/quickwin" class="text-xs text-gray-500 hover:text-gray-300">&larr; Retour campagnes</a>
        <h1 class="text-xl font-bold" style="color:#00d4ff">{{ run.label }}</h1>
        <p class="text-xs text-gray-500">S{{ '%02d'|format(run.week_number) }} {{ run.year }} &mdash; Cr&eacute;&eacute; par {{ run.created_by_name or '?' }}</p>
    </div>
    <div class="flex gap-2 items-center">
        <a href="/patching/correspondance" class="btn-sm" style="background:#1e3a5f;color:#a78bfa;padding:4px 14px;text-decoration:none">Correspondance</a>
        <a href="/patching/validations?campaign_id={{ run.id }}" class="btn-sm" style="background:#1e3a5f;color:#00ff88;padding:4px 14px;text-decoration:none">Validations</a>
        <a href="/quickwin/{{ run.id }}/logs" class="btn-sm" style="background:#1e3a5f;color:#94a3b8;padding:4px 14px;text-decoration:none">Logs</a>
        <form method="post" action="/quickwin/{{ run.id }}/delete" onsubmit="return confirm('Supprimer cette campagne ?')">
            <button class="btn-sm btn-danger" style="padding:4px 12px">Supprimer</button>
        </form>
    </div>
</div>

{% if msg %}
<div style="background:#1a5a2e;color:#8f8;padding:8px 16px;border-radius:6px;margin-bottom:12px;font-size:0.85rem">{{ msg }}</div>
{% endif %}

<!-- Step Progress Bar -->
<div class="card mb-4" style="padding:16px 20px">
    <div style="display:flex;align-items:center;gap:0">
        {% for step_id, step_label, step_color in STEPS %}
        {% set idx = loop.index0 %}
        {% set is_current = (step_id == run.status) %}
        {% set is_done = (idx < current_step_idx.val) %}
        <div style="flex:1;text-align:center;position:relative">
            <div style="width:32px;height:32px;border-radius:50%;margin:0 auto 4px;display:flex;align-items:center;justify-content:center;font-weight:bold;font-size:0.8rem;
                {% if is_done %}background:{{ step_color }};color:#0a0e17{% elif is_current %}background:{{ step_color }};color:#0a0e17;box-shadow:0 0 12px {{ step_color }}{% else %}background:#1e3a5f;color:#4a5568{% endif %}">
                {% if is_done %}&check;{% else %}{{ idx + 1 }}{% endif %}
            </div>
            <div style="font-size:0.7rem;{% if is_current %}color:{{ step_color }};font-weight:bold{% elif is_done %}color:#94a3b8{% else %}color:#4a5568{% endif %}">{{ step_label }}</div>
        </div>
        {% if not loop.last %}
        <div style="flex:1;height:2px;{% if idx < current_step_idx.val %}background:{{ step_color }}{% else %}background:#1e3a5f{% endif %};margin-bottom:18px"></div>
        {% endif %}
        {% endfor %}
    </div>
    <div style="display:flex;justify-content:space-between;margin-top:12px">
        {% if current_step_idx.val > 0 %}
        <form method="post" action="/quickwin/{{ run.id }}/advance">
            <input type="hidden" name="target" value="{{ STEPS[current_step_idx.val - 1][0] }}">
            <button class="btn-sm" style="background:#1e3a5f;color:#94a3b8;padding:4px 14px">&larr; &Eacute;tape pr&eacute;c&eacute;dente</button>
        </form>
        {% else %}<div></div>{% endif %}
        {% if current_step_idx.val < 5 %}
        <form method="post" action="/quickwin/{{ run.id }}/advance">
            <input type="hidden" name="target" value="{{ STEPS[current_step_idx.val + 1][0] }}">
            <button class="btn-primary" style="padding:4px 18px;font-size:0.85rem">&Eacute;tape suivante : {{ STEPS[current_step_idx.val + 1][1] }} &rarr;</button>
        </form>
        {% else %}<div></div>{% endif %}
    </div>
</div>

<!-- KPIs -->
<div style="display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:20px">
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#fff">{{ stats.total }}</div>
        <div class="text-xs text-gray-500">Total</div>
    </div>
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#00d4ff">{{ stats.hprod_total }}</div>
        <div class="text-xs text-gray-500">H-Prod</div>
    </div>
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#ffcc00">{{ stats.prod_total }}</div>
        <div class="text-xs text-gray-500">Prod</div>
    </div>
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#00ff88">{{ stats.patched }}</div>
        <div class="text-xs text-gray-500">Patch&eacute;s</div>
    </div>
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#ff3366">{{ stats.failed }}</div>
        <div class="text-xs text-gray-500">KO</div>
    </div>
    <div class="card p-3 text-center">
        <div class="text-2xl font-bold" style="color:#ff8800">{{ stats.reboot_count }}</div>
        <div class="text-xs text-gray-500">Reboot</div>
    </div>
</div>

<!-- ========== SCOPE SELECTOR (draft + prereq) ========== -->
{% if run.status == 'draft' and scope %}
<div class="card mb-4" style="border-left:3px solid {% if run.status == 'draft' %}#94a3b8{% else %}#00d4ff{% endif %}">
    <div class="p-3" style="border-bottom:1px solid #1e3a5f">
        <h3 style="color:{% if run.status == 'draft' %}#94a3b8{% else %}#00d4ff{% endif %};font-weight:bold;font-size:0.9rem">
            P&eacute;rim&egrave;tre de la campagne
        </h3>
        <p class="text-xs text-gray-500 mt-1">Cochez les domaines et zones &agrave; inclure. Les serveurs hors p&eacute;rim&egrave;tre seront marqu&eacute;s &laquo;&nbsp;Exclu&nbsp;&raquo;.</p>
    </div>
    <form method="post" action="/quickwin/{{ run.id }}/apply-scope" id="scope-form" style="padding:16px">
        <input type="hidden" name="scope_domains" id="h-scope-domains" value="">
        <input type="hidden" name="scope_zones" id="h-scope-zones" value="">
        <div style="display:grid;grid-template-columns:2fr 1fr;gap:20px;margin-bottom:14px">
            <!-- Domaines -->
            <div>
                <div class="text-xs font-bold text-gray-400 mb-2">DOMAINES</div>
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:#0d1520;border-radius:6px;padding:8px 10px">
                {% for d in scope.domains %}
                {% set active = scope.dom_active.get(d, 0) %}
                {% set total = scope.dom_counts.get(d, 0) %}
                <label style="display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-size:0.82rem;color:#cbd5e1">
                    <input type="checkbox" class="scope-dom" value="{{ d }}" {% if active > 0 %}checked{% endif %}>
                    {{ d }}
                    <span style="color:#4a5568;font-size:0.7rem">({{ total }})</span>
                    {% if active > 0 and active < total %}<span style="color:#ffcc00;font-size:0.65rem">{{ active }} actifs</span>{% endif %}
                </label>
                {% endfor %}
                </div>
            </div>
            <!-- Zones -->
            <div>
                <div class="text-xs font-bold text-gray-400 mb-2">ZONES</div>
                <div style="background:#0d1520;border-radius:6px;padding:8px 10px">
                {% for z in scope.zones %}
                {% set active = scope.zone_active.get(z, 0) %}
                {% set total = scope.zone_counts.get(z, 0) %}
                <label style="display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-size:0.82rem;color:#cbd5e1">
                    <input type="checkbox" class="scope-zone" value="{{ z }}" {% if active > 0 %}checked{% endif %}>
                    {{ z }}
                    <span style="color:#4a5568;font-size:0.7rem">({{ total }})</span>
                    {% if active > 0 and active < total %}<span style="color:#ffcc00;font-size:0.65rem">{{ active }} actifs</span>{% endif %}
                </label>
                {% endfor %}
                </div>
            </div>
        </div>
        <div class="flex gap-3 items-center">
            <button type="submit" class="btn-primary" style="padding:6px 20px;font-size:0.9rem"
                    onclick="return prepareScopeForm()">
                Appliquer le p&eacute;rim&egrave;tre
            </button>
            <span class="text-xs text-gray-500" id="scope-preview"></span>
        </div>
    </form>
</div>
{% endif %}

<!-- Step-specific content -->

{% if run.status == 'prereq' %}
<div class="card mb-4" style="border-left:3px solid #00d4ff;padding:16px">
    <h3 style="color:#00d4ff;font-weight:bold;margin-bottom:8px">V&eacute;rification des pr&eacute;requis</h3>
    <p class="text-xs text-gray-400 mb-3">V&eacute;rifie : r&eacute;solution DNS, SSH (PSMP/Key), Satellite/YUM, espace disque (&lt;90%)</p>
    <div style="display:flex;gap:16px;margin-bottom:12px">
        <div>
            <span class="badge badge-green">{{ step_hp.prereq_ok }} OK</span>
            <span class="badge badge-red">{{ step_hp.prereq_ko }} KO</span>
            <span class="badge badge-gray">{{ step_hp.prereq_pending }} en attente</span>
            <span class="text-xs text-gray-500 ml-2">(H-Prod)</span>
        </div>
    </div>
    <div class="flex gap-2 mb-3">
        <button id="btn-check-hprod" class="btn-primary" style="padding:6px 18px;font-size:0.85rem"
                onclick="startPrereqStream('hprod')">Lancer check H-Prod</button>
        {% if prod_ok %}
        <button id="btn-check-prod" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#ffcc00;color:#0a0e17"
                onclick="startPrereqStream('prod')">Lancer check Prod</button>
        {% endif %}
        <button id="btn-stop" style="display:none;background:#ff3366;color:#fff;padding:6px 18px;font-size:0.85rem;border-radius:6px;cursor:pointer"
                onclick="stopPrereqStream()">Arr&ecirc;ter</button>
    </div>
    <!-- Terminal -->
    <div id="prereq-terminal" style="display:none">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
            <span id="prereq-progress" class="text-xs text-gray-400"></span>
            <span id="prereq-stats" class="text-xs"></span>
        </div>
        <div style="background:#000;border:1px solid #1e3a5f;border-radius:6px;padding:8px;font-family:monospace;font-size:0.75rem;max-height:350px;overflow-y:auto;color:#8f8" id="prereq-log"></div>
    </div>
</div>
{% endif %}

{% if run.status == 'snapshot' %}
<div class="card mb-4" style="border-left:3px solid #a78bfa;padding:16px">
    <h3 style="color:#a78bfa;font-weight:bold;margin-bottom:8px">Snapshots VM</h3>
    <p class="text-xs text-gray-400 mb-3">Connexion vSphere &rarr; recherche VM &rarr; snapshot automatique. Les serveurs physiques sont ignor&eacute;s (v&eacute;rifier backup Commvault).</p>
    <div style="display:flex;gap:16px;margin-bottom:12px">
        <div>
            <span class="badge badge-green">{{ step_hp.snap_ok }} fait(s)</span>
            <span class="badge badge-gray">{{ step_hp.snap_pending }} en attente</span>
            <span class="text-xs text-gray-500 ml-2">(H-Prod)</span>
        </div>
    </div>
    <div class="flex gap-2 mb-3" style="flex-wrap:wrap;align-items:center">
        <button id="btn-snap-hprod" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#a78bfa;color:#0a0e17"
                onclick="startSnapshotStream('hprod')">Prendre Snapshots H-Prod</button>
        {% if prod_ok %}
        <button id="btn-snap-prod" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#ffcc00;color:#0a0e17"
                onclick="startSnapshotStream('prod')">Prendre Snapshots Prod</button>
        {% endif %}
        <form method="post" action="/quickwin/{{ run.id }}/snapshot/mark-all" style="display:inline">
            <input type="hidden" name="branch" value="hprod">
            <button class="btn-sm" style="background:#1e3a5f;color:#a78bfa;padding:4px 14px">Tout marquer fait (H-Prod)</button>
        </form>
        <button id="btn-snap-stop" style="display:none;background:#ff3366;color:#fff;padding:6px 18px;font-size:0.85rem;border-radius:6px;cursor:pointer"
                onclick="stopSnapshotStream()">Arr&ecirc;ter</button>
        <span class="text-xs text-gray-500" style="margin-left:8px">Ordre vCenter : H-Prod = Senlis &rarr; Nanterre &rarr; DR | Prod = Nanterre &rarr; Senlis &rarr; DR</span>
    </div>
    <!-- Terminal snapshot -->
    <div id="snap-terminal" style="display:none">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
            <span id="snap-progress" class="text-xs text-gray-400"></span>
            <span id="snap-stats" class="text-xs"></span>
        </div>
        <div style="background:#000;border:1px solid #1e3a5f;border-radius:6px;padding:8px;font-family:monospace;font-size:0.75rem;max-height:350px;overflow-y:auto;color:#8f8" id="snap-log"></div>
    </div>
</div>
{% endif %}

{% if run.status == 'patching' %}

{% if prod_ok and stats.prod_total > 0 %}
{# Alerte validations hors-prod non validées avant de patcher prod #}
{% if not validations_ok %}
<div class="card mb-4" style="border-left:3px solid #ff3366;padding:16px;background:#5a1a1a22">
    <h3 style="color:#ff3366;font-weight:bold;margin-bottom:8px">⚠ Validations hors-prod requises avant la production</h3>
    <p class="text-xs text-gray-300 mb-2">Les non-prod suivants ne sont pas validés. Marquer leur validation dans <a href="/patching/validations?status=en_attente" class="text-cyber-accent hover:underline">/patching/validations</a> avant de patcher les prods correspondants.</p>
    <div class="text-xs" style="max-height:180px;overflow-y:auto">
        <table class="w-full table-cyber">
            <thead><tr><th class="text-left p-1">Prod</th><th class="text-left p-1">Hors-prod bloquant</th><th class="p-1">Statut</th></tr></thead>
            <tbody>
            {% for b in validations_blockers %}
            <tr class="border-t border-cyber-border/30">
                <td class="p-1 font-mono text-cyber-green">{{ b.prod_hostname }}</td>
                <td class="p-1 font-mono text-cyber-yellow">{{ b.nonprod_hostname }}</td>
                <td class="p-1 text-center">
                    {% if b.status == 'en_attente' %}<span class="badge badge-yellow">En attente</span>
                    {% elif b.status == 'validated_ko' %}<span class="badge badge-red">KO</span>
                    {% elif b.status == 'aucun_patching' %}<span class="badge badge-gray">Pas de patching</span>
                    {% else %}<span class="badge badge-gray">{{ b.status }}</span>{% endif %}
                </td>
            </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
    <p class="text-xs text-gray-500 mt-2">{{ validations_blockers|length }} bloquant(s) — vous pouvez continuer mais il est recommandé d'obtenir les validations d'abord.</p>
</div>
{% endif %}
<!-- Prereq + Snapshot Prod (si pas encore faits) -->
<div class="card mb-4" style="border-left:3px solid #ff8800;padding:16px">
    <h3 style="color:#ff8800;font-weight:bold;margin-bottom:8px">Pr&eacute;paration Production</h3>
    <p class="text-xs text-gray-400 mb-3">Avant de patcher la prod, lancez les checks prereq et snapshots sur les serveurs production.</p>
    <div class="flex gap-2 mb-3" style="flex-wrap:wrap;align-items:center">
        <button id="btn-check-prod-p" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#ff8800;color:#0a0e17"
                onclick="startPrereqStream('prod')">Check Prereq Prod</button>
        <button id="btn-stop-prereq-prod" style="display:none;background:#ff3366;color:#fff;padding:6px 18px;font-size:0.85rem;border-radius:6px;cursor:pointer"
                onclick="stopPrereqStream()">Arr&ecirc;ter</button>
        <button id="btn-snap-prod-p" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#a78bfa;color:#0a0e17"
                onclick="startSnapshotStream('prod')">Prendre Snapshots Prod</button>
        <button id="btn-snap-stop-prod" style="display:none;background:#ff3366;color:#fff;padding:6px 18px;font-size:0.85rem;border-radius:6px;cursor:pointer"
                onclick="stopSnapshotStream()">Arr&ecirc;ter</button>
        <form method="post" action="/quickwin/{{ run.id }}/snapshot/mark-all">
            <input type="hidden" name="branch" value="prod">
            <button class="btn-sm" style="background:#a78bfa22;color:#a78bfa;padding:4px 14px">Tout marquer snap OK (prod)</button>
        </form>
    </div>
    <!-- Terminal prereq prod -->
    <div id="prereq-terminal" style="display:none;margin-bottom:12px">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
            <span id="prereq-progress" class="text-xs text-gray-400"></span>
            <span id="prereq-stats" class="text-xs"></span>
        </div>
        <div style="background:#000;border:1px solid #1e3a5f;border-radius:6px;padding:8px;font-family:monospace;font-size:0.75rem;max-height:350px;overflow-y:auto;color:#8f8" id="prereq-log"></div>
    </div>
    <!-- Terminal snapshot prod -->
    <div id="snap-terminal" style="display:none">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
            <span id="snap-progress" class="text-xs text-gray-400"></span>
            <span id="snap-stats" class="text-xs"></span>
        </div>
        <div style="background:#000;border:1px solid #1e3a5f;border-radius:6px;padding:8px;font-family:monospace;font-size:0.75rem;max-height:350px;overflow-y:auto;color:#8f8" id="snap-log"></div>
    </div>
</div>
{% endif %}

<div class="card mb-4" style="border-left:3px solid #ffcc00;padding:16px">
    <h3 style="color:#ffcc00;font-weight:bold;margin-bottom:8px">Ex&eacute;cution du patching</h3>
    <p class="text-xs text-gray-400 mb-3">&Eacute;tape 1 : G&eacute;n&eacute;rer les commandes. &Eacute;tape 2 : V&eacute;rifier. &Eacute;tape 3 : Ex&eacute;cuter via SSH.</p>

    <!-- Boutons generation -->
    <div class="flex gap-2 mb-3" style="flex-wrap:wrap;align-items:center">
        <form method="post" action="/quickwin/{{ run.id }}/build-commands">
            <input type="hidden" name="branch" value="hprod">
            <button class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#ffcc00;color:#0a0e17">1. G&eacute;n&eacute;rer commandes H-Prod</button>
        </form>
        {% if prod_ok %}
        <form method="post" action="/quickwin/{{ run.id }}/build-commands">
            <input type="hidden" name="branch" value="prod">
            <button class="btn-primary" style="padding:6px 18px;font-size:0.85rem;background:#ff8800;color:#0a0e17">1. G&eacute;n&eacute;rer commandes Prod</button>
        </form>
        {% endif %}
        <button class="btn-sm" style="background:#1e3a5f;color:#ffcc00;padding:4px 14px" onclick="loadCommands('hprod')">Voir commandes H-Prod</button>
        {% if prod_ok %}
        <button class="btn-sm" style="background:#1e3a5f;color:#ff8800;padding:4px 14px" onclick="loadCommands('prod')">Voir commandes Prod</button>
        {% endif %}
    </div>

    <!-- Tableau commandes (charge en JS) -->
    <div id="cmd-panel" style="display:none;margin-bottom:16px">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
            <h4 id="cmd-title" class="text-sm font-bold" style="color:#ffcc00"></h4>
            <div class="flex gap-2">
                <button id="btn-exec-patch" class="btn-primary" style="padding:6px 20px;font-size:0.85rem;background:#ff3366;color:#fff"
                        onclick="confirmExec()">2. Ex&eacute;cuter les commandes</button>
                <button id="btn-patch-stop" style="display:none;background:#ff3366;color:#fff;padding:6px 18px;font-size:0.85rem;border-radius:6px;cursor:pointer"
                        onclick="stopPatchStream()">Arr&ecirc;ter</button>
            </div>
        </div>
        <div style="max-height:250px;overflow-y:auto;background:#0a0e17;border:1px solid #1e3a5f;border-radius:6px">
            <table class="table-cyber w-full" style="font-size:0.75rem">
                <thead><tr>
                    <th class="px-2 py-1" style="width:150px">Serveur</th>
                    <th class="px-2 py-1">Commande</th>
                </tr></thead>
                <tbody id="cmd-tbody"></tbody>
            </table>
        </div>
    </div>

    <!-- Terminal patching -->
    <div id="patch-terminal" style="display:none">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
            <span id="patch-progress" class="text-xs text-gray-400"></span>
            <span id="patch-stats" class="text-xs"></span>
        </div>
        <div style="background:#000;border:1px solid #1e3a5f;border-radius:6px;padding:8px;font-family:monospace;font-size:0.75rem;max-height:400px;overflow-y:auto;color:#8f8" id="patch-log"></div>
    </div>
</div>
{% endif %}

{% if run.status == 'result' %}
<div class="card mb-4" style="border-left:3px solid #00ff88;padding:16px">
    <h3 style="color:#00ff88;font-weight:bold;margin-bottom:8px">R&eacute;sultats</h3>
    <div style="display:grid;grid-template-columns:repeat(4,1fr);gap:12px">
        <div class="card p-3 text-center" style="border-color:#00ff88">
            <div class="text-xl font-bold" style="color:#00ff88">{{ stats.patched }}</div>
            <div class="text-xs text-gray-500">Patch&eacute;s</div>
        </div>
        <div class="card p-3 text-center" style="border-color:#ff3366">
            <div class="text-xl font-bold" style="color:#ff3366">{{ stats.failed }}</div>
            <div class="text-xs text-gray-500">KO</div>
        </div>
        <div class="card p-3 text-center" style="border-color:#94a3b8">
            <div class="text-xl font-bold" style="color:#94a3b8">{{ stats.pending }}</div>
            <div class="text-xs text-gray-500">En attente</div>
        </div>
        <div class="card p-3 text-center" style="border-color:#ff8800">
            <div class="text-xl font-bold" style="color:#ff8800">{{ stats.reboot_count }}</div>
            <div class="text-xs text-gray-500">Reboot</div>
        </div>
    </div>
</div>
{% endif %}

{% if run.status == 'completed' %}
<div class="card mb-4" style="border-left:3px solid #10b981;padding:16px">
    <h3 style="color:#10b981;font-weight:bold;margin-bottom:8px">Campagne termin&eacute;e</h3>
    <p class="text-xs text-gray-400 mb-3">{{ stats.patched }} patch&eacute;(s), {{ stats.failed }} KO, {{ stats.reboot_count }} reboot(s).</p>
    <a href="/quickwin/{{ run.id }}/report" class="btn-primary" style="padding:6px 18px;font-size:0.85rem;display:inline-block;text-decoration:none">T&eacute;l&eacute;charger le rapport</a>
</div>
{% endif %}

<!-- Filtres table (contextuels selon l'etape) -->
<form method="GET" class="card mb-4" style="padding:10px 16px;display:flex;gap:12px;align-items:center;flex-wrap:wrap">
    <input type="text" name="search" value="{{ filters.search or '' }}" placeholder="Recherche serveur..." style="width:200px">
    <select name="domain" onchange="this.form.submit()" style="width:160px">
        <option value="">Tous domaines</option>
        {% set doms = entries|map(attribute='domaine')|select('string')|unique|sort %}
        {% for d in doms %}<option value="{{ d }}" {% if filters.domain == d %}selected{% endif %}>{{ d }}</option>{% endfor %}
    </select>
    {% if run.status in ('prereq','snapshot','patching','result','completed') %}
    <select name="prereq_filter" onchange="this.form.submit()" style="width:140px">
        <option value="">Prereq: tous</option>
        <option value="ok" {% if filters.prereq == 'ok' %}selected{% endif %}>Prereq OK</option>
        <option value="ko" {% if filters.prereq == 'ko' %}selected{% endif %}>Prereq KO</option>
        <option value="pending" {% if filters.prereq == 'pending' %}selected{% endif %}>Non v&eacute;rifi&eacute;</option>
    </select>
    {% endif %}
    {% if run.status in ('snapshot','patching','result','completed') %}
    <select name="snap_filter" onchange="this.form.submit()" style="width:130px">
        <option value="">Snap: tous</option>
        <option value="ok" {% if filters.snap == 'ok' %}selected{% endif %}>Snap fait</option>
        <option value="pending" {% if filters.snap == 'pending' %}selected{% endif %}>Snap en attente</option>
    </select>
    {% endif %}
    {% if run.status in ('patching','result','completed') %}
    <select name="status" onchange="this.form.submit()" style="width:140px">
        <option value="">Tous statuts</option>
        <option value="pending" {% if filters.status == 'pending' %}selected{% endif %}>En attente</option>
        <option value="patched" {% if filters.status == 'patched' %}selected{% endif %}>Patch&eacute;</option>
        <option value="failed" {% if filters.status == 'failed' %}selected{% endif %}>KO</option>
        <option value="excluded" {% if filters.status == 'excluded' %}selected{% endif %}>Exclu</option>
        <option value="skipped" {% if filters.status == 'skipped' %}selected{% endif %}>Ignor&eacute;</option>
    </select>
    {% endif %}
    <select name="per_page" onchange="this.form.submit()" style="width:130px">
        <option value="">Par page</option>
        {% for n in [14, 25, 50, 100] %}<option value="{{ n }}" {% if per_page == n %}selected{% endif %}>{{ n }}</option>{% endfor %}
    </select>
    <button type="submit" class="btn-primary" style="padding:4px 14px;font-size:0.8rem">Filtrer</button>
    <a href="/quickwin/{{ run.id }}" class="text-xs text-gray-500 hover:text-gray-300">Reset</a>
</form>

{% if not prod_ok %}
<div class="card mb-4" style="border-left:3px solid #ff3366;padding:12px 16px">
    <p style="color:#ff3366;font-size:0.85rem;font-weight:600">Hors-production d'abord : {{ stats.hprod_pending }} serveur(s) hprod en attente.</p>
</div>
{% endif %}

<!-- ========== MACRO: Entry table ========== -->
{% macro entry_table(rows, branch_label, branch_color, branch_key, page_num, total_pages, total_count) %}
<div class="card mb-4">
    <div class="p-3 flex items-center justify-between" style="border-bottom:1px solid #1e3a5f">
        <h2 class="text-sm font-bold" style="color:{{ branch_color }}">{{ branch_label }} ({{ total_count }})</h2>
        <div class="flex gap-1 items-center">
            <span class="badge badge-green">{{ rows|selectattr('status','eq','patched')|list|length }} OK</span>
            <span class="badge badge-red">{{ rows|selectattr('status','eq','failed')|list|length }} KO</span>
            <span class="badge badge-gray">{{ rows|selectattr('status','eq','pending')|list|length }} en attente</span>
            {% if can_modify %}
            <button class="btn-sm" style="background:#ff336622;color:#ff3366;padding:2px 10px;font-size:0.7rem;margin-left:8px"
                    onclick="removeSelected('{{ branch_key }}')">Supprimer s&eacute;lection</button>
            {% endif %}
        </div>
    </div>
    <div class="table-wrap">
    <table class="table-cyber w-full">
        <thead><tr>
            {% if can_modify %}<th class="px-1 py-2" style="width:28px"><input type="checkbox" class="rm-check-all" data-branch="{{ branch_key }}" title="Tout"></th>{% endif %}
            <th class="px-2 py-2">Serveur</th>
            <th class="px-2 py-2">Domaine</th>
            <th class="px-2 py-2">Env</th>
            <th class="px-2 py-2">Statut</th>
            {% if run.status in ('prereq','snapshot','patching','result','completed') %}
            <th class="px-2 py-2">Prereq</th>
            {% endif %}
            {% if run.status in ('snapshot','patching','result','completed') %}
            <th class="px-2 py-2">Snap</th>
            {% endif %}
            <th class="px-2 py-2">Exclusions g&eacute;n.</th>
            <th class="px-2 py-2">Exclusions sp&eacute;c.</th>
            <th class="px-2 py-2">Packages</th>
            <th class="px-2 py-2">Date patch</th>
            <th class="px-2 py-2">Reboot</th>
            <th class="px-2 py-2">Notes</th>
            {% if run.status == 'patching' %}
            <th class="px-2 py-2">Action</th>
            {% endif %}
        </tr></thead>
        <tbody>
        {% for e in rows %}
        <tr data-id="{{ e.id }}">
            {% if can_modify %}<td class="px-1 py-2"><input type="checkbox" class="rm-check rm-{{ branch_key }}" value="{{ e.id }}"></td>{% endif %}
            <td class="px-2 py-2 font-bold" style="color:{{ branch_color }}">{{ e.hostname }}</td>
            <td class="px-2 py-2 text-gray-400">{{ e.domaine or '?' }}</td>
            <td class="px-2 py-2 text-gray-400">{{ e.environnement or '?' }}</td>
            <td class="px-2 py-2">
                {% if e.status == 'patched' %}<span class="badge badge-green">Patch&eacute;</span>
                {% elif e.status == 'failed' %}<span class="badge badge-red">KO</span>
                {% elif e.status == 'in_progress' %}<span class="badge badge-yellow">En cours</span>
                {% elif e.status == 'excluded' %}<span class="badge badge-gray">Exclu</span>
                {% elif e.status == 'skipped' %}<span class="badge badge-gray">Ignor&eacute;</span>
                {% else %}<span class="badge badge-gray">En attente</span>{% endif %}
            </td>
            {% if run.status in ('prereq','snapshot','patching','result','completed') %}
            <td class="px-2 py-2 text-center">
                {% if e.prereq_ok == true %}<span style="color:#00ff88" title="{{ e.prereq_detail }}">&#10003;</span>
                {% elif e.prereq_ok == false %}<span style="color:#ff3366" title="{{ e.prereq_detail }}">&#10007;</span>
                {% else %}<span style="color:#4a5568">&mdash;</span>{% endif %}
            </td>
            {% endif %}
            {% if run.status in ('snapshot','patching','result','completed') %}
            <td class="px-2 py-2 text-center">
                {% if e.snap_done %}<span style="color:#a78bfa">&#10003;</span>
                {% else %}
                    {% if run.status == 'snapshot' %}
                    <form method="post" action="/quickwin/{{ run.id }}/snapshot/mark" style="display:inline">
                        <input type="hidden" name="entry_id" value="{{ e.id }}">
                        <input type="hidden" name="done" value="true">
                        <button class="btn-sm" style="background:#a78bfa22;color:#a78bfa;font-size:0.6rem">Fait</button>
                    </form>
                    {% else %}<span style="color:#4a5568">&mdash;</span>{% endif %}
                {% endif %}
            </td>
            {% endif %}
            <td class="px-2 py-2 text-xs" style="color:#ffcc00;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="{{ e.general_excludes }}">
                <span class="editable" data-id="{{ e.id }}" data-field="general_excludes">{{ e.general_excludes or '—' }}</span>
            </td>
            <td class="px-2 py-2 text-xs" style="color:#ff8800;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="{{ e.specific_excludes }}">
                <span class="editable" data-id="{{ e.id }}" data-field="specific_excludes">{{ e.specific_excludes or '—' }}</span>
            </td>
            <td class="px-2 py-2 text-center">{{ e.patch_packages_count or '—' }}</td>
            <td class="px-2 py-2 text-xs text-gray-500">{{ e.patch_date.strftime('%d/%m %H:%M') if e.patch_date else '—' }}</td>
            <td class="px-2 py-2 text-center">{% if e.reboot_required %}<span style="color:#ff3366">OUI</span>{% else %}—{% endif %}</td>
            <td class="px-2 py-2 text-xs text-gray-500">
                <span class="editable" data-id="{{ e.id }}" data-field="notes">{{ e.notes or '—' }}</span>
            </td>
            {% if run.status == 'patching' %}
            <td class="px-2 py-2">
                {% if e.status == 'pending' and e.prereq_ok and e.snap_done %}
                <div class="flex gap-1">
                    <form method="post" action="/quickwin/{{ run.id }}/mark-patched" style="display:inline">
                        <input type="hidden" name="entry_id" value="{{ e.id }}">
                        <input type="hidden" name="patch_status" value="patched">
                        <button class="btn-sm" style="background:#00ff8822;color:#00ff88;font-size:0.6rem">OK</button>
                    </form>
                    <form method="post" action="/quickwin/{{ run.id }}/mark-patched" style="display:inline">
                        <input type="hidden" name="entry_id" value="{{ e.id }}">
                        <input type="hidden" name="patch_status" value="failed">
                        <button class="btn-sm" style="background:#ff336622;color:#ff3366;font-size:0.6rem">KO</button>
                    </form>
                </div>
                {% endif %}
            </td>
            {% endif %}
        </tr>
        {% endfor %}
        {% if not rows %}<tr><td colspan="16" class="px-2 py-6 text-center text-gray-500">Aucun serveur{% if filters.search or filters.status or filters.domain %} (filtre actif){% endif %}</td></tr>{% endif %}
        </tbody>
    </table>
    </div>
    {% if total_pages > 1 %}
    <div class="flex justify-between items-center p-3 text-sm text-gray-500" style="border-top:1px solid #1e3a5f">
        <span>Page {{ page_num }} / {{ total_pages }} &mdash; {{ total_count }} serveur(s)</span>
        <div class="flex gap-2">
            {% if branch_key == 'hp' %}
                {% if page_num > 1 %}<a href="{{ qs(hp=page_num - 1, pp=p_page) }}" class="btn-sm bg-cyber-border text-gray-300">Pr&eacute;c.</a>{% endif %}
                {% if page_num < total_pages %}<a href="{{ qs(hp=page_num + 1, pp=p_page) }}" class="btn-sm bg-cyber-border text-gray-300">Suiv.</a>{% endif %}
            {% else %}
                {% if page_num > 1 %}<a href="{{ qs(hp=hp_page, pp=page_num - 1) }}" class="btn-sm bg-cyber-border text-gray-300">Pr&eacute;c.</a>{% endif %}
                {% if page_num < total_pages %}<a href="{{ qs(hp=hp_page, pp=page_num + 1) }}" class="btn-sm bg-cyber-border text-gray-300">Suiv.</a>{% endif %}
            {% endif %}
        </div>
    </div>
    {% endif %}
</div>
{% endmacro %}

<!-- H-PROD -->
{{ entry_table(hprod, "HORS-PRODUCTION", "#00d4ff", "hp", hp_page, hp_total_pages, hprod_total) }}

<!-- PROD -->
{% if prod_ok %}
{{ entry_table(prod, "PRODUCTION", "#ffcc00", "pr", p_page, p_total_pages, prod_total) }}
{% endif %}

{% if run.notes %}
<div class="card p-4 mb-4">
    <h3 class="text-xs font-bold text-gray-500 mb-2">NOTES</h3>
    <p class="text-sm text-gray-300">{{ run.notes }}</p>
</div>
{% endif %}

<!-- Hidden remove form -->
<form method="post" action="/quickwin/{{ run.id }}/remove-entries" id="remove-form" style="display:none">
    <input type="hidden" name="entry_ids" id="remove-entry-ids" value="">
</form>

<script>
/* ---- Scope selector: collect checked domains/zones into hidden fields ---- */
function prepareScopeForm() {
    const doms = [...document.querySelectorAll('.scope-dom:checked')].map(c => c.value);
    const zones = [...document.querySelectorAll('.scope-zone:checked')].map(c => c.value);
    if (!doms.length && !zones.length) {
        alert('Sélectionnez au moins un domaine ou une zone');
        return false;
    }
    document.getElementById('h-scope-domains').value = doms.join(',');
    document.getElementById('h-scope-zones').value = zones.join(',');
    return true;
}
/* ---- Scope: live preview of selection ---- */
document.querySelectorAll('.scope-dom, .scope-zone').forEach(cb => {
    cb.addEventListener('change', function() {
        const dc = document.querySelectorAll('.scope-dom:checked').length;
        const dt = document.querySelectorAll('.scope-dom').length;
        const zc = document.querySelectorAll('.scope-zone:checked').length;
        const zt = document.querySelectorAll('.scope-zone').length;
        const el = document.getElementById('scope-preview');
        if (el) el.textContent = dc + '/' + dt + ' domaines, ' + zc + '/' + zt + ' zones';
    });
});

/* ---- Add panel: select-all + prepare form ---- */
const addCheckAll = document.getElementById('add-check-all');
if (addCheckAll) {
    addCheckAll.addEventListener('change', function() {
        document.querySelectorAll('.add-check').forEach(cb => cb.checked = this.checked);
        updateAddCount();
    });
    document.querySelectorAll('.add-check').forEach(cb => {
        cb.addEventListener('change', updateAddCount);
    });
}
function updateAddCount() {
    const cnt = document.querySelectorAll('.add-check:checked').length;
    const el = document.getElementById('add-count');
    if (el) el.textContent = cnt;
}
function prepareAddForm() {
    const ids = [...document.querySelectorAll('.add-check:checked')].map(cb => cb.value);
    if (!ids.length) { alert('Aucun serveur s\u00e9lectionn\u00e9'); return false; }
    document.getElementById('add-server-ids').value = ids.join(',');
    return true;
}

/* ---- Remove: select-all per branch + submit ---- */
document.querySelectorAll('.rm-check-all').forEach(masterCb => {
    masterCb.addEventListener('change', function() {
        const branch = this.dataset.branch;
        document.querySelectorAll('.rm-' + branch).forEach(cb => cb.checked = this.checked);
    });
});
function removeSelected(branch) {
    const ids = [...document.querySelectorAll('.rm-' + branch + ':checked')].map(cb => cb.value);
    if (!ids.length) { alert('Aucun serveur s\u00e9lectionn\u00e9'); return; }
    if (!confirm('Supprimer ' + ids.length + ' serveur(s) de la campagne ?')) return;
    document.getElementById('remove-entry-ids').value = ids.join(',');
    document.getElementById('remove-form').submit();
}

/* ---- Inline edit ---- */
document.querySelectorAll('.editable').forEach(el => {
    el.style.cursor = 'pointer';
    el.addEventListener('dblclick', function() {
        const field = this.dataset.field;
        const id = this.dataset.id;
        const current = this.textContent.trim() === '\u2014' ? '' : this.textContent.trim();
        const input = document.createElement('input');
        input.value = current;
        input.style.cssText = 'background:#0a0e17;border:1px solid #00d4ff;color:#fff;padding:2px 6px;border-radius:4px;font-size:0.75rem;width:100%';
        this.textContent = '';
        this.appendChild(input);
        input.focus();
        input.select();
        const save = () => {
            const val = input.value.trim();
            this.textContent = val || '\u2014';
            fetch('/api/quickwin/entry/update', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({id: parseInt(id), field: field, value: val})
            });
        };
        input.addEventListener('blur', save);
        input.addEventListener('keydown', e => {
            if (e.key === 'Enter') { e.preventDefault(); input.blur(); }
            if (e.key === 'Escape') { this.textContent = current || '\u2014'; }
        });
    });
});

/* ---- SSE Prereq Terminal ---- */
let prereqSource = null;
function startPrereqStream(branch) {
    const terminal = document.getElementById('prereq-terminal');
    const log = document.getElementById('prereq-log');
    const progress = document.getElementById('prereq-progress');
    const stats = document.getElementById('prereq-stats');
    const btnStop = document.getElementById('btn-stop');

    terminal.style.display = 'block';
    log.innerHTML = '';
    const btnStop2 = document.getElementById('btn-stop-prereq-prod');
    if (btnStop) btnStop.style.display = 'inline-block';
    if (btnStop2) btnStop2.style.display = 'inline-block';
    const btnHprod = document.getElementById('btn-check-hprod');
    if (btnHprod) btnHprod.disabled = true;
    const btnProd = document.getElementById('btn-check-prod');
    if (btnProd) btnProd.disabled = true;
    const btnProdP = document.getElementById('btn-check-prod-p');
    if (btnProdP) btnProdP.disabled = true;

    let okCount = 0, koCount = 0;

    prereqSource = new EventSource('/quickwin/{{ run.id }}/prereq-stream?branch=' + branch);
    prereqSource.onmessage = function(ev) {
        const d = JSON.parse(ev.data);
        if (d.type === 'start') {
            addLine(log, '>>> Lancement check ' + d.branch + ' (' + d.total + ' serveurs)', '#00d4ff');
        } else if (d.type === 'progress') {
            progress.textContent = d.idx + '/' + d.total + ' — ' + d.hostname + '...';
        } else if (d.type === 'result') {
            const color = d.ok ? '#00ff88' : '#ff3366';
            const icon = d.ok ? '\u2713' : '\u2717';
            let line = icon + ' ' + d.hostname;
            if (d.fqdn) line += ' (' + d.fqdn + ')';
            line += '  DNS:' + (d.dns?'OK':'KO') + '  SSH:' + (d.ssh?'OK':'KO') + '  SAT:' + (d.sat?'OK':'KO') + '  DISK:' + (d.disk?'OK':'KO');
            if (!d.ok && d.detail) line += '\n   \u2514 ' + d.detail;
            addLine(log, line, color);
            if (d.ok) okCount++; else koCount++;
            stats.innerHTML = '<span style="color:#00ff88">' + okCount + ' OK</span> &mdash; <span style="color:#ff3366">' + koCount + ' KO</span>';
            progress.textContent = d.idx + '/' + d.total;
        } else if (d.type === 'done') {
            addLine(log, '\n>>> Termin\u00e9 : ' + d.ok + ' OK, ' + d.ko + ' KO sur ' + d.total, '#00d4ff');
            stopPrereqStream();
            progress.textContent = 'Termin\u00e9';
        }
    };
    prereqSource.onerror = function() {
        addLine(log, '>>> Connexion interrompue', '#ff3366');
        stopPrereqStream();
    };
}
function stopPrereqStream() {
    if (prereqSource) { prereqSource.close(); prereqSource = null; }
    const btnStop = document.getElementById('btn-stop');
    if (btnStop) btnStop.style.display = 'none';
    const btnStop2 = document.getElementById('btn-stop-prereq-prod');
    if (btnStop2) btnStop2.style.display = 'none';
    const btnHprod = document.getElementById('btn-check-hprod');
    if (btnHprod) btnHprod.disabled = false;
    const btnProd = document.getElementById('btn-check-prod');
    if (btnProd) btnProd.disabled = false;
    const btnProdP = document.getElementById('btn-check-prod-p');
    if (btnProdP) btnProdP.disabled = false;
}
function addLine(container, text, color) {
    const el = document.createElement('div');
    el.style.color = color || '#ccc';
    el.style.whiteSpace = 'pre-wrap';
    el.style.wordBreak = 'break-all';
    el.textContent = text;
    container.appendChild(el);
    container.scrollTop = container.scrollHeight;
}

/* ---- SSE Snapshot Terminal ---- */
let snapSource = null;
function startSnapshotStream(branch) {
    const terminal = document.getElementById('snap-terminal');
    const log = document.getElementById('snap-log');
    const progress = document.getElementById('snap-progress');
    const stats = document.getElementById('snap-stats');
    const btnStop = document.getElementById('btn-snap-stop');

    terminal.style.display = 'block';
    log.innerHTML = '';
    const btnStop2 = document.getElementById('btn-snap-stop-prod');
    if (btnStop) btnStop.style.display = 'inline-block';
    if (btnStop2) btnStop2.style.display = 'inline-block';
    const btnSnapHprod = document.getElementById('btn-snap-hprod');
    if (btnSnapHprod) btnSnapHprod.disabled = true;
    const btnProd = document.getElementById('btn-snap-prod');
    if (btnProd) btnProd.disabled = true;
    const btnProdP = document.getElementById('btn-snap-prod-p');
    if (btnProdP) btnProdP.disabled = true;

    let okCount = 0, koCount = 0;

    snapSource = new EventSource('/quickwin/{{ run.id }}/snapshot-stream?branch=' + branch);
    snapSource.onmessage = function(ev) {
        const d = JSON.parse(ev.data);
        if (d.type === 'start') {
            addLine(log, '>>> Snapshots ' + d.branch + ' : ' + d.vms + ' VMs, ' + d.physical + ' physique(s) ignor\u00e9(s)', '#a78bfa');
            if (d.physical > 0) {
                addLine(log, '\u26a0 ' + d.physical + ' serveur(s) physique(s) : pas de snapshot VM. V\u00e9rifier les backups Commvault.', '#ffcc00');
            }
        } else if (d.type === 'progress') {
            progress.textContent = d.idx + '/' + d.total + ' \u2014 ' + d.hostname + '...';
        } else if (d.type === 'result') {
            const color = d.ok ? '#00ff88' : '#ff3366';
            const icon = d.ok ? '\u2713' : '\u2717';
            let line = icon + ' ' + d.hostname;
            if (d.vcenter) line += ' [' + d.vcenter + ']';
            line += ' \u2014 ' + d.detail;
            addLine(log, line, color);
            if (d.ok) okCount++; else koCount++;
            stats.innerHTML = '<span style="color:#00ff88">' + okCount + ' OK</span> \u2014 <span style="color:#ff3366">' + koCount + ' KO</span>';
            progress.textContent = d.idx + '/' + d.total;
        } else if (d.type === 'done') {
            let summary = '\n>>> Termin\u00e9 : ' + d.ok + ' OK, ' + d.ko + ' KO sur ' + d.total + ' VMs';
            if (d.physical > 0) summary += ' (' + d.physical + ' physiques ignor\u00e9s)';
            addLine(log, summary, '#a78bfa');
            stopSnapshotStream();
            progress.textContent = 'Termin\u00e9';
        }
    };
    snapSource.onerror = function() {
        addLine(log, '>>> Connexion interrompue', '#ff3366');
        stopSnapshotStream();
    };
}
function stopSnapshotStream() {
    if (snapSource) { snapSource.close(); snapSource = null; }
    const btnStop = document.getElementById('btn-snap-stop');
    if (btnStop) btnStop.style.display = 'none';
    const btnStop2 = document.getElementById('btn-snap-stop-prod');
    if (btnStop2) btnStop2.style.display = 'none';
    const btnSnapHprod = document.getElementById('btn-snap-hprod');
    if (btnSnapHprod) btnSnapHprod.disabled = false;
    const btnProd = document.getElementById('btn-snap-prod');
    if (btnProd) btnProd.disabled = false;
    const btnProdP = document.getElementById('btn-snap-prod-p');
    if (btnProdP) btnProdP.disabled = false;
}

/* ---- Patching: load commands + execute via SSE ---- */
let patchBranch = 'hprod';
function loadCommands(branch) {
    patchBranch = branch;
    fetch('/api/quickwin/{{ run.id }}/commands/' + branch)
        .then(r => r.json())
        .then(cmds => {
            const panel = document.getElementById('cmd-panel');
            const tbody = document.getElementById('cmd-tbody');
            const title = document.getElementById('cmd-title');
            title.textContent = cmds.length + ' commande(s) ' + (branch === 'hprod' ? 'H-Prod' : 'Prod');
            tbody.innerHTML = '';
            if (!cmds.length) {
                tbody.innerHTML = '<tr><td colspan="2" class="px-2 py-4 text-center text-gray-500">Aucune commande. G\u00e9n\u00e9rez d\'abord les commandes.</td></tr>';
            }
            cmds.forEach(c => {
                const tr = document.createElement('tr');
                tr.innerHTML = '<td class="px-2 py-1 font-bold" style="color:#00d4ff">' + c.hostname + '</td>'
                    + '<td class="px-2 py-1" style="color:#ffcc00;font-family:monospace;word-break:break-all">' + c.command + '</td>';
                tbody.appendChild(tr);
            });
            panel.style.display = 'block';
        });
}
function confirmExec() {
    if (!confirm('ATTENTION : Ceci va ex\u00e9cuter yum update sur tous les serveurs ' + patchBranch.toUpperCase() + '.\n\nConfirmer l\'ex\u00e9cution ?')) return;
    startPatchStream(patchBranch);
}
let patchSource = null;
function startPatchStream(branch) {
    const terminal = document.getElementById('patch-terminal');
    const log = document.getElementById('patch-log');
    const progress = document.getElementById('patch-progress');
    const stats = document.getElementById('patch-stats');
    const btnStop = document.getElementById('btn-patch-stop');
    const btnExec = document.getElementById('btn-exec-patch');

    terminal.style.display = 'block';
    log.innerHTML = '';
    btnStop.style.display = 'inline-block';
    btnExec.disabled = true;

    let okCount = 0, koCount = 0;

    patchSource = new EventSource('/quickwin/{{ run.id }}/patch-stream?branch=' + branch);
    patchSource.onmessage = function(ev) {
        const d = JSON.parse(ev.data);
        if (d.type === 'start') {
            addLine(log, '>>> Patching ' + d.branch + ' (' + d.total + ' serveurs)', '#ffcc00');
        } else if (d.type === 'progress') {
            const st = d.status === 'connecting' ? 'Connexion SSH...' : 'Ex\u00e9cution yum...';
            progress.textContent = d.idx + '/' + d.total + ' \u2014 ' + d.hostname + ' \u2014 ' + st;
            if (d.status === 'connecting') {
                addLine(log, '\n[' + d.idx + '/' + d.total + '] ' + d.hostname + ' \u2014 connexion...', '#94a3b8');
            } else {
                addLine(log, '    \u2192 ' + d.command, '#ffcc00');
            }
        } else if (d.type === 'result') {
            const color = d.ok ? '#00ff88' : '#ff3366';
            const icon = d.ok ? '\u2713' : '\u2717';
            let line = '    ' + icon + ' ' + d.hostname;
            if (d.packages) line += ' (' + d.packages + ' paquets)';
            if (d.reboot) line += ' [REBOOT REQUIS]';
            if (d.exit_code !== undefined && d.exit_code !== 0) line += ' (exit ' + d.exit_code + ')';
            addLine(log, line, color);
            if (d.detail) {
                const color2 = d.ok ? '#6b7280' : '#ff6688';
                const lines = d.detail.split('\n').filter(l => l.trim());
                lines.forEach(l => addLine(log, '    \u2502 ' + l.trim(), color2));
            }
            if (d.ok) okCount++; else koCount++;
            stats.innerHTML = '<span style="color:#00ff88">' + okCount + ' OK</span> \u2014 <span style="color:#ff3366">' + koCount + ' KO</span>';
            progress.textContent = d.idx + '/' + d.total;
        } else if (d.type === 'done') {
            addLine(log, '\n>>> Termin\u00e9 : ' + d.ok + ' OK, ' + d.ko + ' KO sur ' + d.total, '#ffcc00');
            stopPatchStream();
            progress.textContent = 'Termin\u00e9';
        }
    };
    patchSource.onerror = function() {
        addLine(log, '>>> Connexion interrompue', '#ff3366');
        stopPatchStream();
    };
}
function stopPatchStream() {
    if (patchSource) { patchSource.close(); patchSource = null; }
    document.getElementById('btn-patch-stop').style.display = 'none';
    document.getElementById('btn-exec-patch').disabled = false;
}

/* ---- Auto-load commands if redirected with show_cmds ---- */
(function() {
    const params = new URLSearchParams(window.location.search);
    const showBranch = params.get('show_cmds');
    if (showBranch) loadCommands(showBranch);
})();
</script>
{% endblock %}
