// Módulo — Planogramas
// Generador 3D de planogramas optimizados + Análisis de lineal por imagen

const CAMPAIGNS = ["Perfect Finish", "Sintex MS-35", "Orbafoam PRO 65"];

const shelfPriority = (n) => {
  const mid = Math.floor(n * 0.45);
  return Array.from({ length: n }, (_, i) => i).sort((a, b) => Math.abs(a - mid) - Math.abs(b - mid));
};

function generatePlanogram(clientName, expositor) {
  const D = window.APP_DATA;
  const prods = D.products.filter(p => p.status !== "out");
  const clientData = D.clients.find(c => c.name === clientName);
  const scored = prods.map(p => {
    const isTop = clientData?.topProducts?.includes(p.name) ? 2.5 : 1;
    const camp = CAMPAIGNS.includes(p.name) ? 1.8 : 1;
    const stock = p.status === "ok" ? 1 : 0.5;
    return { ...p, score: isTop * camp * stock * (p.price || 1) };
  }).sort((a, b) => b.score - a.score);
  const priority = shelfPriority(expositor.shelves);
  const slots = [];
  let pi = 0;
  for (const shelf of priority) {
    for (let col = 0; col < expositor.cols; col++) {
      const prod = scored[pi % scored.length];
      slots.push({ shelf, col, product: prod, facings: pi < 5 ? 2 : 1, score: prod.score });
      pi++;
    }
  }
  return slots;
}

