// ─────────────────────────────────────────────────────
// LEADS view — hydrated from /api/records.
// Mirrors public/js/leads-list.js behavior (filters, sort, export, import).
// ─────────────────────────────────────────────────────

const Sparkline = ({ values, color = 'var(--glass)' }) => {
  const w = 80, h = 24;
  const max = Math.max(...values), min = Math.min(...values);
  const range = max - min || 1;
  const step = w / (values.length - 1);
  const points = values.map((v, i) => `${i*step},${h - ((v - min) / range) * h}`).join(' ');
  return (
    <svg className="spark" width={w} height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      <polyline fill="none" stroke={color} strokeWidth="1.5" points={points} />
      <polyline fill={color} fillOpacity="0.10" stroke="none" points={`0,${h} ${points} ${w},${h}`} />
    </svg>
  );
};

const VendedorChip = ({ code }) => {
  const v = window.DATA.VENDEDORES.find(x => x.code === code) || { code: code || '—', color: '#6b7079' };
  const label = v.code || '—';
  return (
    <span className="vend">
      <span className="av" style={{ background: v.color }}>{label.slice(0, 1)}</span>
      <span>{label}</span>
    </span>
  );
};

// Map backend producto canonico → UI mock id (data.jsx PRODUCTOS).
const PROD_CANON_TO_ID = {
  'cortina_o_corredera_de_cristal': 'cortina',
  'barandilla_de_cristal': null,
  'techo_fijo_o_móvil': 'techo_f',
  'pérgola_bioclimática': 'pergola',
  'otro': null,
};
const PROD_LABELS = {
  'cortina_o_corredera_de_cristal': 'Cortina/corredera',
  'barandilla_de_cristal': 'Barandilla',
  'techo_fijo_o_móvil': 'Techo',
  'pérgola_bioclimática': 'Pérgola',
  'otro': 'Otro',
};

const ProductIcons = ({ canonicos }) => {
  const items = canonicos || [];
  if (!items.length) return <span className="muted">—</span>;
  return (
    <span className="row-flex">
      {items.slice(0, 3).map((c, i) => {
        const id = PROD_CANON_TO_ID[c];
        const p = id ? window.DATA.PRODUCTOS.find(x => x.id === id) : null;
        const label = PROD_LABELS[c] || c;
        return (
          <span key={i} className="prod tip" data-tip={label}>
            {p ? <img src={p.img} alt=""/> : <span style={{fontSize:10,padding:'2px 4px'}}>{label.slice(0,3)}</span>}
          </span>
        );
      })}
      {items.length > 3 && <span className="muted" style={{fontSize:11}}>+{items.length-3}</span>}
    </span>
  );
};

const fmtEur = (n) => n == null || isNaN(n) ? '—' : new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(n);
const fmtDateDmy = (s) => s || '—';

// Parse importe text from backend → number.
const parseImporte = (t) => {
  if (!t) return 0;
  const n = parseFloat(String(t).replace(/[^\d,.-]/g, '').replace(',', '.'));
  return isNaN(n) ? 0 : n;
};

// Normalize backend estado string → ESTADOS_LEAD key.
const normEstado = (raw) => {
  if (!raw) return '';
  const k = String(raw).trim().toUpperCase().replace(/\s+/g, '_');
  return window.DATA.ESTADOS_LEAD[k] ? k : k;
};

// Adapter — backend row → UI shape used by table + drawer.
const toUiRow = (r) => {
  let prods = [];
  try { prods = JSON.parse(r.productos_interesados || '[]'); } catch { prods = []; }
  const estado = normEstado(r.estado);
  return {
    id: r.id,
    np: r.numero_presupuesto || '',
    nombre: r.nombre || '',
    tel: r.telefono || '',
    email: r.email || '',
    loc: r.localidad || '',
    prov: r.provincia || '',
    direccion: r.direccion || '',
    desc: r.descripcion_del_producto || '',
    interes: parseInt(r.interes_pct || '0', 10) || 0,
    estado,
    importe: parseImporte(r.importe),
    importeRaw: r.importe || '',
    productosCanon: Array.isArray(prods) ? prods : [],
    fecha_solicitud: r.fecha_solicitud || '',
    fecha_pre: r.fecha_envio_pto || '',
    fecha_inst: r.fecha_instalacion || '',
    fecha_acept: r.fecha_aceptacion_presupuesto || '',
    accion_dia: r.fecha_proxima_action || '',
    accion: r.accion || '',
    obs: r.observaciones_comentario_estado || '',
    vendedor: r.vendedor || '',
    origen: r.origen || '',
    mes: r.mes || '',
    via_envio_default: r.via_envio_default === 'wa' ? 'wa' : 'mail',
  };
};

