/**
 * Fichier  : assets/js/pages/analytics.js
 * Version  : 2.6.101
 * Date     : 2026-07-11
 * Description : Pilotage & prévisions — intelligence activée
 * Changelog : v2.6.101 (2026-07-20) — Valorisation par produit dormant et total de section.
 * Changelog : v2.6.70 (2026-07-11) — Formats nombres, dates et devise centralisés via Intl.
 *   - Corrections mapping champs API (daysLeft, risk, dormantDays…)
 *   - Filtrage et colorisation des risques (critique/alerte/attention/ok)
 *   - Affichage consommation journalière + stock projeté
 *   - Dormants : jours inactifs calculés depuis lastMovementAt
 *   - Prévisions : date estimée de rupture + stock projeté à horizon
 *   - Nouveau KPI : nb produits en alerte (attention+alerte) distinct des critiques
 */
(function(){
  const esc = (s) => String(s ?? '')
    .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
    .replace(/\"/g,'&quot;').replace(/'/g,'&#039;');

  const fmtInt   = (n) => Locale.formatInteger(n);
  const fmtDec   = (n,d=1) => Locale.formatDecimal(n, d);
  const fmtMoney = (n) => Locale.formatMoney(n);

  // Couleurs et libellés des niveaux de risque
  const RISK_META = {
    critique:  { color:'var(--red)',    bg:'var(--red-pale)',    label:'Critique',  icon:'🔴' },
    alerte:    { color:'var(--orange)', bg:'var(--orange-pale)', label:'Alerte',    icon:'🟠' },
    attention: { color:'#f59e0b',       bg:'rgba(245,158,11,.1)',label:'Attention', icon:'🟡' },
    ok:        { color:'var(--green)',  bg:'var(--green-pale)',  label:'OK',        icon:'🟢' },
  };

  // Calcule les jours réels inactifs depuis lastMovementAt
  function calcInactiveDays(lastMovementAt) {
    if(!lastMovementAt) return null;
    const ts = Date.parse(lastMovementAt);
    if(isNaN(ts)) return null;
    return Math.floor((Date.now() - ts) / 86400000);
  }

  // Formatte une date estimée de rupture à partir d'un nb de jours
  function fmtRuptureDate(daysLeft) {
    if(daysLeft === null || daysLeft === undefined || !isFinite(daysLeft)) return '—';
    const d = new Date(Date.now() + daysLeft * 86400000);
    return Locale.formatDate(d, {day:'2-digit', month:'short', year:'numeric'});
  }

  const AnalyticsPage = {
    warehouses: [],

    async init(){
      const root = document.getElementById('analyticsRoot');
      if(!root) return;
      root.innerHTML = this.renderSkeleton();
      this.bind();
      await this.refresh();
    },

    bind(){
      document.getElementById('anRefresh')?.addEventListener('click', ()=>this.refresh());
      ['anWh','anWindow','anHorizon'].forEach(id=>{
        document.getElementById(id)?.addEventListener('change', ()=>this.refresh());
      });
    },

    renderSkeleton(){
      return `
        <div class="filters-bar" style="margin-bottom:var(--sp-4)">
          <div class="filters-section">
            <div>
              <label class="lbl">Magasin</label>
              <select id="anWh" class="sel" style="min-width:160px"><option value="">Tous les magasins</option></select>
            </div>
          </div>
          <div class="filters-divider"></div>
          <div class="filters-section">
            <div>
              <label class="lbl">Fenêtre analyse (j)</label>
              <input id="anWindow" class="inp" type="number" value="90" min="7" step="1" style="width:90px" />
            </div>
            <div>
              <label class="lbl">Horizon projection (j)</label>
              <input id="anHorizon" class="inp" type="number" value="90" min="7" step="1" style="width:90px" />
            </div>
          </div>
          <div class="filters-section ml-auto">
            <button class="btn btn-primary" id="anRefresh">Actualiser</button>
          </div>
        </div>

        <div class="report-summary" id="anKpi" style="margin-bottom:var(--sp-4)"></div>

        <div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-bottom:var(--sp-4)">
          <div class="card">
            <div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
              <strong>🔥 Top consommés</strong>
              <span id="anTopPeriod" style="font-size:11px;color:var(--text-muted)"></span>
            </div>
            <div class="table-container">
              <table class="data-table" id="anTop">
                <thead><tr>
                  <th>Produit</th><th>SKU</th>
                  <th style="text-align:right">Conso totale</th>
                  <th style="text-align:right">Moy/jour</th>
                </tr></thead>
                <tbody></tbody>
              </table>
            </div>
          </div>

          <div class="card">
            <div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
              <strong>⚠️ Risques de rupture</strong>
              <span id="anRiskFilter" style="font-size:11px;color:var(--text-muted)"></span>
            </div>
            <div class="table-container">
              <table class="data-table" id="anRisks">
                <thead><tr>
                  <th>Produit</th>
                  <th style="text-align:right">Stock actuel</th>
                  <th style="text-align:right">Jours restants</th>
                  <th style="text-align:right">Date rupture est.</th>
                  <th style="text-align:right">Niveau</th>
                </tr></thead>
                <tbody></tbody>
              </table>
            </div>
          </div>
        </div>

        <div class="card" style="margin-bottom:var(--sp-4)">
          <div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
            <strong>📈 Projections stock à l'horizon</strong>
            <span id="anProjPeriod" style="font-size:11px;color:var(--text-muted)"></span>
          </div>
          <div class="table-container">
            <table class="data-table" id="anProjections">
              <thead><tr>
                <th>Produit</th><th>SKU</th>
                <th style="text-align:right">Stock actuel</th>
                <th style="text-align:right">Conso prévue</th>
                <th style="text-align:right">Stock projeté</th>
                <th style="text-align:right">Seuil sécurité</th>
                <th style="text-align:right">Statut</th>
              </tr></thead>
              <tbody></tbody>
            </table>
          </div>
        </div>

        <div class="card">
          <div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
            <strong>🕓 Produits dormants</strong>
            <span id="anDormantInfo" style="font-size:11px;color:var(--text-muted)"></span>
          </div>
          <div class="table-container">
            <table class="data-table" id="anDormants">
              <thead><tr>
                <th>Produit</th><th>SKU</th>
                <th style="text-align:right">Stock</th>
                <th style="text-align:right">Valorisation</th>
                <th style="text-align:right">Dernier mouvement</th>
                <th style="text-align:right">Jours inactifs</th>
              </tr></thead>
              <tbody></tbody>
            </table>
          </div>
        </div>
      `;
    },

    async refresh(){
      const btn = document.getElementById('anRefresh');
      if(btn){ btn.disabled = true; btn.textContent = '…'; }
      try{
        const warehouseId = document.getElementById('anWh')?.value || '';
        const windowDays  = Number(document.getElementById('anWindow')?.value || 90);
        const horizonDays = Number(document.getElementById('anHorizon')?.value || 90);

        const json = await Api.analytics({ warehouseId: warehouseId||undefined, windowDays, horizonDays, top:20 });
        const payload = json?.data ? json.data : json;

        // Peupler le select magasins (1 seule fois)
        if(this.warehouses.length === 0 && Array.isArray(payload.warehouses)){
          this.warehouses = payload.warehouses;
          const sel = document.getElementById('anWh');
          if(sel){
            sel.innerHTML = '<option value="">Tous les magasins</option>' +
              this.warehouses.map(w=>`<option value="${esc(w.id)}">${esc(w.name)}</option>`).join('');
            if(warehouseId) sel.value = warehouseId;
          }
        }

        this.renderKpi(payload.kpi||{}, payload.ruptureRisks||[]);
        this.renderTop(payload.topConsumed||[], windowDays);
        this.renderRisks(payload.ruptureRisks||[], horizonDays);
        this.renderProjections(payload.ruptureRisks||[], horizonDays);
        this.renderDormants(payload.dormants||[], payload.kpi?.dormantValue);

      }catch(e){
        console.error('[Analytics]', e);
        const t = typeof toast !== 'undefined' ? toast : null;
        if(t) t('Erreur Pilotage : '+(e?.message||e), 'error');
      } finally {
        if(btn){ btn.disabled=false; btn.textContent='Actualiser'; }
      }
    },

    renderKpi(k, risks){
      const el = document.getElementById('anKpi');
      if(!el) return;

      const stockValue = (k.stockValue==null) ? '—' : fmtMoney(k.stockValue);

      // Compter attention+alerte séparément des critiques
      const alertCount = (risks||[]).filter(r=>r.risk==='attention'||r.risk==='alerte').length;

      el.innerHTML = `
        <div class="summary-card">
          <div class="summary-icon">📦</div>
          <div class="summary-data">
            <div class="summary-value">${stockValue}</div>
            <div class="summary-label">Valeur stock</div>
          </div>
        </div>
        <div class="summary-card ${k.criticalCount>0?'summary-card--crit':''}">
          <div class="summary-icon">🔴</div>
          <div class="summary-data">
            <div class="summary-value" style="${k.criticalCount>0?'color:var(--red)':''}">${fmtInt(k.criticalCount??0)}</div>
            <div class="summary-label">Critiques <small style="font-size:10px;color:var(--text-muted)">(≤ 7j)</small></div>
          </div>
        </div>
        <div class="summary-card">
          <div class="summary-icon">🟠</div>
          <div class="summary-data">
            <div class="summary-value" style="${alertCount>0?'color:var(--orange)':''}">${fmtInt(alertCount)}</div>
            <div class="summary-label">En alerte <small style="font-size:10px;color:var(--text-muted)">(≤ 60j)</small></div>
          </div>
        </div>
        <div class="summary-card">
          <div class="summary-icon">🕓</div>
          <div class="summary-data">
            <div class="summary-value">${fmtInt(k.dormantCount??0)}</div>
            <div class="summary-label">Dormants</div>
          </div>
        </div>
      `;
    },

    renderTop(rows, windowDays){
      const tbody = document.querySelector('#anTop tbody');
      const period = document.getElementById('anTopPeriod');
      if(period) period.textContent = `sur ${windowDays} jours`;
      if(!tbody) return;

      if(!rows.length){
        tbody.innerHTML = `<tr><td colspan="4" style="text-align:center;color:var(--text-muted);padding:20px">Aucune sortie enregistrée sur la période</td></tr>`;
        return;
      }
      tbody.innerHTML = rows.slice(0,15).map(r=>{
        const avgDaily = r.windowDays>0 ? (r.consumed/r.windowDays) : 0;
        return `<tr>
          <td>${esc(r.productName)}</td>
          <td style="font-family:var(--font-mono);font-size:11px">${esc(r.sku||'')}</td>
          <td style="text-align:right;font-weight:600">${fmtDec(r.consumed,0)}</td>
          <td style="text-align:right;color:var(--text-muted);font-size:12px">${fmtDec(avgDaily,2)}</td>
        </tr>`;
      }).join('');
    },

    renderRisks(rows, horizonDays){
      const tbody = document.querySelector('#anRisks tbody');
      const info  = document.getElementById('anRiskFilter');
      if(!tbody) return;

      // Filtrer : uniquement les produits avec consommation (avgDaily > 0)
      const active = rows.filter(r=>r.avgDaily > 0);
      const nonOk  = active.filter(r=>r.risk !== 'ok');

      if(info) info.textContent = nonOk.length ? `${nonOk.length} produit(s) à surveiller` : 'Tout est OK';

      if(!active.length){
        tbody.innerHTML = `<tr><td colspan="6" style="text-align:center;color:var(--text-muted);padding:20px">Aucun produit avec consommation sur la période</td></tr>`;
        return;
      }

      // Trier : critiques → alertes → attention → ok
      const order = {critique:0, alerte:1, attention:2, ok:3};
      const sorted = [...active].sort((a,b)=>{
        const da = a.daysLeft??1e9, db = b.daysLeft??1e9;
        return da - db;
      });

      tbody.innerHTML = sorted.slice(0,20).map(r=>{
        const meta  = RISK_META[r.risk] || RISK_META.ok;
        const days  = r.daysLeft===null||r.daysLeft===undefined ? null : Math.round(r.daysLeft);
        const daysStr = days===null ? '∞' : (days<1 ? '<1' : fmtInt(days));
        const ruptureDate = (days!==null && isFinite(days)) ? fmtRuptureDate(days) : '—';
        const badge = `<span style="display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:20px;font-size:11px;font-weight:700;background:${meta.bg};color:${meta.color}">${meta.icon} ${meta.label}</span>`;

        return `<tr>
          <td style="font-weight:${r.risk!=='ok'?'600':'400'}">${esc(r.productName)}</td>
          <td style="text-align:right;font-family:var(--font-mono);font-size:12px">${fmtDec(r.quantity,0)}</td>
          <td style="text-align:right;font-weight:600;color:${meta.color}">${daysStr}</td>
          <td style="text-align:right;font-size:12px;color:var(--text-muted)">${ruptureDate}</td>
          <td style="text-align:right">${badge}</td>
        </tr>`;
      }).join('');
    },

    renderProjections(rows, horizonDays){
      const tbody  = document.querySelector('#anProjections tbody');
      const period = document.getElementById('anProjPeriod');
      if(period) period.textContent = `à ${horizonDays} jours`;
      if(!tbody) return;

      // Uniquement les produits actifs (avgDaily > 0)
      const active = rows.filter(r=>r.avgDaily>0);
      if(!active.length){
        tbody.innerHTML = `<tr><td colspan="7" style="text-align:center;color:var(--text-muted);padding:20px">Aucun produit avec consommation sur la période</td></tr>`;
        return;
      }

      // Trier par stock projeté le plus critique en premier
      const sorted = [...active].sort((a,b)=>(a.projectedQty??0)-(b.projectedQty??0));

      tbody.innerHTML = sorted.slice(0,20).map(r=>{
        const consoProj  = r.avgDaily * horizonDays;
        const projQty    = r.quantity - consoProj;
        const safety     = r.dynamicSafety || 0;
        const meta       = RISK_META[r.risk] || RISK_META.ok;

        // Barre de progression visuelle
        const pct = r.quantity>0 ? Math.max(0,Math.min(100,(projQty/r.quantity)*100)) : 0;
        const barColor = projQty<=0 ? 'var(--red)' : projQty<=safety ? 'var(--orange)' : 'var(--green)';
        const projStr  = projQty<=0
          ? `<span style="color:var(--red);font-weight:700">Rupture</span>`
          : `<span style="color:${barColor};font-weight:600">${fmtDec(projQty,0)}</span>`;

        return `<tr>
          <td>${esc(r.productName)}</td>
          <td style="font-family:var(--font-mono);font-size:11px">${esc(r.sku||'')}</td>
          <td style="text-align:right">${fmtDec(r.quantity,0)}</td>
          <td style="text-align:right;color:var(--text-muted);font-size:12px">−${fmtDec(consoProj,0)}</td>
          <td style="text-align:right">
            ${projStr}
            <div style="margin-top:4px;height:3px;background:var(--border);border-radius:2px;overflow:hidden">
              <div style="height:100%;width:${pct}%;background:${barColor};border-radius:2px;transition:width .3s"></div>
            </div>
          </td>
          <td style="text-align:right;font-size:12px;color:var(--text-muted)">${safety>0?fmtDec(safety,0):'—'}</td>
          <td style="text-align:right"><span style="display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:20px;font-size:11px;font-weight:700;background:${meta.bg};color:${meta.color}">${meta.icon} ${meta.label}</span></td>
        </tr>`;
      }).join('');
    },

    renderDormants(rows, dormantValue){
      const tbody = document.querySelector('#anDormants tbody');
      const info  = document.getElementById('anDormantInfo');
      if(!tbody) return;

      if(info) info.textContent = `${rows.length} produit(s) · Total : ${dormantValue == null ? '—' : fmtMoney(dormantValue)}`;

      if(!rows.length){
        tbody.innerHTML = `<tr><td colspan="6" style="text-align:center;color:var(--text-muted);padding:20px">Aucun produit dormant</td></tr>`;
        return;
      }

      tbody.innerHTML = rows.map(r=>{
        const inactive = calcInactiveDays(r.lastMovementAt);
        const lastDate = r.lastMovementAt
          ? Locale.formatDate(r.lastMovementAt,{day:'2-digit',month:'short',year:'numeric'})
          : '—';
        const inactiveColor = inactive===null ? 'var(--text-muted)' : inactive>365 ? 'var(--red)' : inactive>180 ? 'var(--orange)' : 'var(--text-secondary)';

        return `<tr>
          <td>${esc(r.productName)}</td>
          <td style="font-family:var(--font-mono);font-size:11px">${esc(r.sku||'')}</td>
          <td style="text-align:right">${fmtDec(r.quantity,0)}</td>
          <td style="text-align:right;font-weight:800;color:var(--blue)">${r.valuation==null?'—':fmtMoney(r.valuation)}</td>
          <td style="text-align:right;font-size:12px;color:var(--text-muted)">${lastDate}</td>
          <td style="text-align:right;font-weight:600;color:${inactiveColor}">${inactive===null?'—':fmtInt(inactive)+' j'}</td>
        </tr>`;
      }).join('');
    }
  };

  window.AnalyticsPage = AnalyticsPage;
})();