// ──────────────────────── SVG 3D Planogram
function Planogram3D({ expositor, placement }) {
  const colors = window.APP_DATA.familyColors;
  const SW = 580, SH = 400;

  const FRONT_W = Math.min(320, Math.max(220, expositor.cols * 58));
  const SHELF_H = Math.max(40, Math.min(62, 260 / expositor.shelves));
  const COL_W = FRONT_W / expositor.cols;
  const BASE_H = 18;
  const TOP_RAIL = 12;
  const FRONT_H = expositor.shelves * SHELF_H + BASE_H + TOP_RAIL;
  const DEPTH = 60, DX = DEPTH * 0.48, DY = DEPTH * 0.27;

  const OX = (SW - FRONT_W - DX) / 2;
  const OY = SH - 28;

  const P = (x, y, d = 0) => [OX + x + (d / DEPTH) * DX, OY - y - (d / DEPTH) * DY];
  const pts = (pairs) => pairs.map(([x, y]) => `${x.toFixed(1)},${y.toFixed(1)}`).join(' ');

  const FC = {
    back: '#0c1a33', side: '#14243f', top: '#1a3060',
    shelfSurf: '#c0d3ea', shelfEdge: '#3e618f', base: '#091526',
  };

  const elems = [];
  let k = 0;
  const K = () => ++k;

  // Back panel
  elems.push(<polygon key={K()} points={pts([P(0, 0, DEPTH), P(FRONT_W, 0, DEPTH), P(FRONT_W, FRONT_H, DEPTH), P(0, FRONT_H, DEPTH)])} fill={FC.back} />);
  // Left side
  elems.push(<polygon key={K()} points={pts([P(0,0), P(0,0,DEPTH), P(0,FRONT_H,DEPTH), P(0,FRONT_H)])} fill={FC.side} />);
  // Right side
  elems.push(<polygon key={K()} points={pts([P(FRONT_W,0,DEPTH), P(FRONT_W,0), P(FRONT_W,FRONT_H), P(FRONT_W,FRONT_H,DEPTH)])} fill={FC.side} />);
  // Top rail
  elems.push(<polygon key={K()} points={pts([P(0,FRONT_H), P(FRONT_W,FRONT_H), P(FRONT_W,FRONT_H,DEPTH), P(0,FRONT_H,DEPTH)])} fill={FC.top} />);
  // Base
  elems.push(<polygon key={K()} points={pts([P(0,0), P(FRONT_W,0), P(FRONT_W,BASE_H), P(0,BASE_H)])} fill={FC.base} />);

  // Shelves
  const SHELF_T = 6;
  for (let s = 0; s <= expositor.shelves; s++) {
    const y = BASE_H + s * SHELF_H;
    if (s < expositor.shelves) {
      elems.push(<polygon key={K()} points={pts([P(0,y+SHELF_T), P(FRONT_W,y+SHELF_T), P(FRONT_W,y+SHELF_T,DEPTH), P(0,y+SHELF_T,DEPTH)])} fill={FC.shelfSurf} />);
    }
    elems.push(<polygon key={K()} points={pts([P(0,y), P(FRONT_W,y), P(FRONT_W,y+SHELF_T), P(0,y+SHELF_T)])} fill={FC.shelfEdge} />);
    // Col dividers
    for (let c = 1; c < expositor.cols; c++) {
      const cx = c * COL_W;
      elems.push(<line key={K()} x1={P(cx,y)[0].toFixed(1)} y1={P(cx,y)[1].toFixed(1)} x2={P(cx,y+SHELF_T)[0].toFixed(1)} y2={P(cx,y+SHELF_T)[1].toFixed(1)} stroke="rgba(0,0,0,0.25)" strokeWidth="0.7"/>);
    }
  }

  // Products
  const PROD_PAD = 3, PROD_TOP = 7;
  const PROD_H = SHELF_H - SHELF_T - 4;

  for (const slot of placement) {
    const sfb = expositor.shelves - 1 - slot.shelf;
    const bY = BASE_H + sfb * SHELF_H + SHELF_T + 2;
    const bX = slot.col * COL_W + PROD_PAD;
    const pW = COL_W - PROD_PAD * 2;
    const fc = colors[slot.product.family] || { fill: '#64748b', light: '#cbd5e1' };
    const isCamp = CAMPAIGNS.includes(slot.product.name);

    const bl = P(bX, bY), br = P(bX+pW, bY), tr = P(bX+pW, bY+PROD_H), tl = P(bX, bY+PROD_H);
    elems.push(<polygon key={K()} points={pts([bl,br,tr,tl])} fill={fc.fill} />);
    elems.push(<polygon key={K()} points={pts([tl,tr,P(bX+pW,bY+PROD_H,PROD_TOP),P(bX,bY+PROD_H,PROD_TOP)])} fill={fc.light} opacity="0.88" />);
    elems.push(<polygon key={K()} points={pts([bl,br,tr,tl])} fill="none" stroke="rgba(255,255,255,0.18)" strokeWidth="0.6"/>);

    const lx = ((bl[0]+br[0])/2).toFixed(1);
    const ly = ((bl[1]+tl[1])/2 + 3).toFixed(1);
    const short = slot.product.name.length > 9 ? slot.product.name.slice(0, 8) + '.' : slot.product.name;
    const fs = COL_W < 52 ? 6 : COL_W < 68 ? 7 : 8.5;
    elems.push(<text key={K()} x={lx} y={ly} textAnchor="middle" fill="white" fontSize={fs} fontWeight="700" fontFamily="Inter,sans-serif">{short}</text>);

    if (isCamp) {
      const sx = tr[0] - 5, sy = tr[1] + 5;
      elems.push(<circle key={K()} cx={sx.toFixed(1)} cy={sy.toFixed(1)} r="7" fill="#fbbf24" />);
      elems.push(<text key={K()} x={sx.toFixed(1)} y={(sy+2.5).toFixed(1)} textAnchor="middle" fill="#7c2d12" fontSize="7.5" fontWeight="900">★</text>);
    }
  }

  // Front face frame outline
  elems.push(<polygon key={K()} points={pts([P(0,0),P(FRONT_W,0),P(FRONT_W,FRONT_H),P(0,FRONT_H)])} fill="none" stroke="#2a4a7a" strokeWidth="1.5"/>);

  return (
    <svg viewBox={`0 0 ${SW} ${SH}`} style={{ width: '100%', maxHeight: 380, display: 'block' }}>
      <defs>
        <linearGradient id="pgBg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#eef3f9"/><stop offset="1" stopColor="#dde6f2"/>
        </linearGradient>
        <filter id="pgShadow"><feDropShadow dx="3" dy="5" stdDeviation="4" floodOpacity="0.18"/></filter>
      </defs>
      <rect width={SW} height={SH} fill="url(#pgBg)" rx="10"/>
      {Array.from({length:8},(_,i)=><line key={'g'+i} x1={i*80} y1="0" x2={i*80} y2={SH} stroke="#c8d5e4" strokeWidth="0.5"/>)}
      <g filter="url(#pgShadow)">{elems}</g>
    </svg>
  );
}

