// Dashboard — orders KPIs + dual-bar chart + product table with active/inactive filter
(function () {
  const { useState, useRef, useEffect } = React;

  const eur = v => (+(v)||0).toLocaleString('es-ES', { style:'currency', currency:'EUR', minimumFractionDigits:2 });
  const num = v => (+(v)||0).toLocaleString('es-ES');
  const pct = v => `${(+(v)||0).toFixed(1)}%`;
  const dlt = (v, ref) => (ref > 0 && v != null) ? +((v - ref) / ref * 100).toFixed(1) : null;

  // ── Chart helpers ──────────────────────────────────────────────────────────
  const W=900, H=230, PL=70, PR=16, PT=14, PB=44;
  const cw=W-PL-PR, ch=H-PT-PB;

  const MESES = ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic'];
  function fmtDateLabel(dateStr, prevDateStr) {
    if (!dateStr) return null;
    const [y, m, d] = dateStr.split('-');
    const month    = MESES[parseInt(m,10)-1];
    const prevM    = prevDateStr ? prevDateStr.slice(5,7) : null;
    const prevY    = prevDateStr ? prevDateStr.slice(0,4)  : null;
    const showMon  = !prevDateStr || prevM !== m;
    const showYear = !prevDateStr || prevY !== y;
    return { day: d, month: showMon ? month : null, year: showYear ? `'${y.slice(2)}` : null };
  }

  const fmtY = v => {
    if (v === 0) return '0 €';
    if (Math.abs(v) >= 1000) return `${(v/1000).toFixed(1)}k €`;
    return `${Math.round(v)} €`;
  };
  const yp = (v, minV, rng) => PT + ch - ((v - minV) / rng) * ch;

  function BarChart({ data, labelFmt, highlightFn, gradId, hasProfit }) {
    const [tip, setTip] = useState(null);
    const ref = useRef(null);

    if (!data?.length) return null;

    const maxRev    = Math.max(1, ...data.map(d => d.revenue||0));
    const profitVals = hasProfit ? data.map(d => d.profit ?? 0) : [0];
    const maxP = Math.max(0, ...profitVals);
    const minP = Math.min(0, ...profitVals);
    const maxV = Math.max(maxRev, maxP) * 1.15;
    const minV = minP < 0 ? minP * 1.2 : 0;
    const rng  = maxV - minV || 1;
    const zero = yp(0, minV, rng);

    const n     = data.length;
    const slotW = cw / n;
    const bwR   = Math.max(4, Math.floor(slotW * (hasProfit ? 0.42 : 0.65)));
    const bwP   = hasProfit ? Math.max(3, Math.floor(slotW * 0.26)) : 0;
    const gap   = hasProfit ? 2 : 0;
    const totalW = bwR + (hasProfit ? bwP + gap : 0);
    const xSlot  = i => PL + (i + 0.5) * slotW;
    const xRev   = i => xSlot(i) - totalW / 2;
    const xPro   = i => xSlot(i) - totalW / 2 + bwR + gap;

    const ticks = 4;
    const gridLines = Array.from({length: ticks+1}, (_, i) => {
      const v  = minV + rng * (i / ticks);
      const yy = yp(v, minV, rng);
      return React.createElement('g', {key:i},
        React.createElement('line', {x1:PL, x2:W-PR, y1:yy, y2:yy, stroke:'#f0f2f6', strokeWidth:1}),
        React.createElement('text', {
          x:PL-6, y:yy+4, textAnchor:'end', fontSize:10,
          fill:'#b0b8c8', fontFamily:'Inter,sans-serif',
        }, fmtY(v))
      );
    });

    const zeroLine = minV < 0 ? React.createElement('line', {
      key:'z', x1:PL, x2:W-PR, y1:zero, y2:zero,
      stroke:'#94a3b8', strokeWidth:1, strokeDasharray:'3,2',
    }) : null;

    return React.createElement('div', {className:'chart-wrap', style:{position:'relative'}},
      tip && React.createElement('div', {className:'chart-tooltip', style:{left:tip.x+'px', top:tip.y+'px', minWidth:230}},
        // ── Header ──────────────────────────────────────────
        React.createElement('div', {className:'ct-header'},
          React.createElement('span', {className:'ct-time'}, tip.label),
          tip.orders > 0 && React.createElement('span', {className:'ct-badge'},
            `${tip.orders} pedido${tip.orders!==1?'s':''}`
          )
        ),
        // ── Financial breakdown ──────────────────────────────
        React.createElement('div', {className:'ct-section'},
          React.createElement('div', {className:'ct-krow'},
            React.createElement('span', {className:'ct-klabel'}, 'Ingresos'),
            React.createElement('span', {className:'ct-kval'}, eur(tip.revenue))
          ),
          tip.totalFees != null && tip.totalFees > 0 && React.createElement('div', {className:'ct-krow'},
            React.createElement('span', {className:'ct-klabel'}, 'Tarifas'),
            React.createElement('span', {className:'ct-kval red'}, `\u2212${eur(tip.totalFees)}`)
          ),
          tip.profit != null && React.createElement('div', {className:'ct-krow ct-profit'},
            React.createElement('span', {className:'ct-klabel'}, 'G. Neta'),
            React.createElement('span', {className:`ct-kval ${tip.profit>=0?'green':'red'}`},
              eur(tip.profit),
              tip.revenue > 0 && React.createElement('span', {className:'ct-pct'},
                ` ${((tip.profit/tip.revenue)*100).toFixed(0)}%`
              )
            )
          )
        ),
        // ── Order list ───────────────────────────────────────
        tip.ordersList?.length > 0 && React.createElement('div', {className:'ct-section ct-orders'},
          tip.ordersList.map(o => {
            const isPend = o.status==='Pending'||o.status==='PendingAvailability';
            const isShip = o.status==='Shipped';
            const sc = isPend ? '#f59e0b' : isShip ? '#22c55e' : '#3b82f6';
            const sl = isPend ? 'Pend.' : (o.status==='Unshipped'||o.status==='PartiallyShipped') ? 'Prep.' : isShip ? 'Env.' : o.status;
            const sid = o.order_id.slice(0,3) + '-\u2026' + o.order_id.slice(-7);
            return React.createElement('div', {key:o.order_id, className:'ct-order-row'},
              React.createElement('span', {style:{display:'flex',alignItems:'center',gap:5,minWidth:0}},
                React.createElement('span', {style:{width:6,height:6,borderRadius:'50%',background:sc,flexShrink:0,display:'inline-block'}}),
                React.createElement('span', {className:'ct-oid'}, sid)
              ),
              React.createElement('span', {style:{display:'flex',alignItems:'center',gap:6,flexShrink:0}},
                React.createElement('span', {className:'ct-kval'}, eur(o.revenue)),
                React.createElement('span', {style:{fontSize:10,color:sc}}, sl)
              )
            );
          })
        )
      ),
      React.createElement('svg', {
        ref, viewBox:`0 0 ${W} ${H}`,
        style:{width:'100%', height:'auto', display:'block'},
        onMouseLeave: () => setTip(null),
      },
        React.createElement('defs', null,
          React.createElement('linearGradient', {id:gradId, x1:'0', y1:'0', x2:'0', y2:'1'},
            React.createElement('stop', {offset:'0%',   stopColor:'#3b82f6', stopOpacity:'0.9'}),
            React.createElement('stop', {offset:'100%', stopColor:'#60a5fa', stopOpacity:'0.55'})
          ),
          React.createElement('linearGradient', {id:gradId+'p', x1:'0', y1:'0', x2:'0', y2:'1'},
            React.createElement('stop', {offset:'0%',   stopColor:'#22c55e', stopOpacity:'0.9'}),
            React.createElement('stop', {offset:'100%', stopColor:'#4ade80', stopOpacity:'0.55'})
          )
        ),
        gridLines,
        zeroLine,
        data.map((d, i) => {
          const rev   = d.revenue || 0;
          const pro   = hasProfit ? (d.profit ?? null) : null;
          const isHi  = highlightFn ? highlightFn(d, i) : false;
          const showL = n <= 24 || i % Math.max(1, Math.ceil(n/10)) === 0;

          // Multi-line date label (day / month name / year)
          const dateLabel = d.date ? fmtDateLabel(d.date, data[i-1]?.date) : null;
          const simpleLabel = labelFmt ? labelFmt(d, i) : null;

          const revH = Math.max(2, Math.abs(zero - yp(rev, minV, rng)));
          const revY = yp(rev, minV, rng);

          let proEl = null;
          if (pro !== null) {
            const proH = Math.max(2, Math.abs(zero - yp(pro, minV, rng)));
            const proY = pro >= 0 ? yp(pro, minV, rng) : zero;
            proEl = React.createElement('rect', {
              key:'p', x:xPro(i), y:proY, width:bwP, height:proH, rx:2,
              fill: pro >= 0 ? `url(#${gradId}p)` : '#ef4444',
              opacity: 0.9,
            });
          }

          const tipLabel = dateLabel
            ? `${dateLabel.day} ${dateLabel.month||MESES[parseInt(d.date.slice(5,7),10)-1]} ${d.date.slice(0,4)}`
            : simpleLabel || '';

          return React.createElement('g', {
            key: i,
            style:{cursor:'default'},
            onMouseEnter: () => {
              const rc = ref.current?.getBoundingClientRect();
              if (!rc) return;
              const tipX = xSlot(i) / W * rc.width;
              const ordersList = d.ordersList || [];
              const tipW = ordersList.length ? 240 : 200;
              setTip({
                x: Math.min(Math.max(0, tipX - tipW/2), rc.width - tipW - 4),
                y: Math.max(4, revY / H * rc.height - 80),
                label: tipLabel, revenue: rev, profit: pro,
                totalFees: d.totalFees ?? null,
                orders: d.orders||0, ordersList,
              });
            },
          },
            React.createElement('rect', {
              x:xRev(i), y:revY, width:bwR, height:revH, rx:3,
              fill: isHi ? '#1d4ed8' : (rev>0 ? `url(#${gradId})` : '#f1f5f9'),
            }),
            proEl,
            showL && dateLabel && React.createElement('g', {key:'lbl'},
              // day number
              React.createElement('text', {
                x:xSlot(i), y:H-30, textAnchor:'middle', fontSize:10,
                fill: isHi?'#3b82f6':'#94a3b8',
                fontFamily:'Inter,sans-serif', fontWeight: isHi?700:500,
              }, dateLabel.day),
              // month name — always show at transitions, else show faint
              React.createElement('text', {
                x:xSlot(i), y:H-18, textAnchor:'middle', fontSize:9,
                fill: dateLabel.month ? (isHi?'#3b82f6':'#64748b') : '#cbd5e1',
                fontFamily:'Inter,sans-serif', fontWeight: dateLabel.month?600:400,
              }, dateLabel.month || MESES[parseInt(d.date.slice(5,7),10)-1]),
              // year — only when it changes
              dateLabel.year && React.createElement('text', {
                x:xSlot(i), y:H-6, textAnchor:'middle', fontSize:8,
                fill:'#94a3b8', fontFamily:'Inter,sans-serif',
              }, dateLabel.year)
            ),
            showL && !dateLabel && simpleLabel && React.createElement('text', {
              x:xSlot(i), y:H-4, textAnchor:'middle', fontSize:9,
              fill: isHi?'#3b82f6':'#b0b8c8',
              fontFamily:'Inter,sans-serif', fontWeight: isHi?700:400,
            }, simpleLabel)
          );
        })
      )
    );
  }

  // ── Smart chart ───────────────────────────────────────────────────────────
  function SalesChart({ preset, range, dailyData }) {
    const [hourly,      setHourly]      = useState(null);
    const [ordersByDay, setOrdersByDay] = useState({});
    const [loading,     setLoading]     = useState(false);

    const isSingle  = preset === 'today' || preset === 'yesterday';
    const chartDate = preset === 'today'
      ? new Date().toLocaleDateString('sv')
      : range?.from;

    // Hourly mode: buckets + per-order list for that single day
    useEffect(() => {
      if (!isSingle) { setHourly(null); return; }
      setLoading(true);
      Promise.all([
        API.ordersHourly(chartDate),
        API.ordersList({ date: chartDate }).catch(() => ({ data: [] })),
      ]).then(([h, ol]) => {
          const byHour = {};
          for (const o of (ol.data || [])) {
            if (!byHour[o.hour]) byHour[o.hour] = [];
            byHour[o.hour].push(o);
          }
          setHourly((h.data || []).map(b => ({ ...b, ordersList: byHour[b.hour] || [] })));
        })
        .catch(() => setHourly([]))
        .finally(() => setLoading(false));
    }, [isSingle, chartDate]);

    // Daily mode: per-order list for the full range, grouped by day
    useEffect(() => {
      if (isSingle || !range?.from) { setOrdersByDay({}); return; }
      API.ordersList({ dateFrom: range.from, dateTo: range.to }).catch(() => ({ data: [] }))
        .then(ol => {
          const map = {};
          for (const o of (ol.data || [])) {
            if (!map[o.day]) map[o.day] = [];
            map[o.day].push(o);
          }
          setOrdersByDay(map);
        });
    }, [isSingle, range?.from, range?.to]);

    if (loading) return React.createElement('div', {className:'chart-empty-note'}, 'Cargando...');

    if (isSingle) {
      const hasData = hourly?.some(h => h.revenue > 0);
      const curHour = preset === 'today' ? new Date().getHours() : -1;
      return React.createElement('div', null,
        !hasData && React.createElement('div', {className:'chart-no-data-note'},
          'Sin pedidos para este día todavía'
        ),
        hourly && React.createElement(BarChart, {
          data: hourly,
          gradId: 'hg1',
          hasProfit: false,
          labelFmt: (d, i) => i % 3 === 0 ? `${String(d.hour).padStart(2,'0')}h` : '',
          highlightFn: d => d.hour === curHour,
        })
      );
    }

    if (!dailyData?.length) return React.createElement('div', {className:'chart-empty-note'},
      'Sin datos — sincroniza para ver la evolución de ventas'
    );

    const todayStr  = new Date().toLocaleDateString('sv');
    const hasProfit = dailyData.some(d => d.profit !== null && d.profit !== undefined);
    const dailyWithOrders = dailyData.map(d => ({ ...d, ordersList: ordersByDay[d.date] || [] }));
    return React.createElement(BarChart, {
      data: dailyWithOrders,
      gradId: 'dg1',
      hasProfit,
      labelFmt: d => d.date?.slice(5),
      highlightFn: d => d.date === todayStr,
    });
  }

  // ── KPI card ──────────────────────────────────────────────────────────────
  function KPI({ label, value, sub, sub2, delta, color, subColor }) {
    const up   = delta > 0;
    const show = delta != null && !isNaN(delta);
    return React.createElement('div', {className:'kpi-card'},
      React.createElement('div', {className:'kpi-label'}, label),
      React.createElement('div', {className:'kpi-value', style:{color: color||'var(--txt-1)'}}, value),
      sub && React.createElement('div', {className:'kpi-sub2', style:{color: subColor||'var(--txt-2)'}}, sub),
      React.createElement('div', {className:'kpi-sub'},
        sub2 && React.createElement('span', {className:'kpi-sub-txt'}, sub2),
        show && React.createElement('span', {className:`delta ${up?'up':'down'}`},
          `${up?'+':''}${delta}%`
        )
      )
    );
  }

  // ── Product table ─────────────────────────────────────────────────────────
  function ProductTable({ rows }) {
    const [filter, setFilter] = useState('active');

    if (!rows?.length) return React.createElement('div', {
      className:'card', style:{padding:'24px', textAlign:'center', color:'var(--txt-4)'}
    }, 'Sin datos de productos — sincroniza primero');

    const active   = rows.filter(r => (r.fulfillable_qty||0) > 0);
    const inactive = rows.filter(r => (r.fulfillable_qty||0) === 0);
    const shown    = filter === 'active' ? active : filter === 'inactive' ? inactive : rows;

    const filters = [
      { id:'all',      label:`Todos (${rows.length})` },
      { id:'active',   label:`Activos (${active.length})` },
      { id:'inactive', label:`Inactivos (${inactive.length})` },
    ];

    return React.createElement('div', {className:'card', style:{padding:'20px 24px'}},
      React.createElement('div', {className:'card-header', style:{marginBottom:16}},
        React.createElement('span', {className:'card-title'}, 'Rendimiento por producto'),
        React.createElement('div', {className:'radio-filter'},
          filters.map(f =>
            React.createElement('button', {
              key: f.id,
              className: `radio-btn${filter === f.id ? ' active' : ''}`,
              onClick: () => setFilter(f.id),
            }, f.label)
          )
        )
      ),
      React.createElement('div', {style:{overflowX:'auto'}},
        React.createElement('table', {className:'data-table sb-table'},
          React.createElement('thead', null,
            React.createElement('tr', null,
              ['Producto','Uds.','Reembolsos','Ventas','Tarifas','COGS','G. Bruta','G. Neta','Margen','ROI','Stock FBA'].map(h =>
                React.createElement('th', {key:h, className: h!=='Producto'?'r':''}, h)
              )
            )
          ),
          React.createElement('tbody', null,
            shown.map(r => {
              const gBruta  = (r.revenue||0) - (r.totalFees||0) - (r.refundAmount||0);
              const roi     = (r.cogs||0)>0 ? (r.profit||0)/r.cogs*100 : null;
              const mg      = r.margin ?? ((r.revenue||0)>0 ? (r.profit||0)/r.revenue*100 : 0);
              const mgClass = mg>=20?'green': mg>=10?'amber':'red';
              const ss      = r.stockStatus||'ok';

              return React.createElement('tr', {key:r.asin},
                React.createElement('td', {style:{minWidth:200}},
                  React.createElement('div', {className:'flex items-center gap-2'},
                    r.image_url && React.createElement('img', {
                      src:r.image_url,
                      style:{width:38,height:38,borderRadius:6,objectFit:'contain',border:'1px solid var(--border)',flexShrink:0}
                    }),
                    React.createElement('div', {style:{minWidth:0}},
                      React.createElement('div', {className:'fw-7', style:{fontSize:12,lineHeight:1.3}},
                        (r.name||r.asin).length>48 ? (r.name||r.asin).slice(0,48)+'…' : (r.name||r.asin)
                      ),
                      React.createElement('div', {style:{fontSize:10,color:'var(--txt-4)',marginTop:1}},
                        r.asin + (r.sku?` · ${r.sku}`:'')
                      ),
                      (r.pvp_listing||r.unitCogs) && React.createElement('div', {style:{fontSize:10,color:'var(--txt-3)',marginTop:1}},
                        [r.pvp_listing&&`PVP ${eur(r.pvp_listing)}`, r.unitCogs&&`COGS ${eur(r.unitCogs)}`].filter(Boolean).join(' · ')
                      )
                    )
                  )
                ),
                React.createElement('td', {className:'r fw-7'}, num(r.units||0)),
                React.createElement('td', {className:'r', style:{color:(r.refundAmount||0)>0?'var(--red)':'var(--txt-3)'}},
                  (r.refundAmount||0)>0 ? eur(r.refundAmount) : '—'
                ),
                React.createElement('td', {className:'r fw-7'}, eur(r.revenue||0)),
                React.createElement('td', {className:'r txt-red'}, eur(r.totalFees||0)),
                React.createElement('td', {className:'r txt-purple'}, (r.cogs||0)>0?eur(r.cogs):'—'),
                React.createElement('td', {className:'r fw-7', style:{color:gBruta>=0?'var(--green)':'var(--red)'}}, eur(gBruta)),
                React.createElement('td', {className:'r fw-7', style:{color:(r.profit||0)>=0?'var(--green)':'var(--red)'}}, eur(r.profit||0)),
                React.createElement('td', {className:'r'},
                  React.createElement('span', {className:`margin-pill ${mgClass}`}, pct(mg))
                ),
                React.createElement('td', {className:'r', style:{color:roi==null?'var(--txt-4)':roi>=50?'var(--green)':roi>=20?'var(--amber)':'var(--red)'}},
                  roi!=null?pct(roi):'—'
                ),
                React.createElement('td', {className:'r'},
                  React.createElement('span', {
                    className:`stock-badge ${ss}`,
                    title: r.daysLeft!=null?`~${r.daysLeft} días`:'',
                  },
                    num(r.fulfillable_qty||0),
                    r.daysLeft!=null && React.createElement('span', {style:{opacity:.65,marginLeft:3,fontSize:10}}, `·${r.daysLeft}d`)
                  )
                )
              );
            })
          )
        )
      )
    );
  }

  // ── Main ──────────────────────────────────────────────────────────────────
  function DashboardView({ apiData, apiLoading, preset, range }) {
    if (!apiData && apiLoading) return React.createElement('div', {className:'empty-state'},
      React.createElement('span', {className:'txt-4'}, 'Cargando...')
    );

    const cur    = apiData?.ordersKpis?.current   || {};
    const prev   = apiData?.ordersKpis?.previous  || {};
    const fin    = apiData?.salesKpis?.current    || {};
    const finP   = apiData?.salesKpis?.previous   || {};
    const daily  = apiData?.dailyData  || [];
    const rows   = apiData?.products   || [];
    const hasFin = !!(apiData?.salesKpis && !apiData.salesKpis?.error);

    const gastos  = (fin.totalFees||0) + (fin.cogs||0) + (fin.refundAmount||0);
    const gastosP = (finP.totalFees||0) + (finP.cogs||0) + (finP.refundAmount||0);
    const margin  = hasFin && (fin.revenue||0) > 0
      ? `${((fin.profit||0) / fin.revenue * 100).toFixed(1)}%`
      : null;

    // For today/yesterday with no financial data: estimate from 30d rates
    // Use salesKpis from App (which loads 30d by default) as rate base — passed as salesKpis30d
    const isShortPreset = preset === 'today' || preset === 'yesterday';
    const rev30  = apiData?.salesKpis30d?.current?.revenue  || 0;
    const estFeeRate  = rev30 > 0 ? (apiData?.salesKpis30d?.current?.totalFees||0) / rev30 : 0.3;
    const estCogsRate = rev30 > 0 ? (apiData?.salesKpis30d?.current?.cogs||0)      / rev30 : 0;
    const todayRev    = cur.revenue || 0;
    const estimated   = isShortPreset && !hasFin && todayRev > 0;
    const estFees     = estimated ? todayRev * estFeeRate  : null;
    const estCogs     = estimated ? todayRev * estCogsRate : null;
    const estProfit   = estimated ? todayRev - (estFees||0) - (estCogs||0) : null;
    const estMargin   = estimated && todayRev > 0 ? `${((estProfit||0)/todayRev*100).toFixed(1)}%` : null;

    const hasProfit = daily.some(d => d.profit !== null && d.profit !== undefined);
    const chartLegend = !preset?.startsWith('today') && !preset?.startsWith('yesterday') && hasProfit;

    return React.createElement('div', {className:'view-pad'},

      // ── KPIs ──
      React.createElement('div', {className:'kpi-grid'},
        React.createElement(KPI, {
          label: 'Pedidos',
          value: eur(cur.revenue||0),
          sub:   `${num(cur.total_orders||0)} pedidos`,
          sub2:  `ant. ${eur(prev.revenue||0)} · ${num(prev.total_orders||0)} ped.`,
          delta: dlt(cur.revenue, prev.revenue),
        }),
        React.createElement(KPI, {
          label:    estimated ? 'Gastos ~estimados' : 'Gastos totales',
          value:    hasFin ? eur(gastos) : (estimated ? `~${eur(estFees + estCogs)}` : '—'),
          sub:      hasFin
            ? `Tarifas ${eur(fin.totalFees||0)} · COGS ${eur(fin.cogs||0)}`
            : (estimated
              ? `~Tarifas ${eur(estFees)} · ~COGS ${eur(estCogs)}`
              : 'Datos disponibles mañana'),
          sub2:     hasFin && gastosP > 0 ? `ant. ${eur(gastosP)}` : null,
          color:    (hasFin || estimated) ? 'var(--red)' : 'var(--txt-3)',
          subColor: 'var(--txt-3)',
          delta:    hasFin ? dlt(gastos, gastosP) : null,
        }),
        React.createElement(KPI, {
          label:    estimated ? 'G. Neta ~estimada' : 'G. Neta',
          value:    hasFin ? eur(fin.profit||0) : (estimated ? `~${eur(estProfit)}` : '—'),
          sub:      hasFin && margin
            ? `Margen ${margin}`
            : (estimated ? `~Margen ${estMargin}` : 'Datos disponibles mañana'),
          sub2:     hasFin && finP.profit ? `ant. ${eur(finP.profit||0)}` : null,
          color:    hasFin
            ? ((fin.profit||0) >= 0 ? 'var(--green)' : 'var(--red)')
            : (estimated ? ((estProfit||0) >= 0 ? 'var(--green)' : 'var(--red)') : 'var(--txt-3)'),
          subColor: 'var(--txt-3)',
          delta:    hasFin ? dlt(fin.profit, finP.profit) : null,
        }),
        React.createElement(KPI, {
          label: 'Pendientes',
          value: num(cur.pending||0),
          sub:   'en proceso',
          color: (cur.pending||0)>0 ? 'var(--amber)' : 'var(--txt-3)',
        })
      ),

      // ── Chart ──
      React.createElement('div', {className:'chart-card'},
        React.createElement('div', {className:'card-header'},
          React.createElement('div', {style:{display:'flex', alignItems:'center', gap:12}},
            React.createElement('span', {className:'card-title'}, 'Evolución de ventas'),
            React.createElement('span', {className:'card-sub'},
              preset==='today'     ? 'Hoy · por hora'
              : preset==='yesterday' ? 'Ayer · por hora'
              : `${range?.from||''} → ${range?.to||''}`
            )
          ),
          chartLegend && React.createElement('div', {style:{display:'flex', gap:14, alignItems:'center'}},
            React.createElement('span', {style:{display:'flex', alignItems:'center', gap:5, fontSize:11, color:'var(--txt-4)'}},
              React.createElement('span', {style:{width:10, height:10, borderRadius:2, background:'#3b82f6', display:'inline-block', flexShrink:0}}),
              'Ventas'
            ),
            React.createElement('span', {style:{display:'flex', alignItems:'center', gap:5, fontSize:11, color:'var(--txt-4)'}},
              React.createElement('span', {style:{
                width:10, height:10, borderRadius:2, display:'inline-block', flexShrink:0,
                background:'linear-gradient(to right, #22c55e 50%, #ef4444 50%)',
              }}),
              'G. Neta'
            )
          )
        ),
        React.createElement(SalesChart, {preset, range, dailyData: daily})
      ),

      // ── Product table ──
      React.createElement(ProductTable, {rows})
    );
  }

  window.DashboardView = DashboardView;
})();
