<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ session.label }} — Rapport avec images</title>
    <style>
        * { box-sizing: border-box; font-family: Arial, "Helvetica Neue", sans-serif; }
        @page { size: A4 landscape; margin: 12mm 8mm 12mm 8mm; }
        body { color: #1f2937; font-size: 11px; margin: 0; padding: 16px; background: #fff; }

        /* Barre d'outils à l'écran (cachée à l'impression) */
        .toolbar {
            position: sticky; top: 0; z-index: 10;
            display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
            background: #21409A; color: #fff; padding: 10px 14px; border-radius: 8px; margin-bottom: 16px;
        }
        .toolbar .hint { font-size: 12px; opacity: .9; }
        .toolbar button, .toolbar a.btn {
            background: #fff; color: #21409A; border: 0; border-radius: 6px;
            padding: 7px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
            text-decoration: none; display: inline-block;
        }
        .toolbar button:hover, .toolbar a.btn:hover { background: #eef2ff; }
        .toolbar button:disabled { opacity: .5; cursor: default; }
        #status { font-size: 12px; opacity: .95; }

        h1 { color: #21409A; font-size: 18px; margin: 0 0 2px 0; }
        .meta { color: #6b7280; font-size: 11px; margin: 0 0 14px 0; }
        .meta strong { color: #374151; }
        .card { border: 1px solid #e5e7eb; border-radius: 8px; padding: 18px; max-width: 760px; }
        .card p { margin: 0 0 8px 0; }
        .bar { height: 8px; background: #e5e7eb; border-radius: 999px; overflow: hidden; margin: 10px 0; }
        .bar > i { display: block; height: 100%; width: 0; background: #21409A; transition: width .2s; }

        table { width: 100%; border-collapse: collapse; }
        thead th {
            background: #21409A; color: #fff; text-align: left;
            padding: 5px 6px; font-size: 9px; text-transform: uppercase; letter-spacing: .03em;
        }
        tbody td { padding: 5px 6px; border-bottom: 1px solid #e5e7eb; vertical-align: middle; }
        tbody tr:nth-child(even) { background: #f3f4f6; }
        tbody tr { page-break-inside: avoid; }
        img.photo { width: 150px; height: auto; max-height: 110px; border: 1px solid #e5e7eb; border-radius: 4px; }
        img.photo-vin { width: 230px; height: auto; max-height: 150px; border: 1px solid #e5e7eb; border-radius: 4px; }
        .noimg { color: #9ca3af; font-style: italic; }
        .mono { font-family: "Courier New", monospace; }

        @media print {
            body { padding: 0; }
            .no-print { display: none !important; }
            thead { display: table-header-group; }
        }
    </style>
</head>
<body>
{% if blockedReason is defined and blockedReason %}
    {# Export bloqué : l'inventaire n'est pas validé. On affiche un message plutôt que le rapport. #}
    {% set statusLabels = {'en_cours': 'En cours', 'a_valider': 'À valider', 'valide': 'Validé', 'annule': 'Annulé'} %}
    <div class="card" style="max-width:560px;margin:48px auto;text-align:center;">
        <h1 style="margin:0 0 12px 0;">Export indisponible</h1>
        <p style="font-size:14px;color:#374151;margin:0 0 8px 0;">{{ blockedReason }}</p>
        <p style="font-size:12px;color:#6b7280;margin:16px 0 0 0;">
            Inventaire : <strong>{{ session.label }}</strong><br>
            Statut actuel : <strong>{{ statusLabels[session.status]|default(session.status) }}</strong>
        </p>
    </div>
{% elseif printMode %}
    {# ---------- REPLI : ancienne page imprimable (window.print) ---------- #}
    <div class="toolbar no-print">
        <button type="button" onclick="window.print()">🖨️ Imprimer / Enregistrer en PDF</button>
        <span class="hint">Dans la boîte de dialogue, choisissez « Enregistrer au format PDF » comme destination.</span>
        <span id="status"></span>
    </div>

    <h1>{{ session.label }} — Rapport avec images</h1>
    <p class="meta">
        <strong>{{ session.results|length }}</strong> véhicule{{ session.results|length > 1 ? 's' }}
        {% if session.scanType %} · <strong>{{ session.scanType|scan_type_label }}</strong>{% endif %}
        {% if session.createdAt %} · {{ session.createdAt|date('d/m/Y à H:i') }}{% endif %}
        · Scanné par <strong>{{ session.userEmail }}</strong>
        {% if session.locationNote %} · 📍 {{ session.locationNote }}{% endif %}
        · Concession(s) : <strong>{{ concessionStr }}</strong>
    </p>

    <table>
        <thead>
            <tr>
                <th style="width:4%">#</th>
                <th style="width:24%">Photo VIN</th>
                <th style="width:13%">VIN</th>
                <th style="width:8%">Date VIN</th>
                <th style="width:15%">Photo plaque</th>
                <th style="width:9%">Immat.</th>
                <th style="width:8%">Date plaque</th>
                <th style="width:19%">Commentaire</th>
            </tr>
        </thead>
        <tbody>
            {% for r in session.results %}
                {% set vin = (r.vin ?: r.rawVin) ?: '-' %}
                {% set plate = (r.plate ?: r.rawPlate) ?: '-' %}
                {% set vinUrl = r.vinImageId ? image_url(session, r.vinImageId) : '' %}
                {% set plateUrl = r.plateImageId ? image_url(session, r.plateImageId) : '' %}
                <tr>
                    <td class="mono">{{ loop.index }}</td>
                    <td>{% if vinUrl %}<img class="photo-vin" src="{{ vinUrl }}" alt="" loading="eager">{% else %}<span class="noimg">—</span>{% endif %}</td>
                    <td class="mono">{{ vin }}</td>
                    <td class="mono">{{ r.vinDate|default('-') }}</td>
                    <td>{% if plateUrl %}<img class="photo" src="{{ plateUrl }}" alt="" loading="eager">{% else %}<span class="noimg">—</span>{% endif %}</td>
                    <td class="mono">{{ plate }}</td>
                    <td class="mono">{{ r.plateDate|default('-') }}</td>
                    <td style="white-space: pre-wrap; word-break: break-word;">{{ r.comment|default('') }}</td>
                </tr>
            {% else %}
                <tr><td colspan="8" style="padding:24px;text-align:center;color:#9ca3af;">Aucun véhicule dans cet inventaire.</td></tr>
            {% endfor %}
        </tbody>
    </table>

    {% if session.signature %}
        <div style="margin-top:24px;page-break-inside:avoid;">
            <p style="color:#21409A;font-weight:bold;font-size:13px;margin:0 0 2px 0;">Signature</p>
            {% if session.signatureDate %}<p style="color:#6b7280;font-size:11px;margin:0 0 6px 0;">Signé le {{ session.signatureDate|date('d/m/Y à H:i') }}</p>{% endif %}
            <img src="{{ session.signature }}" alt="Signature" style="display:block;max-width:70mm;max-height:35mm;border-bottom:1px solid #d1d5db;">
        </div>
    {% endif %}

    <script>
        (function () {
            var statusEl = document.getElementById('status');
            var imgs = Array.prototype.slice.call(document.images);
            var total = imgs.length, loaded = 0, printed = false;
            function refresh() { if (statusEl) statusEl.textContent = total ? (loaded + ' / ' + total + ' photos chargées') : ''; }
            function maybePrint() { if (printed) return; printed = true; setTimeout(function () { window.print(); }, 400); }
            function tick() { loaded++; refresh(); if (loaded >= total) maybePrint(); }
            refresh();
            if (total === 0) { maybePrint(); return; }
            imgs.forEach(function (img) {
                if (img.complete) tick();
                else { img.addEventListener('load', tick); img.addEventListener('error', tick); }
            });
            setTimeout(maybePrint, 25000);
        })();
    </script>
{% else %}
    {# ---------- DÉFAUT : téléchargement direct d'un PDF (jsPDF) ---------- #}
    {% set rows = [] %}
    {% for r in session.results %}
        {% set rows = rows|merge([{
            idx: loop.index,
            vin: ((r.vin ?: r.rawVin) ?: '-'),
            plate: ((r.plate ?: r.rawPlate) ?: '-'),
            vinDate: (r.vinDate|default('') ?: ''),
            plateDate: (r.plateDate|default('') ?: ''),
            comment: (r.comment|default('') ?: ''),
            vinUrl: (r.vinImageId ? image_url(session, r.vinImageId) : ''),
            plateUrl: (r.plateImageId ? image_url(session, r.plateImageId) : '')
        }]) %}
    {% endfor %}

    <div class="toolbar no-print">
        <button type="button" id="dl" disabled>⬇️ Télécharger le PDF</button>
        <a class="btn" href="{{ path('app_report_photos_web', {id: session.id, print: 1}) }}">🖨️ Version imprimable</a>
        <span id="status">Préparation…</span>
    </div>

    <h1>{{ session.label }} — Rapport avec images</h1>
    <p class="meta">
        <strong>{{ session.results|length }}</strong> véhicule{{ session.results|length > 1 ? 's' }}
        {% if session.scanType %} · <strong>{{ session.scanType|scan_type_label }}</strong>{% endif %}
        {% if session.createdAt %} · {{ session.createdAt|date('d/m/Y à H:i') }}{% endif %}
        · Scanné par <strong>{{ session.userEmail }}</strong>
        {% if session.locationNote %} · 📍 {{ session.locationNote }}{% endif %}
        · Concession(s) : <strong>{{ concessionStr }}</strong>
    </p>

    <div class="card">
        <p><strong>Génération du PDF en cours…</strong></p>
        <div class="bar"><i id="prog"></i></div>
        <p id="detail" style="color:#6b7280;font-size:12px;">Récupération et réduction des photos…</p>
        <p style="color:#6b7280;font-size:12px;margin-top:12px;">
            Le téléchargement démarre automatiquement dès que le PDF est prêt.
            Si rien ne se passe, cliquez sur « Télécharger le PDF », ou utilisez la « Version imprimable ».
        </p>
    </div>

    <script>
        window.__REPORT__ = {
            filename: {{ ((session.label ~ ' - rapport photos'))|json_encode|raw }},
            title: {{ session.label|json_encode|raw }},
            meta: {{ ([
                (session.results|length ~ ' véhicule' ~ (session.results|length > 1 ? 's' : '')),
                (session.scanType|scan_type_label),
                (session.createdAt ? session.createdAt|date('d/m/Y à H:i') : null),
                ('Par ' ~ session.userEmail),
                (session.locationNote ? ('Lieu : ' ~ session.locationNote) : null),
                ('Concession(s) : ' ~ concessionStr)
            ]|filter(v => v is not null)|join('  ·  '))|json_encode|raw }},
            rows: {{ rows|json_encode|raw }},
            signature: {{ (session.signature ?: null)|json_encode|raw }},
            signatureDate: {{ (session.signatureDate ? session.signatureDate|date('d/m/Y à H:i') : null)|json_encode|raw }}
        };
    </script>
    <script src="/vendor-pdf/jspdf.umd.min.js"></script>
    <script src="/vendor-pdf/jspdf.plugin.autotable.min.js"></script>
    <script>
        (function () {
            var R = window.__REPORT__;
            var statusEl = document.getElementById('status');
            var detailEl = document.getElementById('detail');
            var progEl = document.getElementById('prog');
            var dlBtn = document.getElementById('dl');
            var ready = false;

            function setStatus(t) { if (statusEl) statusEl.textContent = t; }
            function setDetail(t) { if (detailEl) detailEl.textContent = t; }
            function setProg(p) { if (progEl) progEl.style.width = Math.round(p * 100) + '%'; }

            function sanitize(s) {
                return (s || 'rapport-photos').replace(/[^\w.\- ]+/g, '_').replace(/\s+/g, ' ').trim().slice(0, 80) || 'rapport-photos';
            }

            // Décode un blob image en bitmap (createImageBitmap si dispo, sinon <img>).
            function decode(blob) {
                if (window.createImageBitmap) {
                    return createImageBitmap(blob).catch(function () { return viaImg(blob); });
                }
                return viaImg(blob);
            }
            function viaImg(blob) {
                return new Promise(function (resolve, reject) {
                    var url = URL.createObjectURL(blob);
                    var im = new Image();
                    im.onload = function () { resolve(im); URL.revokeObjectURL(url); };
                    im.onerror = function () { URL.revokeObjectURL(url); reject(new Error('img')); };
                    im.src = url;
                });
            }

            // Récupère une photo S3 (CORS), réduit sa définition (largeur = origine / divisor),
            // renvoie { dataUrl, w, h } en JPEG. null si indisponible (n'interrompt pas le rapport).
            function loadReduced(url, divisor, quality) {
                if (!url) return Promise.resolve(null);
                return fetch(url, { mode: 'cors', cache: 'force-cache' })
                    .then(function (resp) { if (!resp.ok) throw new Error('HTTP ' + resp.status); return resp.blob(); })
                    .then(decode)
                    .then(function (bmp) {
                        var ow = bmp.width, oh = bmp.height;
                        if (!ow || !oh) throw new Error('dim');
                        var tw = Math.max(60, Math.round(ow / divisor));
                        var th = Math.max(1, Math.round(oh * (tw / ow)));
                        var c = document.createElement('canvas');
                        c.width = tw; c.height = th;
                        c.getContext('2d').drawImage(bmp, 0, 0, tw, th);
                        if (bmp.close) bmp.close();
                        return { dataUrl: c.toDataURL('image/jpeg', quality), w: tw, h: th };
                    })
                    .catch(function () { return null; });
            }

            async function processAll() {
                var tasks = [];
                R.rows.forEach(function (row) {
                    // Compromis lisibilité/poids : VIN en demi-résolution (div 2, ×2 vs l'ancien /4)
                    // + vignette agrandie ci-dessous → VIN gravé lisible sans alourdir comme la pleine réso.
                    // Plaque : /8 (l'immatriculation reste lisible et le poids reste maîtrisé).
                    tasks.push({ row: row, key: '_vin', url: row.vinUrl, div: 2, q: 0.8 });
                    tasks.push({ row: row, key: '_plate', url: row.plateUrl, div: 8, q: 0.6 });
                });
                var total = tasks.filter(function (t) { return t.url; }).length || 1;
                var done = 0, i = 0, CONC = 6;
                setStatus('Préparation des photos… 0 / ' + total);
                async function worker() {
                    while (i < tasks.length) {
                        var t = tasks[i++];
                        t.row[t.key] = await loadReduced(t.url, t.div, t.q);
                        if (t.url) { done++; setProg(done / total); setStatus('Préparation des photos… ' + done + ' / ' + total); }
                    }
                }
                var ws = [];
                for (var w = 0; w < CONC; w++) ws.push(worker());
                await Promise.all(ws);
            }

            function buildPdf() {
                var jsPDF = window.jspdf.jsPDF;
                var doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' });
                var MARGIN = 8;

                doc.setFontSize(14); doc.setTextColor(33, 64, 154);
                doc.text(R.title || 'Rapport', MARGIN, 13);
                doc.setFontSize(9); doc.setTextColor(107, 114, 128);
                doc.text(R.meta || '', MARGIN, 19, { maxWidth: 281 });

                var VIN_W = 52, PLATE_W = 28, MAXH = 34; // mm — vignette VIN agrandie pour la lisibilité
                // Les colonnes photo portent un objet cellule { content:'', _img } : l'image voyage
                // AVEC la cellule (data.cell.raw._img), on ne ré-indexe pas par numéro de ligne
                // (data.row.index ne correspond pas à l'index du tableau source en pagination).
                var body = R.rows.map(function (row) {
                    return [
                        String(row.idx),
                        { content: '', _img: row._vin || null },
                        row.vin || '-', row.vinDate || '-',
                        { content: '', _img: row._plate || null },
                        row.plate || '-', row.plateDate || '-',
                        row.comment || ''
                    ];
                });

                function dispSize(img, colIdx) {
                    var w = colIdx === 1 ? VIN_W : PLATE_W;
                    var h = img.h * (w / img.w);
                    if (h > MAXH) { h = MAXH; w = img.w * (MAXH / img.h); }
                    return { w: w, h: h };
                }

                doc.autoTable({
                    head: [['#', 'Photo VIN', 'VIN', 'Date VIN', 'Photo plaque', 'Immat.', 'Date plaque', 'Commentaire']],
                    body: body,
                    startY: 23,
                    theme: 'grid',
                    margin: { left: MARGIN, right: MARGIN },
                    styles: { fontSize: 7, cellPadding: 1.5, valign: 'middle', overflow: 'linebreak', lineColor: [229, 231, 235] },
                    headStyles: { fillColor: [33, 64, 154], textColor: 255, fontSize: 7 },
                    alternateRowStyles: { fillColor: [243, 244, 246] },
                    columnStyles: {
                        0: { cellWidth: 8, halign: 'center' },
                        1: { cellWidth: 56, halign: 'center' },
                        2: { cellWidth: 30, font: 'courier' },
                        3: { cellWidth: 22 },
                        4: { cellWidth: 32, halign: 'center' },
                        5: { cellWidth: 24, font: 'courier' },
                        6: { cellWidth: 22 },
                        7: { cellWidth: 'auto' }
                    },
                    didParseCell: function (data) {
                        var raw = data.cell.raw;
                        if (data.section === 'body' && raw && raw._img) {
                            data.cell.styles.minCellHeight = dispSize(raw._img, data.column.index).h + 3;
                        }
                    },
                    didDrawCell: function (data) {
                        var raw = data.cell.raw;
                        if (data.section === 'body' && raw && raw._img) {
                            var d = dispSize(raw._img, data.column.index);
                            var x = data.cell.x + (data.cell.width - d.w) / 2;
                            var y = data.cell.y + (data.cell.height - d.h) / 2;
                            try { doc.addImage(raw._img.dataUrl, 'JPEG', x, y, d.w, d.h); } catch (e) { /* photo illisible : cellule vide */ }
                        }
                    }
                });

                drawSignature(doc);

                doc.save(sanitize(R.filename) + '.pdf');
            }

            // Bloc signature en fin de document : la signature manuscrite (apposée au
            // lancement du scan) et sa date. Placé sous le tableau, ou sur une nouvelle
            // page s'il ne reste pas assez de place.
            function drawSignature(doc) {
                if (!R.signature) return;
                var MARGIN = 8;
                var props = null;
                try { props = doc.getImageProperties(R.signature); } catch (e) { props = null; }
                var imgW = 60, imgH = 24;
                if (props && props.width && props.height) {
                    imgH = imgW * (props.height / props.width);
                    if (imgH > 32) { imgH = 32; imgW = imgH * (props.width / props.height); }
                }
                var pageH = doc.internal.pageSize.getHeight();
                var startY = (doc.lastAutoTable ? doc.lastAutoTable.finalY : 30) + 8;
                var blockH = 7 + imgH + 4;
                if (startY + blockH > pageH - 8) { doc.addPage(); startY = 18; }
                doc.setFontSize(10); doc.setTextColor(33, 64, 154);
                doc.text('Signature', MARGIN, startY);
                if (R.signatureDate) {
                    doc.setFontSize(8); doc.setTextColor(107, 114, 128);
                    doc.text('Signé le ' + R.signatureDate, MARGIN, startY + 4.5);
                }
                try { doc.addImage(R.signature, 'JPEG', MARGIN, startY + 7, imgW, imgH); } catch (e) { /* signature illisible : ignorée */ }
                doc.setDrawColor(209, 213, 219);
                doc.line(MARGIN, startY + 7 + imgH + 2, MARGIN + Math.max(imgW, 60), startY + 7 + imgH + 2);
            }

            async function run() {
                if (!window.jspdf || !window.jspdf.jsPDF || typeof (new window.jspdf.jsPDF()).autoTable !== 'function') {
                    setStatus('Bibliothèque PDF indisponible.');
                    setDetail('Utilisez « Version imprimable » pour enregistrer en PDF.');
                    return;
                }
                try {
                    await processAll();
                    setDetail('Génération du document…');
                    buildPdf();
                    ready = true;
                    dlBtn.disabled = false;
                    setProg(1);
                    setStatus('PDF téléchargé ✔');
                    setDetail('Téléchargement effectué. Cliquez sur « Télécharger le PDF » pour le régénérer si besoin.');
                } catch (e) {
                    console.error(e);
                    setStatus('Erreur de génération.');
                    setDetail('Détail : ' + ((e && e.message) ? e.message : String(e)) + ' — Réessayez ou utilisez « Version imprimable ».');
                }
            }

            dlBtn.addEventListener('click', function () { if (window.jspdf && window.jspdf.jsPDF) buildPdf(); });
            run();
        })();
    </script>
{% endif %}
</body>
</html>