// ──────────────────────── Expositor selector card with SVG silhouette
function ExpCard({ exp, selected, onSelect }) {
  const active = selected?.id === exp.id;
  return (
    <div onClick={() => onSelect(exp)} style={{
      cursor: 'pointer', borderRadius: 8, padding: '10px 8px',
      border: `2px solid ${active ? 'var(--accent)' : 'var(--border)'}`,
      background: active ? 'var(--accent-soft)' : 'var(--surface)',
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
      transition: 'border-color 120ms, background 120ms',
    }}>
      <ExpSilhouette exp={exp} active={active} />
      <div style={{ fontSize: 10.5, fontWeight: 600, textAlign: 'center', color: active ? 'var(--accent)' : 'var(--ink-soft)', lineHeight: 1.25 }}>{exp.name}</div>
      <div style={{ fontSize: 9.5, color: 'var(--ink-muted)', textAlign: 'center' }}>{exp.capacity} uds · {exp.dims}</div>
    </div>
  );
}

function ExpSilhouette({ exp, active }) {
  const c = active ? 'var(--accent)' : '#6b88aa';
  const bg = active ? 'var(--accent-soft-2)' : 'var(--surface-2)';
  const W = 56, H = 48;
  const shW = Math.min(48, 8 * exp.cols), shH = Math.max(4, Math.min(6, 36 / exp.shelves));
  const startX = (W - shW) / 2;
  const totalH = exp.shelves * (shH + 2) + 4;
  const startY = (H - totalH) / 2;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width={W} height={H} style={{ background: bg, borderRadius: 6 }}>
      <rect x={startX - 2} y={startY} width={shW + 4} height={totalH} rx="2" fill="none" stroke={c} strokeWidth="1.5"/>
      {Array.from({ length: exp.shelves }, (_, i) => (
        <rect key={i} x={startX} y={startY + 2 + i * (shH + 2)} width={shW} height={shH} rx="1" fill={c} opacity="0.45"/>
      ))}
    </svg>
  );
}

