/**
 * Fichier  : assets/js/pages/dashboard.js
 * Auteur   : KREMER Régis
 * Version  : 2.6.0
 * Date     : 2026-03-01
 * Description : JS — Tableau de bord : KPIs, graphiques, alertes cards produit, activité
 *
 * Changelog :
 *   v2.2.0 — Version initiale
 *   v2.6.0 — Alertes avec photo produit, valorisation chart corrigé, responsive amélioré
 */
const DashPage = {

    async init() {
        const [prods, stock, mvs, warehses, alerts] = await Promise.all([
            Api.products(), Api.stock(), Api.movements(), Api.warehouses(), Api.alerts()
        ]);
        this.data = { prods, stock, mvs, warehses, alerts };
        this.renderKPIs();
        this.renderCharts();
        this.renderActivity();
        this.renderAlertWidget();
        this.renderStockTable();
        this.initWhFilter();
    },

    // ══════════════════════════════════════════════════════════════
    // KPIs
    // ══════════════════════════════════════════════════════════════
    renderKPIs() {
        const { prods, stock, alerts } = this.data;
        const totalProd  = prods.length;
        const totalUnit  = stock.reduce((s, x) => s + (parseInt(x.quantity) || 0), 0);
        const totalValue = stock.reduce((sum, s) => {
            const p = prods.find(x => String(x.id) === String(s.productId));
            return sum + (getBaseCost(p) * (parseInt(s.quantity) || 0));
        }, 0);
        const lowCount = alerts.filter(a => a.triggered).length;

        document.getElementById('kpiRow').innerHTML = `
            <div class="kpi-card blue">
                <div class="kpi-top"><div class="kpi-ico">${Icons.box}</div></div>
                <div class="kpi-val">${totalProd}</div>
                <div class="kpi-lbl">Produits</div>
            </div>
            <div class="kpi-card green">
                <div class="kpi-top"><div class="kpi-ico">${Icons.box}</div></div>
                <div class="kpi-val">${totalUnit}</div>
                <div class="kpi-lbl">Unités totales</div>
            </div>
            <div class="kpi-card orange">
                <div class="kpi-top"><div class="kpi-ico">${Icons.warehouse}</div></div>
                <div class="kpi-val">${totalValue.toFixed(2)}€</div>
                <div class="kpi-lbl">Valeur stock</div>
            </div>
            <div class="kpi-card red">
                <div class="kpi-top"><div class="kpi-ico">${Icons.bell}</div></div>
                <div class="kpi-val">${lowCount}</div>
                <div class="kpi-lbl">Alertes actives</div>
            </div>`;
    },

    // ══════════════════════════════════════════════════════════════
    // GRAPHIQUES
    // ══════════════════════════════════════════════════════════════
    renderCharts() {
        if (window.Chart) {
            this._chartMovements14d();
            this._chartStockByWarehouse();
        } else {
            this._fallbackMovements();
            this._fallbackStockByWarehouse();
        }
    },

    _destroyChart(key) {
        try {
            if (this._charts?.[key]) { this._charts[key].destroy(); delete this._charts[key]; }
        } catch (_) {}
    },

    _chartMovements14d() {
        const c = document.getElementById('dashChartMov');
        if (!c) return;
        const ctx = c.getContext('2d');
        if (!ctx) return;

        const mvs = this.data.mvs || [];
        const today = new Date();
        const labels = [], values = [];

        for (let i = 13; i >= 0; i--) {
            const d = new Date(today);
            d.setDate(today.getDate() - i);
            const key = d.toISOString().slice(0, 10);
            labels.push(d.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit' }));
            values.push(mvs.filter(m => (m.createdAt || m.date || '').slice(0, 10) === key).length);
        }

        this._charts = this._charts || {};
        this._destroyChart('mov');
        this._charts.mov = new Chart(ctx, {
            type: 'bar',
            data: {
                labels,
                datasets: [{
                    label: 'Mouvements',
                    data: values,
                    backgroundColor: 'rgba(59,130,246,0.55)',
                    borderColor: 'rgba(59,130,246,0.9)',
                    borderWidth: 1,
                    borderRadius: 4,
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: { y: { beginAtZero: true, ticks: { precision: 0 } } },
                plugins: { legend: { display: false } }
            }
        });
    },

    _chartStockByWarehouse() {
        const c = document.getElementById('dashChartVal');
        if (!c) return;
        const ctx = c.getContext('2d');
        if (!ctx) return;

        const { prods = [], stock = [], warehses = [] } = this.data;

        // Calculer valeur par magasin
        const byWh = {};
        for (const s of stock) {
            const p = prods.find(x => String(x.id) === String(s.productId));
            const val = getBaseCost(p) * (parseFloat(s.quantity) || 0);
            const wid = String(s.warehouseId || '');
            byWh[wid] = (byWh[wid] || 0) + val;
        }

        const labels = [], values = [], colors = [];
        const palette = [
            'rgba(59,130,246,0.6)', 'rgba(16,185,129,0.6)', 'rgba(245,158,11,0.6)',
            'rgba(239,68,68,0.6)',  'rgba(139,92,246,0.6)', 'rgba(236,72,153,0.6)',
        ];
        let ci = 0;
        for (const w of warehses) {
            const val = parseFloat((byWh[String(w.id)] || 0).toFixed(2));
            labels.push(w.name || ('Magasin ' + w.id));
            values.push(val);
            colors.push(palette[ci++ % palette.length]);
        }

        this._charts = this._charts || {};
        this._destroyChart('val');
        this._charts.val = new Chart(ctx, {
            type: 'bar',
            data: {
                labels,
                datasets: [{
                    label: 'Valeur (€)',
                    data: values,
                    backgroundColor: colors,
                    borderColor: colors.map(c => c.replace('0.6', '0.9')),
                    borderWidth: 1,
                    borderRadius: 4,
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: { y: { beginAtZero: true } },
                plugins: {
                    legend: { display: false },
                    tooltip: { callbacks: { label: ctx => (ctx.raw || 0).toFixed(2) + ' €' } }
                }
            }
        });
    },

    // Fallbacks canvas natif si Chart.js absent
    _fallbackMovements() {
        const c = document.getElementById('dashChartMov');
        if (!c) return;
        const ctx = c.getContext('2d');
        const mvs = this.data.mvs || [];
        const today = new Date();
        const buckets = [];
        for (let i = 13; i >= 0; i--) {
            const d = new Date(today); d.setDate(d.getDate() - i);
            const key = d.toISOString().slice(0, 10);
            buckets.push({ label: key.slice(5), count: mvs.filter(m => (m.date || '').slice(0, 10) === key).length });
        }
        this._drawBars(ctx, c.offsetWidth || 300, 160, buckets.map(b => b.label), buckets.map(b => b.count));
    },

    _fallbackStockByWarehouse() {
        const c = document.getElementById('dashChartVal');
        if (!c) return;
        const ctx = c.getContext('2d');
        const { prods = [], stock = [], warehses = [] } = this.data;
        const byWh = {};
        for (const s of stock) {
            const p = prods.find(x => String(x.id) === String(s.productId));
            const wid = String(s.warehouseId || '');
            byWh[wid] = (byWh[wid] || 0) + getBaseCost(p) * (parseFloat(s.quantity) || 0);
        }
        const entries = warehses.map(w => ({ label: w.name, val: Math.round(byWh[String(w.id)] || 0) }));
        this._drawBars(ctx, c.offsetWidth || 300, 160, entries.map(e => e.label), entries.map(e => e.val));
    },

    _drawBars(ctx, w, h, labels, values) {
        ctx.clearRect(0, 0, w, h);
        const padL = 36, padR = 8, padT = 8, padB = 28;
        const gw = w - padL - padR, gh = h - padT - padB;
        const max = Math.max(1, ...values);
        const n = values.length || 1;
        const gap = 4;
        const barW = Math.max(4, Math.floor((gw - gap * (n - 1)) / n));
        ctx.strokeStyle = '#e5e7eb'; ctx.lineWidth = 1;
        ctx.beginPath(); ctx.moveTo(padL, padT); ctx.lineTo(padL, padT + gh); ctx.lineTo(padL + gw, padT + gh); ctx.stroke();
        ctx.fillStyle = 'rgba(59,130,246,0.55)';
        ctx.font = '10px system-ui';
        ctx.fillStyle = '#6b7280';
        for (let i = 0; i < values.length; i++) {
            const bh = Math.round(((values[i] || 0) / max) * (gh - 2));
            const x = padL + i * (barW + gap);
            const y = padT + gh - bh;
            ctx.fillStyle = 'rgba(59,130,246,0.55)';
            ctx.fillRect(x, y, barW, bh);
            ctx.save(); ctx.translate(x + barW / 2, padT + gh + 10); ctx.rotate(-0.5);
            ctx.textAlign = 'right'; ctx.fillStyle = '#6b7280'; ctx.font = '9px system-ui';
            ctx.fillText(String(labels[i] || '').slice(0, 10), 0, 0); ctx.restore();
        }
        ctx.fillStyle = '#6b7280'; ctx.font = '9px system-ui';
        ctx.fillText(String(max), 2, padT + 10);
    },

    // ══════════════════════════════════════════════════════════════
    // ACTIVITÉ RÉCENTE
    // ══════════════════════════════════════════════════════════════
    renderActivity() {
        const mvs = [...this.data.mvs].sort((a, b) => new Date(b.date) - new Date(a.date)).slice(0, 12);
        const prods = this.data.prods;
        const el = document.getElementById('activityFeed');
        if (!el) return;
        if (!mvs.length) { el.innerHTML = '<div class="act-empty">Aucune activité encore</div>'; return; }

        const lbls = { add: 'Ajout', remove: 'Sortie', transfer: 'Transfert', entry: 'Entrée stock', inventory: 'Inventaire' };
        el.innerHTML = mvs.map(m => {
            const p = prods.find(x => String(x.id) === String(m.productId));
            const name = p ? p.name : '?';
            const d = new Date(m.date);
            const timeStr = d.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' });
            return `<div class="act-item">
                <div class="act-dot ${m.type}"></div>
                <div class="act-txt">
                    <strong>${name} — ${lbls[m.type] || m.type} (${m.quantity}u)</strong>
                    <span>${m.operator || '?'}${m.site ? ' · ' + m.site : ''}</span>
                </div>
                <div class="act-time">${timeStr}</div>
            </div>`;
        }).join('');
    },

    // ══════════════════════════════════════════════════════════════
    // ALERTES ACTIVES — cartes produit avec photo
    // ══════════════════════════════════════════════════════════════
    renderAlertWidget() {
        const triggered = this.data.alerts.filter(a => a.triggered);
        const prods     = this.data.prods;
        const whs       = this.data.warehses;
        const el        = document.getElementById('alertsWidget');
        if (!el) return;

        if (!triggered.length) {
            el.innerHTML = `<div class="dash-alerts-ok">
                <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="currentColor" stroke-width="1.5">
                    <path d="M22 11.08V12a10 10 0 11-5.93-9.14"/>
                    <polyline points="22 4 12 14.01 9 11.01"/>
                </svg>
                <span>Tout est en ordre</span>
            </div>`;
            return;
        }

        el.innerHTML = triggered.map(a => {
            const p   = prods.find(x => String(x.id) === String(a.productId));
            const w   = whs.find(x => String(x.id) === String(a.warehouseId));
            const name = p ? p.name : '?';
            const sku  = p ? (p.sku || '') : '';
            const isMin = a.type === 'min';
            const qty  = a.currentQty ?? '?';
            const thr  = a.threshold;
            const imgSrc = p?.image ? `/sm/${p.image}` : null;

            const imgHtml = imgSrc
                ? `<img src="${imgSrc}" alt="${name}" class="dash-alert-img" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">`
                + `<div class="dash-alert-img-fallback" style="display:none">${Icons.box}</div>`
                : `<div class="dash-alert-img-fallback">${Icons.box}</div>`;

            const badgeCls = isMin ? 'dash-alert-badge-min' : 'dash-alert-badge-max';
            const badgeLbl = isMin ? '↓ MIN' : '↑ MAX';
            const detailLbl = isMin
                ? `Stock bas : <strong>${qty}</strong> / seuil <strong>${thr}</strong>`
                : `Stock élevé : <strong>${qty}</strong> / seuil <strong>${thr}</strong>`;

            return `<div class="dash-alert-card">
                <div class="dash-alert-thumb">${imgHtml}</div>
                <div class="dash-alert-body">
                    <div class="dash-alert-header">
                        <span class="dash-alert-name">${name}</span>
                        <span class="dash-alert-badge ${badgeCls}">${badgeLbl}</span>
                    </div>
                    ${sku ? `<div class="dash-alert-sku">${sku}</div>` : ''}
                    ${w ? `<div class="dash-alert-wh">${w.name}</div>` : ''}
                    <div class="dash-alert-detail">${detailLbl}</div>
                </div>
            </div>`;
        }).join('');
    },

    // ══════════════════════════════════════════════════════════════
    // FILTRE MAGASIN + TABLE STOCK
    // ══════════════════════════════════════════════════════════════
    initWhFilter() {
        const sel = document.getElementById('dashWh');
        if (!sel) return;
        sel.innerHTML = '<option value="">Tous magasins</option>' +
            this.data.warehses.map(w => `<option value="${w.id}">${w.name}</option>`).join('');
        sel.onchange = () => this.renderStockTable();
    },

    renderStockTable() {
        const wid   = document.getElementById('dashWh')?.value || '';
        let stock   = this.data.stock;
        if (wid) stock = stock.filter(s => String(s.warehouseId) === String(wid));
        const { prods, warehses: whs, alerts } = this.data;
        const tbody = document.getElementById('dashStockBody');
        if (!tbody) return;
        if (!stock.length) {
            tbody.innerHTML = '<tr><td colspan="9" class="tbl-empty">Aucun stock enregistré</td></tr>';
            return;
        }
        tbody.innerHTML = stock.map(s => {
            const p = prods.find(x => String(x.id) === String(s.productId));
            const w = whs.find(x => String(x.id) === String(s.warehouseId));
            const qty = parseInt(s.quantity) || 0;
            const baseCost = getBaseCost(p);
            const val = (qty * baseCost).toFixed(2);
            const min = s.minStock, max = s.maxStock;
            let statusCls = 'badge-green', statusLbl = 'Normal';
            if (min != null && qty <= min) { statusCls = 'badge-red'; statusLbl = 'Bas'; }
            if (max != null && qty >= max) { statusCls = 'badge-orange'; statusLbl = 'Élevé'; }
            return `<tr>
                <td><strong>${p ? p.name : '?'}</strong></td>
                <td class="col-mono">${p ? (p.sku || '—') : '—'}</td>
                <td>${w ? w.name : '?'}</td>
                <td class="cell-number"><strong>${qty}</strong></td>
                <td class="cell-number">${min != null ? min : '—'}</td>
                <td class="cell-number">${max != null ? max : '—'}</td>
                <td class="cell-number">${baseCost > 0 ? baseCost.toFixed(2) + '€' : '—'}</td>
                <td class="cell-number"><strong>${val}€</strong></td>
                <td><span class="badge ${statusCls}">${statusLbl}</span></td>
            </tr>`;
        }).join('');
    },
};
