// js/lib/produtos/calcs.js
// [Wave 7 KIMI 2026-05-17] Extraído de Produtos.jsx L537-552 (isLossSelling + stockBadge).
// [Wave 25-alt v224.6 NUCLEAR 2026-05-23] EXPANSION +5 factories:
//   filterProductsWithLoss, computeCustoPreview, makeSortComparator, filterByStatus, extractBrand
//
// Deps runtime globals (window): isLowStock (declarado index.html L717).
// Validação RUNTIME (padrão Wave 6 v223.2).
(function() {
  'use strict';

  // regra_validacao_helpers_runtime_quando_ordem_scripts_uncertain — RUNTIME 1x
  let _validated = false;
  function _validateHelpers() {
    if (_validated) return;
    _validated = true;
    const _missing = [];
    if (typeof isLowStock === 'undefined') _missing.push('isLowStock');
    if (_missing.length > 0) {
      const _msg = `[lib/produtos/calcs] runtime helpers faltando: ${_missing.join(', ')}`;
      console.error(_msg);
      window.Sentry?.captureMessage?.(_msg, 'error');
    }
  }

  // [Onda L Fase 1 — 20260507] Detecta produto vendendo com prejuízo (sale_price <= avg_cost)
  function isLossSelling(p){
    _validateHelpers();
    const cost = Number(p.avgCost||p.avg_cost||0);
    const price = Number(p.salePrice||p.sale_price||0);
    return cost > 0 && price > 0 && price <= cost;
  }

  // Badge JSX — retorna <span> baseado em stock + isLowStock helper
  function stockBadge(p, sales){
    _validateHelpers();
    if(p.stock<=0)return<span className="badge badge-red">Zerado</span>;
    if(p.stock<=(p.estoqueMin||20))return<span className="badge badge-red" style={{background:'#3a1800',color:'#EA580C'}}>Acabando</span>;
    if(isLowStock(p,sales))return<span className="badge badge-yellow">Baixo</span>;
    return<span className="badge badge-green">OK</span>;
  }

  // ═══ FACTORIES NOVAS Wave 25-alt v224.6 ═══

  // extractBrand helper (fallback se já não existe global)
  function extractBrand(productName){
    if(!productName) return '';
    const first = String(productName).trim().split(/\s+/)[0];
    return first || '';
  }

  // Filter products with loss (cost >= salePrice · active != false · !deletedAt)
  function filterProductsWithLoss(products){
    return (products||[]).filter(function(p){
      if(p.active === false || p.deletedAt) return false;
      return isLossSelling(p);
    });
  }

  // Custo médio preview (entrada novo lote)
  function computeCustoPreview(form){
    const newQty = Number(form.newQty||0);
    const newCost = Number(form.newCost||0);
    const oldStock = Number(form.stock||0);
    const oldCost = Number(form.avgCost||0);
    if(newQty <= 0 || newCost <= 0) return null;
    const newStock = oldStock + newQty;
    const newAvg = oldStock === 0 ? newCost : Math.round(((oldStock * oldCost + newQty * newCost) / newStock) * 100) / 100;
    return {
      old: oldCost,
      newAvg: newAvg,
      diferenca: newAvg - oldCost,
      newStock: newStock
    };
  }

  // Sort comparator factory (column + direction · matches inline L216-226 LITERAL)
  function makeSortComparator(col, dir, suppliers){
    return function(a, b){
      function statusRank(p){
        const min = p.estoqueMin||20;
        if(p.stock<=0) return 0;
        if(p.stock<=min) return 1;
        return 2;
      }
      let va, vb;
      if(col === 'brand'){ va = (a.brand||''); vb = (b.brand||''); }
      else if(col === 'name'){ va = (a.name||''); vb = (b.name||''); }
      else if(col === 'stock'){ va = a.stock||0; vb = b.stock||0; }
      else if(col === 'salePrice'){ va = a.salePrice||0; vb = b.salePrice||0; }
      else if(col === 'avgCost'){ va = a.avgCost||0; vb = b.avgCost||0; }
      else if(col === 'status'){ va = statusRank(a); vb = statusRank(b); }
      else { va = a[col]||0; vb = b[col]||0; }
      const sign = dir === 'asc' ? 1 : -1;
      if(typeof va === 'string') return va.localeCompare(vb) * sign;
      return (va - vb) * sign;
    };
  }

  // Filter by status (factory pra futuro · main file mantém inline por enquanto)
  function filterByStatus(products, filterStatus){
    if(!filterStatus) return products;
    return (products||[]).filter(function(p){
      const stock = Number(p.stock||0);
      const minStock = Number(p.estoqueMin||20);
      if(filterStatus === 'ok') return stock > minStock;
      if(filterStatus === 'acabando') return stock > 0 && stock <= minStock;
      if(filterStatus === 'zerado') return stock <= 0;
      if(filterStatus === 'prejuizo') return isLossSelling(p);
      if(filterStatus === 'sem_fornecedor') return !p.supplierId;
      if(filterStatus === 'sem_categoria') return !p.categoria;
      if(filterStatus === 'sem_volume') return !p.volume;
      if(filterStatus === 'sem_genero') return !p.genero;
      if(filterStatus === 'sem_ncm') return !p.ncm;
      if(filterStatus === 'sem_ean') return !p.ean;
      if(filterStatus === 'custo_zero') return Number(p.avgCost||0) <= 0;
      return true;
    });
  }

  window.ZNX = window.ZNX || {};
  window.ZNX.produtos = window.ZNX.produtos || {};
  window.ZNX.produtos.calcs = {
    isLossSelling: isLossSelling,
    stockBadge: stockBadge,
    extractBrand: extractBrand,
    filterProductsWithLoss: filterProductsWithLoss,
    computeCustoPreview: computeCustoPreview,
    makeSortComparator: makeSortComparator,
    filterByStatus: filterByStatus
  };
  window.ZNX_produtos_calcs_v224_6_wave25alt = true;
})();