// ──────────────────────── Tab 1: Generador
function GeneradorPlanograma() {
  const D = window.APP_DATA;
  const [client, setClient] = React.useState("");
  const [expSelected, setExpSelected] = React.useState(null);
  const [generating, setGenerating] = React.useState(false);
  const [placement, setPlacement] = React.useState(null);
  const [page, setPage] = React.useState(0); // expositor pagination
  const PER_PAGE = 8;

  const generate = () => {
    if (!client || !expSelected) return;
    setGenerating(true);
    setPlacement(null);
    setTimeout(() => {
      setPlacement(generatePlanogram(client, expSelected));
      setGenerating(false);
    }, 1400);
  };

  const exps = D.expositores;
  const pageExps = exps.slice(page * PER_PAGE, (page + 1) * PER_PAGE);
  const totalPages = Math.ceil(exps.length / PER_PAGE);

  const familyCount = placement ? Object.entries(
    placement.reduce((acc, s) => { acc[s.product.family] = (acc[s.product.family] || 0) + 1; return acc; }, {})
  ) : [];

  const capacity = expSelected ? expSelected.capacity : 0;
  const usedPct = placement && capacity ? Math.round((placement.length / capacity) * 100) : 0;

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: 16 }}>
      {/* Left panel */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div className="card">
          <h3>Cliente</h3>
          <select className="select" value={client} onChange={e => setClient(e.target.value)}>
            <option value="">Selecciona cliente...</option>
            {D.clients.map(c => <option key={c.code} value={c.name}>{c.name}</option>)}
          </select>
          {client && (() => {
            const cl = D.clients.find(c => c.name === client);
            return cl ? (
              <div style={{ marginTop: 10, padding: 10, background: 'var(--surface-2)', borderRadius: 8, fontSize: 12 }}>
                <div><b>Clase {cl.class}</b> · {cl.volume}</div>
                <div style={{ color: 'var(--ink-muted)', marginTop: 2 }}>Top: {cl.topProducts.join(', ')}</div>
              </div>
            ) : null;
          })()}
        </div>

        <div className="card">
          <h3>Tipo de Expositor <span style={{ fontSize: 11, fontWeight: 400, color: 'var(--ink-muted)' }}>(22 tipos en PIM)</span></h3>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            {pageExps.map(exp => <ExpCard key={exp.id} exp={exp} selected={expSelected} onSelect={setExpSelected} />)}
          </div>
          {totalPages > 1 && (
            <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 10, alignItems: 'center' }}>
              <button className="btn-ghost" disabled={page === 0} onClick={() => setPage(p => p - 1)} style={{ padding: '4px 10px', fontSize: 12, borderRadius: 6 }}>←</button>
              <span style={{ fontSize: 11, color: 'var(--ink-muted)' }}>Pág. {page + 1}/{totalPages}</span>
              <button className="btn-ghost" disabled={page === totalPages - 1} onClick={() => setPage(p => p + 1)} style={{ padding: '4px 10px', fontSize: 12, borderRadius: 6 }}>→</button>
            </div>
          )}
        </div>

        {expSelected && (
          <div className="card" style={{ background: 'var(--accent-soft)', borderColor: 'var(--accent)' }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--accent)', marginBottom: 6 }}>{expSelected.name}</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, fontSize: 11.5, color: 'var(--ink-soft)' }}>
              <span>Estantes: <b>{expSelected.shelves}</b></span>
              <span>Columnas: <b>{expSelected.cols}</b></span>
              <span>Capacidad: <b>{expSelected.capacity} uds</b></span>
              <span>Medidas: <b>{expSelected.dims}</b></span>
            </div>
            <div style={{ marginTop: 8, fontSize: 11, color: 'var(--ink-muted)' }}>Canal: {expSelected.channel.join(' · ')}</div>
          </div>
        )}

        <button className="btn" disabled={!client || !expSelected || generating} onClick={generate} style={{ width: '100%', justifyContent: 'center', padding: 12 }}>
          <Icon.Spark /> {generating ? 'Optimizando...' : 'Generar Planograma IA'}
        </button>
      </div>

      {/* Right panel */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        {!placement && !generating && (
          <div className="card" style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: 380, textAlign: 'center', color: 'var(--ink-muted)' }}>
            <svg viewBox="0 0 64 64" width="56" height="56" style={{ marginBottom: 16, opacity: 0.35 }}>
              <rect x="8" y="8" width="48" height="48" rx="4" fill="none" stroke="currentColor" strokeWidth="2"/>
              {[18,28,38,48].map(y => <line key={y} x1="8" y1={y} x2="56" y2={y} stroke="currentColor" strokeWidth="1.5" opacity="0.5"/>)}
              {[22,36].map(x => <line key={x} x1={x} y1="8" x2={x} y2="56" stroke="currentColor" strokeWidth="1.5" opacity="0.5"/>)}
            </svg>
            <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink-soft)', marginBottom: 6 }}>Selecciona cliente y expositor</div>
            <div style={{ fontSize: 13 }}>El sistema optimizará el planograma basándose en ventas, campañas activas y características de los productos.</div>
          </div>
        )}

        {generating && (
          <div className="card" style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: 380, gap: 18 }}>
            <div style={{ width: 48, height: 48, border: '4px solid var(--border)', borderTop: '4px solid var(--accent)', borderRadius: '50%', animation: 'spin 0.9s linear infinite' }} />
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontWeight: 600, color: 'var(--accent)' }}>Optimizando planograma...</div>
              <div style={{ fontSize: 12.5, color: 'var(--ink-muted)', marginTop: 4 }}>
                Analizando ventas · Aplicando reglas de slotting · Priorizando campañas
              </div>
            </div>
            <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
          </div>
        )}

        {placement && expSelected && !generating && (
          <>
            <div className="card" style={{ padding: '12px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 10 }}>
              <div>
                <div style={{ fontWeight: 600, fontSize: 15 }}>{expSelected.name}</div>
                <div style={{ fontSize: 12, color: 'var(--ink-muted)' }}>{client} · {new Date().toLocaleDateString('es-ES')}</div>
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                <button className="btn-secondary" style={{ padding: '7px 14px', fontSize: 12.5 }}><Icon.Share /> Compartir</button>
                <button className="btn" style={{ padding: '7px 14px', fontSize: 12.5 }}><Icon.Download /> Exportar PDF</button>
              </div>
            </div>

            <div className="card" style={{ padding: '14px 16px' }}>
              <Planogram3D expositor={expSelected} placement={placement} />
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
              <KPI label="CAPACIDAD USADA" value={usedPct + '%'} sub={placement.length + ' de ' + capacity + ' slots'} />
              <KPI label="FAMILIAS" value={familyCount.length} sub="categorías activas" />
              <KPI label="EN CAMPAÑA ★" value={placement.filter(s => CAMPAIGNS.includes(s.product.name)).length} sub="posiciones" subType="info" />
              <KPI label="EYE LEVEL" value={expSelected.cols} sub="posiciones premium" subType="ok" />
            </div>

            <div className="card">
              <h3>Criterios de optimización aplicados</h3>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13 }}>
                <Rule icon="★" color="var(--warn)" text="Campañas activas en posición eye-level (estante central)" />
                <Rule icon="▲" color="var(--ok)" text="Top productos del cliente priorizados frente a categoría general" />
                <Rule icon="●" color="var(--info)" text="Productos agrupados por familia para facilitar la compra" />
                <Rule icon="↓" color="var(--ink-muted)" text="Productos de mayor volumen/peso en estantes bajos" />
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

function Rule({ icon, color, text }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', background: 'var(--surface-2)', borderRadius: 6 }}>
      <span style={{ color, fontWeight: 700, fontSize: 14, width: 16, flexShrink: 0, textAlign: 'center' }}>{icon}</span>
      <span style={{ color: 'var(--ink-soft)' }}>{text}</span>
    </div>
  );
}

// ──────────────────────── Tab 2: Análisis de Lineal
function AnalisisLineal() {
  const [state, setState] = React.useState('idle'); // idle | uploaded | analyzing | done
  const [imgName, setImgName] = React.useState('');
  const fileRef = React.useRef(null);

  const handleFile = (f) => {
    if (!f) return;
    setImgName(f.name);
    setState('uploaded');
  };

  const analyze = () => {
    setState('analyzing');
    setTimeout(() => setState('done'), 2200);
  };

  const CURRENT = [
    [null, 'Sintex N-25', null, 'Sintex N-25', 'Aqua Protect', null, 'Fijación 60s', 'Fijación 60s'],
    ['Orbafoam PRO 65', 'Orbafoam PRO 65', 'Orbafoam PRO 65', null, '1000 Usos', '1000 Usos', null, null],
    ['Perfect Finish', 'Perfect Finish', 'Sintex MS-35', 'Sintex MS-35', 'Sintex MS-35', 'MS Instant', null, null],
  ];
  const OPTIMAL = [
    ['Perfect Finish', 'Perfect Finish', 'Sintex MS-35', 'Sintex MS-35', 'Sintex MS-35', 'MS Instant', 'Orbasil N-39', 'Orbasil N-39'],
    ['Orbafoam PRO 65', 'Orbafoam PRO 65', 'Aqua Protect', 'Aqua Protect', '1000 Usos', '1000 Usos', 'Fijación 60s', 'Fijación 60s'],
    ['Sintex N-25', 'Sintex N-25', 'Sintex DM-30', 'Sintex DM-30', 'Sintex Madera', 'Sintex Madera', 'Sintex Madera', null],
  ];

  const FC = window.APP_DATA.familyColors;
  const prodColor = (name) => {
    if (!name) return null;
    const p = window.APP_DATA.products.find(x => x.name === name || name.startsWith(x.name.slice(0,8)));
    return p ? (FC[p.family] || { fill: '#94a3b8', light: '#e2e8f0' }) : { fill: '#94a3b8', light: '#e2e8f0' };
  };

  const renderGrid = (data, showGaps = false) => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      {data.map((row, ri) => (
        <div key={ri} style={{ display: 'flex', gap: 3 }}>
          {row.map((cell, ci) => {
            const fc = prodColor(cell);
            const isEmpty = !cell;
            const isCurrent = showGaps && !CURRENT[ri][ci] && OPTIMAL[ri][ci];
            return (
              <div key={ci} style={{
                flex: 1, height: 52, borderRadius: 4,
                background: isEmpty ? (showGaps && isCurrent ? 'var(--err-soft)' : 'var(--surface-2)') : fc?.fill,
                border: isEmpty ? '1.5px dashed var(--border-strong)' : '1px solid rgba(255,255,255,0.15)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 2,
                position: 'relative',
              }}>
                {cell && <div style={{ fontSize: 9, fontWeight: 700, color: '#fff', textAlign: 'center', lineHeight: 1.2 }}>
                  {cell.length > 10 ? cell.slice(0, 9) + '.' : cell}
                </div>}
                {CAMPAIGNS.includes(cell) && <div style={{ position: 'absolute', top: 2, right: 2, fontSize: 8, color: '#fbbf24' }}>★</div>}
                {showGaps && isEmpty && OPTIMAL[ri][ci] && <div style={{ fontSize: 9, color: 'var(--err)', fontWeight: 600 }}>VACÍO</div>}
              </div>
            );
          })}
        </div>
      ))}
    </div>
  );

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {state === 'idle' && (
        <div className="card" style={{ textAlign: 'center', padding: 60 }}>
          <div
            onClick={() => fileRef.current?.click()}
            onDragOver={e => e.preventDefault()}
            onDrop={e => { e.preventDefault(); handleFile(e.dataTransfer.files[0]); }}
            style={{
              border: '2.5px dashed var(--border-strong)', borderRadius: 12, padding: 50,
              cursor: 'pointer', transition: 'border-color 150ms, background 150ms',
              background: 'var(--surface-2)',
            }}
            onMouseEnter={e => e.currentTarget.style.borderColor = 'var(--accent)'}
            onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--border-strong)'}
          >
            <div style={{ width: 48, height: 48, margin: '0 auto 16px', color: 'var(--ink-muted)' }}><Icon.Camera /></div>
            <div style={{ fontWeight: 600, fontSize: 16, color: 'var(--ink-soft)' }}>Arrastra o sube una foto del lineal</div>
            <div style={{ fontSize: 13, color: 'var(--ink-muted)', marginTop: 6 }}>
              El sistema detectará los productos y posiciones usando visión artificial + optimización de slotting
            </div>
            <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginTop: 4 }}>JPG, PNG, HEIC · Máx. 20MB</div>
          </div>
          <input ref={fileRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={e => handleFile(e.target.files[0])} />
          <button className="btn-secondary" style={{ marginTop: 18 }} onClick={() => setState('done')}>
            Ver demo sin foto
          </button>
        </div>
      )}

      {state === 'uploaded' && (
        <div className="card" style={{ textAlign: 'center', padding: 40 }}>
          <div style={{ background: 'var(--ok-soft)', color: 'var(--ok)', padding: '10px 20px', borderRadius: 999, display: 'inline-flex', gap: 8, alignItems: 'center', marginBottom: 20, fontWeight: 600 }}>
            <Icon.Check /> {imgName} subido correctamente
          </div>
          <div style={{ fontSize: 13, color: 'var(--ink-muted)', marginBottom: 24 }}>
            El análisis combinará visión artificial (Azure Computer Vision) con optimización de slotting para identificar cada producto en su posición y comparar con el planograma óptimo.
          </div>
          <button className="btn" onClick={analyze} style={{ padding: '10px 28px', fontSize: 14 }}>
            <Icon.Spark /> Analizar con IA
          </button>
        </div>
      )}

      {state === 'analyzing' && (
        <div className="card" style={{ textAlign: 'center', padding: 60 }}>
          <div style={{ width: 56, height: 56, border: '5px solid var(--border)', borderTop: '5px solid var(--accent)', borderRadius: '50%', animation: 'spin 0.9s linear infinite', margin: '0 auto 24px' }} />
          <div style={{ fontWeight: 600, color: 'var(--accent)', fontSize: 16 }}>Analizando lineal...</div>
          <div style={{ fontSize: 12.5, color: 'var(--ink-muted)', marginTop: 8, lineHeight: 1.6 }}>
            Detección de objetos con Azure Computer Vision<br />
            Clasificación de productos por packaging + etiqueta<br />
            Cálculo de score vs planograma óptimo
          </div>
        </div>
      )}

      {state === 'done' && (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
            <KPI label="EFICIENCIA ACTUAL" value="68%" sub="Vs. 94% óptimo" subType="err" />
            <KPI label="HUECOS VACÍOS" value="7" sub="13% del espacio" subType="err" />
            <KPI label="MAL POSICIONADOS" value="4" sub="productos fuera de zona" subType="warn" />
            <KPI label="POTENCIAL VENTAS" value="+18%" sub="Con planograma óptimo" subType="ok" />
          </div>

          <div className="grid-2">
            <div className="card">
              <h3>📸 Estado actual detectado</h3>
              <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginBottom: 12 }}>3 estantes · 8 posiciones · Confianza detección: 91%</div>
              {renderGrid(CURRENT, true)}
              <div style={{ marginTop: 12, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                <LegendItem color="var(--surface-2)" border dashed label="Hueco vacío" />
                <LegendItem color="var(--err-soft)" border label="Falta producto" />
              </div>
            </div>
            <div className="card">
              <h3>✅ Planograma óptimo recomendado</h3>
              <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginBottom: 12 }}>Basado en ventas + campañas · Generado por IA</div>
              {renderGrid(OPTIMAL)}
              <div style={{ marginTop: 12, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                <LegendItem color="#2563eb" label="Selladores" />
                <LegendItem color="#16a34a" label="Espumas PU" />
                <LegendItem color="#7c3aed" label="Siliconas" />
              </div>
            </div>
          </div>

          <div className="card">
            <h3>Acciones recomendadas</h3>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {[
                { sev: 'err', text: 'Reubicar Perfect Finish a estante central (eye-level). Actualmente en fila inferior.' },
                { sev: 'err', text: 'Cubrir 7 huecos vacíos: añadir Orbasil N-39 (×2) y Sintex DM-30 (×2) — disponibles en almacén.' },
                { sev: 'warn', text: 'Separar Sintex N-25 Color del bloque de espumas PU — mejorar visualización por familia.' },
                { sev: 'info', text: 'Añadir cartel de campaña ★ en Perfect Finish, Sintex MS-35 y Orbafoam PRO 65.' },
              ].map((a, i) => (
                <div key={i} style={{ display: 'flex', gap: 10, padding: '10px 12px', background: 'var(--surface-2)', borderRadius: 6, borderLeft: `3px solid var(--${a.sev})`, fontSize: 13 }}>
                  <span>{a.text}</span>
                </div>
              ))}
            </div>
            <div style={{ marginTop: 14, display: 'flex', gap: 8 }}>
              <button className="btn" onClick={() => setState('idle')}>
                <Icon.Camera /> Analizar otro lineal
              </button>
              <button className="btn-secondary"><Icon.Download /> Exportar informe</button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

function LegendItem({ color, label, border, dashed }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 5, fontSize: 11 }}>
      <div style={{ width: 12, height: 12, borderRadius: 2, background: color, border: border ? `1.5px ${dashed ? 'dashed' : 'solid'} var(--border-strong)` : 'none' }} />
      <span style={{ color: 'var(--ink-muted)' }}>{label}</span>
    </div>
  );
}

// ──────────────────────── Main module
function Planogramas() {
  const [tab, setTab] = React.useState('generator');
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div className="card" style={{ padding: '0 16px', background: 'var(--surface)' }}>
        <div className="tabs" style={{ marginBottom: 0 }}>
          <button className={'tab ' + (tab === 'generator' ? 'active' : '')} onClick={() => setTab('generator')}>
            🗂 Generador de Planograma 3D
          </button>
          <button className={'tab ' + (tab === 'analysis' ? 'active' : '')} onClick={() => setTab('analysis')}>
            📸 Análisis de Lineal (VA + Slotting)
          </button>
        </div>
      </div>

      {tab === 'generator' && <GeneradorPlanograma />}
      {tab === 'analysis' && <AnalisisLineal />}
    </div>
  );
}

Object.assign(window, { Planogramas });