// Build mailto: / wa.me URLs for a lead row.
const buildContactUrl = (channel, row) => {
  if (channel === 'mail') {
    const email = (row.email || '').trim();
    if (!email) return { href: '#', disabled: true, title: 'Sin email' };
    const subject = `Presupuesto ${row.np || ''}`.trim();
    const body = `Hola ${row.nombre || ''},\n\n`;
    const q = `subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
    return { href: `mailto:${email}?${q}`, disabled: false, title: `Email a ${email}` };
  }
  if (channel === 'wa') {
    const raw = (row.tel || '').trim();
    const digits = raw.replace(/[^\d]/g, '');
    if (!digits) return { href: '#', disabled: true, title: 'Sin teléfono' };
    const text = `Hola ${row.nombre || ''}, te contacto desde Kurtenglass por el presupuesto ${row.np || ''}.`;
    return { href: `https://wa.me/${digits}?text=${encodeURIComponent(text)}`, disabled: false, title: `WhatsApp a ${raw}` };
  }
  return { href: '#', disabled: true, title: '' };
};

// ─────────────────────────────────────────────────────
// Multi-select dropdown chip.
// ─────────────────────────────────────────────────────
const MultiChip = ({ icon, label, options, selected, onChange }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('click', close);
    return () => document.removeEventListener('click', close);
  }, []);
  const toggle = (v) => {
    const has = selected.includes(v);
    onChange(has ? selected.filter(x => x !== v) : [...selected, v]);
  };
  const display = selected.length ? `${label}: ${selected.length}` : label;
  return (
    <div ref={ref} style={{position:'relative',display:'inline-block'}}>
      <button className={`chip${selected.length?' active':''}`} onClick={(e)=>{e.stopPropagation(); setOpen(o=>!o);}} type="button">
        {icon && <Icon name={icon} />} {display} <Icon name="chevron_down" size={11}/>
      </button>
      {open && (
        <div style={{position:'absolute',top:'calc(100% + 4px)',left:0,zIndex:50,background:'var(--surface)',border:'1px solid var(--line)',borderRadius:6,boxShadow:'0 8px 24px rgba(0,0,0,.12)',minWidth:180,maxHeight:280,overflow:'auto'}}>
          {options.length === 0 && <div style={{padding:8,fontSize:12,color:'var(--ink-3)'}}>Sin opciones</div>}
          {options.map(opt => {
            const v = typeof opt === 'string' ? opt : opt.value;
            const lbl = typeof opt === 'string' ? opt : opt.label;
            const on = selected.includes(v);
            return (
              <label key={v} style={{display:'flex',alignItems:'center',gap:8,padding:'6px 10px',fontSize:12.5,cursor:'pointer'}}>
                <input type="checkbox" checked={on} onChange={()=>toggle(v)}/>
                <span>{lbl}</span>
              </label>
            );
          })}
          {selected.length > 0 && (
            <div style={{borderTop:'1px solid var(--line)',padding:'4px 10px'}}>
              <button type="button" className="btn ghost sm" onClick={()=>onChange([])} style={{width:'100%'}}>Limpiar</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const DateRangeChip = ({ field, from, to, onChange }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('click', close);
    return () => document.removeEventListener('click', close);
  }, []);
  const has = field && (from || to);
  return (
    <div ref={ref} style={{position:'relative',display:'inline-block'}}>
      <button className={`chip${has?' active':''}`} type="button" onClick={(e)=>{e.stopPropagation(); setOpen(o=>!o);}}>
        <Icon name="calendar"/> {has ? `${field}: ${from||'…'}→${to||'…'}` : 'Rango fecha'} <Icon name="chevron_down" size={11}/>
      </button>
      {open && (
        <div style={{position:'absolute',top:'calc(100% + 4px)',left:0,zIndex:50,background:'var(--surface)',border:'1px solid var(--line)',borderRadius:6,boxShadow:'0 8px 24px rgba(0,0,0,.12)',padding:10,display:'flex',flexDirection:'column',gap:6,minWidth:240}}>
          <select value={field || ''} onChange={e=>onChange({field: e.target.value, from, to})}
            style={{padding:'4px 8px',border:'1px solid var(--line)',borderRadius:4,background:'var(--surface)',fontSize:12}}>
            <option value="">Campo fecha…</option>
            <option value="fecha_solicitud">F. solicitud</option>
            <option value="fecha_envio_pto">F. envío presup.</option>
            <option value="fecha_aceptacion_presupuesto">F. aceptación</option>
            <option value="fecha_instalacion">F. instalación</option>
          </select>
          <input type="date" value={from || ''} onChange={e=>onChange({field, from: e.target.value, to})} style={{padding:'4px 8px',border:'1px solid var(--line)',borderRadius:4,background:'var(--surface)',fontSize:12,color:'var(--ink)'}}/>
          <input type="date" value={to || ''} onChange={e=>onChange({field, from, to: e.target.value})} style={{padding:'4px 8px',border:'1px solid var(--line)',borderRadius:4,background:'var(--surface)',fontSize:12,color:'var(--ink)'}}/>
          {has && <button type="button" className="btn ghost sm" onClick={()=>onChange({field:'',from:'',to:''})}>Limpiar</button>}
        </div>
      )}
    </div>
  );
};

// ─────────────────────────────────────────────────────
// Main view
// ─────────────────────────────────────────────────────
const LeadsView = ({ onOpen, refreshKey, onRefresh, onToast }) => {
  const [rows, setRows]       = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [filters, setFilters] = React.useState({ estados: [], vendedores: [], origenes: [], meses: [], productos: [] });

  const [search, setSearch]   = React.useState('');
  const [vendedor, setVend]   = React.useState([]);
  const [origen, setOrig]     = React.useState([]);
  const [mes, setMes]         = React.useState('');
  const [productos, setProd]  = React.useState([]);
  const [dateRange, setDate]  = React.useState({ field:'', from:'', to:'' });
  const [estadoFilter, setEstadoFilter] = React.useState('todos');

  const [sortBy, setSortBy]   = React.useState('fecha_solicitud');
  const [sortDir, setSortDir] = React.useState('desc');
  const [sel, setSel]         = React.useState(new Set());
  const [page, setPage]       = React.useState(1);
  const PAGE_SIZE = 50;

  const [formOpen, setFormOpen] = React.useState(false);
  const [editId, setEditId]     = React.useState(null);
  const [importing, setImporting] = React.useState(false);
  const [importPreview, setImportPreview] = React.useState(null);
  const fileRef = React.useRef(null);

  // Load filter options once
  React.useEffect(() => {
    API.get('/api/filters').then(setFilters).catch(()=>{});
  }, []);

  // Listen for edit requests from drawer
  React.useEffect(() => {
    const handler = (e) => { setEditId(e.detail.id); setFormOpen(true); };
    window.addEventListener('erp:edit-lead', handler);
    return () => window.removeEventListener('erp:edit-lead', handler);
  }, []);

  // Build query params from state
  const buildParams = React.useCallback(() => {
    const p = new URLSearchParams();
    if (search.trim()) p.set('search', search.trim());
    vendedor.forEach(v => p.append('vendedor', v));
    origen.forEach(v => p.append('origen', v));
    if (mes) p.set('mes', mes);
    if (productos.length) p.set('productos', productos.join(','));
    if (dateRange.field && (dateRange.from || dateRange.to)) {
      p.set('date_field', dateRange.field);
      if (dateRange.from) p.set('date_from', dateRange.from);
      if (dateRange.to)   p.set('date_to',   dateRange.to);
    }
    if (estadoFilter !== 'todos') {
      if (estadoFilter === 'pdte') {
        // Backend filters by estado equality → fall back to client-side filter for "pendientes"
      } else {
        p.append('estado', estadoFilter);
      }
    }
    if (sortBy) { p.set('sort_by', sortBy); p.set('sort_dir', sortDir); }
    return p;
  }, [search, vendedor, origen, mes, productos, dateRange, estadoFilter, sortBy, sortDir]);

  // Fetch records (debounced on search input)
  React.useEffect(() => {
    let alive = true;
    const t = setTimeout(() => {
      setLoading(true);
      API.get(`/api/records?${buildParams()}`).then(data => {
        if (!alive) return;
        const ui = (data || []).map(toUiRow);
        const filtered = estadoFilter === 'pdte'
          ? ui.filter(l => l.estado.startsWith('PDTE_'))
          : ui;
        setRows(filtered);
        setPage(1);
        setLoading(false);
      }).catch(e => {
        if (!alive) return;
        setLoading(false);
        onToast && onToast(e.message || 'Error al cargar leads', true);
      });
    }, 250);
    return () => { alive = false; clearTimeout(t); };
  }, [buildParams, refreshKey]);

  // GUT-63 — abrir el lead pendiente (navegación inversa desde presupuesto).
  React.useEffect(() => {
    const pendingId = (typeof window !== 'undefined') ? window.__erpPendingLeadId : null;
    if (!pendingId || !rows.length) return;
    const match = rows.find(l => String(l.id) === String(pendingId));
    if (match) { onOpen(match); window.__erpPendingLeadId = null; }
  }, [rows]);

  // KPIs over current loaded set
  const total      = rows.reduce((s, l) => s + l.importe, 0);
  const aceptados  = rows.filter(l => l.estado === 'ACEPTADO');
  const enviados   = rows.filter(l => l.estado === 'ENVIADO');
  const pendientes = rows.filter(l => l.estado.startsWith('PDTE_'));

  const totalPages = Math.max(1, Math.ceil(rows.length / PAGE_SIZE));
  const pageRows   = rows.slice((page-1)*PAGE_SIZE, page*PAGE_SIZE);

  const toggleSel = (id) => {
    const n = new Set(sel);
    n.has(id) ? n.delete(id) : n.add(id);
    setSel(n);
  };

  const setSort = (k) => {
    if (sortBy === k) setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
    else { setSortBy(k); setSortDir('desc'); }
  };

  const sortIndicator = (k) => sortBy === k ? (sortDir === 'asc' ? '↑' : '↓') : '↕';

  // Export
  const today = new Date().toISOString().slice(0, 10);
  const onExport = (kind) => {
    const url = `/api/export/records/${kind}?${buildParams()}`;
    const ext = kind === 'excel' ? 'xlsx' : 'pdf';
    API.download(url, `leads_${today}.${ext}`).catch(e => onToast && onToast(e.message || 'Error al exportar', true));
  };

  // Import
  const onImportClick = () => { if (fileRef.current) { fileRef.current.value = ''; fileRef.current.click(); }};
  const onImportFile = async (ev) => {
    const file = ev.target.files[0];
    if (!file) return;
    setImporting(true);
    try {
      const content = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = e => resolve(e.target.result.split(',')[1]);
        reader.onerror = reject;
        reader.readAsDataURL(file);
      });
      const payload = { filename: file.name, content };
      const data = await API.post('/api/import/leads/preview', payload);
      setImportPreview({ ...data, payload });
    } catch (e) {
      onToast && onToast(e.message || 'Error al leer archivo', true);
    } finally {
      setImporting(false);
    }
  };
  const onImportConfirm = async () => {
    if (!importPreview) return;
    try {
      const r = await API.post('/api/import/leads', importPreview.payload);
      const msg = `${r.imported} lead${r.imported !== 1 ? 's' : ''} importado${r.imported !== 1 ? 's' : ''}`;
      onToast && onToast(r.errors?.length ? `${msg} (${r.errors.length} errores)` : msg);
      setImportPreview(null);
      onRefresh && onRefresh();
    } catch (e) {
      onToast && onToast(e.message || 'Error al importar', true);
    }
  };

  return (
    <>
      <div className="page-h">
        <div>
          <h1>Leads</h1>
          <div className="sub">Gestión comercial de presupuestos · {rows.length} registros</div>
        </div>
        <div className="page-h-actions">
          <button className="btn" onClick={onImportClick} disabled={importing}><Icon name="upload" /> {importing?'Leyendo…':'Importar'}</button>
          <input ref={fileRef} type="file" accept=".xlsx,.xls,.csv" style={{display:'none'}} onChange={onImportFile}/>
          <button className="btn" onClick={()=>onExport('excel')}><Icon name="download" /> Excel</button>
          <button className="btn" onClick={()=>onExport('pdf')}><Icon name="download" /> PDF</button>
          <button className="btn primary" onClick={()=>{ setEditId(null); setFormOpen(true); }}><Icon name="plus" /> Nuevo lead</button>
        </div>
      </div>

      {/* KPIs */}
      <div className="kpi-grid">
        <div className="kpi">
          <div className="lbl">Volumen total</div>
          <div className="row"><div className="num">{fmtEur(total)}</div></div>
          <Sparkline values={[12,18,15,22,28,24,30,34,32,40,38,46]} />
        </div>
        <div className="kpi">
          <div className="lbl"><span className="dot" style={{background:'var(--ok)'}}/> Aceptados</div>
          <div className="row"><div className="num">{aceptados.length}</div><span className="sub">{fmtEur(aceptados.reduce((s,l)=>s+l.importe,0))}</span></div>
          <Sparkline values={[2,3,2,4,3,5,4,6,5,7,6,8]} color="var(--ok)" />
        </div>
        <div className="kpi">
          <div className="lbl"><span className="dot" style={{background:'var(--info)'}}/> Enviados</div>
          <div className="row"><div className="num">{enviados.length}</div><span className="sub">{fmtEur(enviados.reduce((s,l)=>s+l.importe,0))}</span></div>
          <Sparkline values={[5,4,6,5,7,6,8,7,9,8,10,9]} color="var(--info)" />
        </div>
        <div className="kpi">
          <div className="lbl"><span className="dot" style={{background:'var(--warn)'}}/> Pendientes</div>
          <div className="row"><div className="num">{pendientes.length}</div><span className="sub">{fmtEur(pendientes.reduce((s,l)=>s+l.importe,0))}</span></div>
          <Sparkline values={[8,7,9,8,10,9,11,10,12,11,13,12]} color="var(--warn)" />
        </div>
        <div className="kpi">
          <div className="lbl">Tasa conversión</div>
          <div className="row">
            <div className="num">{rows.length ? Math.round(aceptados.length/rows.length*100) : 0}%</div>
          </div>
          <Sparkline values={[18,20,22,21,24,23,26,25,28,27,30,28]} color="var(--carbon)" />
        </div>
      </div>

      {/* Toolbar */}
      <div className="toolbar">
        <div className="tb-search">
          <Icon name="search" />
          <input placeholder="Nombre, teléfono, email, nº presupuesto…" value={search} onChange={e=>setSearch(e.target.value)}/>
        </div>
        <div className="tb-divider" />
        <select value={mes} onChange={e=>setMes(e.target.value)}
          style={{padding:'4px 8px',border:'1px solid var(--line)',borderRadius:4,background:'var(--surface)',fontSize:12}}>
          <option value="">Mes: todos</option>
          {(filters.meses || []).map(m => <option key={m} value={m}>{m}</option>)}
        </select>
        <MultiChip icon="leads" label="Vendedor" options={filters.vendedores || []} selected={vendedor} onChange={setVend}/>
        <MultiChip icon="package" label="Productos" options={(filters.productos||[]).map(p => ({value:p, label: PROD_LABELS[p] || p}))} selected={productos} onChange={setProd}/>
        <MultiChip label="Origen" options={filters.origenes || []} selected={origen} onChange={setOrig}/>
        <DateRangeChip field={dateRange.field} from={dateRange.from} to={dateRange.to} onChange={setDate}/>
        <div className="tb-spacer" />
        <div className="seg">
          <button className={estadoFilter==='todos'?'on':''}    onClick={()=>setEstadoFilter('todos')}>Todos</button>
          <button className={estadoFilter==='pdte'?'on':''}     onClick={()=>setEstadoFilter('pdte')}>Pendientes</button>
          <button className={estadoFilter==='enviado'?'on':''}  onClick={()=>setEstadoFilter('enviado')}>Enviados</button>
          <button className={estadoFilter==='aceptado'?'on':''} onClick={()=>setEstadoFilter('aceptado')}>Aceptados</button>
        </div>
      </div>

      {/* Table */}
      <div className="tbl-wrap">
        <div className="tbl-scroll">
          <table className="tbl">
            <thead>
              <tr>
                <th style={{width:32}}><span className="ck" /></th>
                <th className="sortable" onClick={()=>setSort('numero_presupuesto')}>Nº Presup. <span className="sort">{sortIndicator('numero_presupuesto')}</span></th>
                <th className="sortable" onClick={()=>setSort('nombre')}>Cliente <span className="sort">{sortIndicator('nombre')}</span></th>
                <th>Vendedor</th>
                <th className="sortable" onClick={()=>setSort('fecha_solicitud')}>F. solicitud <span className="sort">{sortIndicator('fecha_solicitud')}</span></th>
                <th>Estado</th>
                <th>Productos</th>
                <th>Localidad</th>
                <th className="sortable" onClick={()=>setSort('importe')} style={{textAlign:'right'}}>Importe <span className="sort">{sortIndicator('importe')}</span></th>
                <th>Interés</th>
                <th>Próx. acción</th>
                <th>Origen</th>
                <th style={{width:78}}>Contacto</th>
                <th style={{width:32}}/>
              </tr>
            </thead>
            <tbody>
              {loading && (
                <tr><td colSpan={14} style={{textAlign:'center',padding:30,color:'var(--ink-3)'}}>Cargando…</td></tr>
              )}
              {!loading && pageRows.length === 0 && (
                <tr><td colSpan={14} style={{textAlign:'center',padding:30,color:'var(--ink-3)'}}>Sin resultados</td></tr>
              )}
              {!loading && pageRows.map(l => {
                const e = window.DATA.ESTADOS_LEAD[l.estado] || { label: l.estado || '—', cls: '' };
                const isSel = sel.has(l.id);
                return (
                  <tr key={l.id} className={isSel ? 'selected' : ''} onClick={() => onOpen(l)}>
                    <td onClick={(ev)=>{ev.stopPropagation(); toggleSel(l.id);}}>
                      <span className={`ck ${isSel?'on':''}`} />
                    </td>
                    <td className="num strong">{l.np}</td>
                    <td className="strong truncate">{l.nombre}</td>
                    <td><VendedorChip code={l.vendedor}/></td>
                    <td className="num muted">{fmtDateDmy(l.fecha_solicitud)}</td>
                    <td><span className={`pill ${e.cls}`}><span className="d"/>{e.label}</span></td>
                    <td><ProductIcons canonicos={l.productosCanon} /></td>
                    <td>{l.loc}</td>
                    <td className="num right strong">{l.importe ? fmtEur(l.importe) : <span className="muted">—</span>}</td>
                    <td>
                      <div className="row-flex">
                        <span className={`pbar ${l.interes>=80?'ok':l.interes>=50?'warn':''}`}><i style={{width:`${l.interes}%`}}/></span>
                        <span className="num muted" style={{fontSize:11}}>{l.interes}%</span>
                      </div>
                    </td>
                    <td className="num muted">{fmtDateDmy(l.accion_dia)}</td>
                    <td><span className="tag">{l.origen}</span></td>
                    <td onClick={(ev)=>ev.stopPropagation()}>
                      {(() => {
                        const mail = buildContactUrl('mail', l);
                        const wa = buildContactUrl('wa', l);
                        const primary = l.via_envio_default === 'wa' ? wa : mail;
                        const secondary = l.via_envio_default === 'wa' ? mail : wa;
                        const renderBtn = (info, label, isPrimary) => info.disabled
                          ? <button className="icon-btn" disabled title={info.title} style={{opacity:.35,cursor:'not-allowed'}}>{label}</button>
                          : <a className="icon-btn" href={info.href} target="_blank" rel="noopener noreferrer" title={info.title} style={isPrimary?{fontWeight:600}:undefined}>{label}</a>;
                        return (
                          <div className="row-flex" style={{gap:4}}>
                            {renderBtn(primary, l.via_envio_default === 'wa' ? '💬' : '✉️', true)}
                            {renderBtn(secondary, l.via_envio_default === 'wa' ? '✉️' : '💬', false)}
                          </div>
                        );
                      })()}
                    </td>
                    <td onClick={(ev)=>ev.stopPropagation()}>
                      <button className="icon-btn" onClick={()=>{ setEditId(l.id); setFormOpen(true); }}><Icon name="edit" size={13}/></button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginTop:10,fontSize:11.5,color:'var(--ink-3)'}}>
        <div>Mostrando {pageRows.length} de {rows.length} · {sel.size} seleccionados</div>
        <div className="row-flex">
          <button className="btn ghost sm" disabled={page<=1} onClick={()=>setPage(p=>Math.max(1,p-1))}><Icon name="chevron_left" size={11}/></button>
          <span className="mono">{page} / {totalPages}</span>
          <button className="btn ghost sm" disabled={page>=totalPages} onClick={()=>setPage(p=>Math.min(totalPages,p+1))}><Icon name="chevron_right" size={11}/></button>
        </div>
      </div>

      {formOpen && (
        <LeadForm
          leadId={editId}
          vendedores={filters.vendedores}
          origenes={filters.origenes}
          onClose={()=>{ setFormOpen(false); setEditId(null); }}
          onSaved={()=>{ onRefresh && onRefresh(); }}
          onToast={onToast}
        />
      )}

      {importPreview && (
        <ImportPreviewModal data={importPreview} onCancel={()=>setImportPreview(null)} onConfirm={onImportConfirm}/>
      )}
    </>
  );
};

const ImportPreviewModal = ({ data, onCancel, onConfirm }) => {
  const cols = [
    { k:'nombre', l:'Nombre' }, { k:'telefono', l:'Teléfono' }, { k:'email', l:'Email' },
    { k:'localidad', l:'Localidad' }, { k:'provincia', l:'Provincia' },
    { k:'fecha_solicitud', l:'F. solicitud' }, { k:'mes', l:'Mes' },
    { k:'descripcion_del_producto', l:'Descripción' }, { k:'origen', l:'Origen' },
  ];
  const [busy, setBusy] = React.useState(false);
  const total = data.total || 0;
  const preview = data.preview || [];
  const handle = async () => { setBusy(true); await onConfirm(); setBusy(false); };
  return (
    <div className="modal-bg open" onClick={(e)=>{ if (e.target.classList.contains('modal-bg')) onCancel(); }}
      style={{position:'fixed',inset:0,background:'rgba(0,0,0,.35)',zIndex:200,display:'flex',alignItems:'flex-start',justifyContent:'center',padding:'40px 20px',overflow:'auto'}}>
      <div style={{background:'var(--surface)',border:'1px solid var(--line)',borderRadius:8,width:'min(1100px,100%)'}} onClick={e=>e.stopPropagation()}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'14px 18px',borderBottom:'1px solid var(--line)'}}>
          <div>
            <h3 style={{margin:0,fontSize:15}}>Previsualización de importación</h3>
            <div style={{fontSize:12,color:'var(--ink-3)',marginTop:2}}>{total} lead{total!==1?'s':''} · mostrando {preview.length}</div>
          </div>
          <button className="icon-btn" onClick={onCancel}><Icon name="x"/></button>
        </div>
        <div style={{maxHeight:'60vh',overflow:'auto'}}>
          <table className="tbl">
            <thead><tr>{cols.map(c => <th key={c.k}>{c.l}</th>)}</tr></thead>
            <tbody>
              {preview.map((row, i) => row._error ? (
                <tr key={i}><td colSpan={cols.length} style={{color:'var(--err)'}}>{row._error}</td></tr>
              ) : (
                <tr key={i}>{cols.map(c => <td key={c.k}>{row[c.k] || '—'}</td>)}</tr>
              ))}
            </tbody>
          </table>
        </div>
        <div style={{display:'flex',justifyContent:'flex-end',gap:8,padding:'12px 18px',borderTop:'1px solid var(--line)'}}>
          <button className="btn ghost" onClick={onCancel}>Cancelar</button>
          <button className="btn primary" onClick={handle} disabled={busy}>{busy?'Importando…':`Confirmar (${total})`}</button>
        </div>
      </div>
    </div>
  );
};

window.LeadsView      = LeadsView;
window.fmtEur         = fmtEur;
window.fmtDateDmy     = fmtDateDmy;
window.VendedorChip   = VendedorChip;
window.ProductIcons   = ProductIcons;
window.Sparkline      = Sparkline;
window.toUiRow        = toUiRow;
window.buildContactUrl = buildContactUrl;
window.PROD_LABELS    = PROD_LABELS;
window.PROD_CANON_TO_ID = PROD_CANON_TO_ID;
