// ROCA GOLF — v4.0 · Importar Presupuesto por IA (Claude)
// Sube el .xlsx del presupuesto de un proyecto; la IA extrae subtotal/total/total+impuesto
// y los insumos del catálogo. El usuario revisa, ajusta en masa y aprueba: se llena
// ADMINISTRADOR DE PROYECTOS y se crean en masa las alertas (Presupuesto Global por Insumo).

function moneyP(n) { try { return '$' + fmtMoney(Number(n) || 0); } catch { return '$' + (Number(n)||0).toFixed(2); } }

function ScoreBadgeP({ score }) {
  if (score === null || score === undefined) return null;
  const c = score >= 85 ? 'var(--rg-flag-ok)' : (score >= 60 ? 'var(--rg-flag-warn)' : 'var(--rg-flag-over)');
  return <span className="rg-mono" style={{ fontSize:10.5, fontWeight:700, color:c, background:c+'18', border:'1px solid '+c+'55', borderRadius:4, padding:'1px 5px' }}>{score}%</span>;
}

function ImportPresupuestoView({ onNav, user, onLogout }) {
  const { data: proyectos } = useApiData('proyectos.php');
  const fileRef = useRef(null);

  const [moneda, setMoneda]     = useState('MXN');
  const [tc, setTc]             = useState(1);
  const [uploading, setUploading] = useState(false);
  const [saving, setSaving]     = useState(false);
  const [prev, setPrev]         = useState(null);   // respuesta de action=preview (editable)
  const [debugMode, setDebugMode] = useState(false);
  const [debug, setDebug]       = useState(null);   // respuesta de action=debug (paso a paso)

  // Selección de proyecto destino
  const [projMode, setProjMode]     = useState('existing'); // 'existing' | 'nuevo'
  const [selProjId, setSelProjId]   = useState('');
  const [nuevoNombre, setNuevoNombre] = useState('');
  const [seedProy, setSeedProy]     = useState(false);
  const [reemplazarAlertas, setReemplazarAlertas] = useState(false);   // borrar alertas previas del proyecto

  // Controles masivos
  const [bulkFi, setBulkFi]   = useState('');
  const [bulkFf, setBulkFf]   = useState('');
  const [bulkUmb, setBulkUmb] = useState(80);

  async function handleFile(e) {
    const file = e.target.files && e.target.files[0];
    e.target.value = '';
    if (!file) return;
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append('file', file);
      fd.append('moneda', moneda);
      fd.append('tc', moneda === 'MXN' ? 1 : (Number(tc) || 1));
      const act = debugMode ? 'debug' : 'preview';
      const res = await fetch('api/import_presupuesto.php?action=' + act, {
        method: 'POST', credentials: 'same-origin',
        headers: getCsrfToken() ? { 'X-CSRF-Token': getCsrfToken() } : {}, body: fd,
      });
      const json = await res.json();
      if (!json.ok) throw new Error(json.error || 'Error al analizar el archivo');
      if (debugMode) {
        setDebug(json.data); setPrev(null);
        const fail = (json.data.steps || []).find(s => !s.ok);
        if (fail) toast.error('Diagnóstico: falló en “' + fail.label + '”');
        else toast.success('Diagnóstico completado sin errores');
        return;
      }
      setDebug(null);
      const d = json.data;
      setPrev(d);
      // Inicializar selección de proyecto
      if (d.proyecto && d.proyecto.id) { setProjMode('existing'); setSelProjId(String(d.proyecto.id)); }
      else { setProjMode('nuevo'); setSelProjId(''); }
      setNuevoNombre((d.proyecto && d.proyecto.nombre_detectado) || '');
      toast.success(`IA: ${d.resumen_ia.insumos_detectados} insumos (${d.resumen_ia.con_match} con match). Revisa y aprueba.`);
    } catch (err) { toast.error(err.message); }
    finally { setUploading(false); }
  }

  const setAdmin = (k, v) => setPrev(p => ({ ...p, admin: { ...p.admin, [k]: v } }));
  const setUtil  = (k, v) => setPrev(p => ({ ...p, utilidad: { ...p.utilidad, [k]: v } }));
  const setRow   = (i, k, v) => setPrev(p => ({ ...p, alertas: p.alertas.map((r, idx) => idx === i ? { ...r, [k]: v } : r) }));
  const setGrupo = (i, k, v) => setPrev(p => ({ ...p, grupos_costos: (p.grupos_costos || []).map((g, idx) => idx === i ? { ...g, [k]: v } : g) }));
  const addGrupo = () => setPrev(p => ({ ...p, grupos_costos: [...(p.grupos_costos || []), { nombre: '', total_mxn: 0, total_orig: 0 }] }));
  const delGrupo = (i) => setPrev(p => ({ ...p, grupos_costos: (p.grupos_costos || []).filter((_, idx) => idx !== i) }));

  function applyBulk() {
    setPrev(p => ({ ...p, alertas: p.alertas.map(r => (r.incluir && !r.sin_match) ? {
      ...r,
      fecha_inicio: bulkFi || r.fecha_inicio,
      fecha_fin:    bulkFf || r.fecha_fin,
      pct_umbral:   Number(bulkUmb) || r.pct_umbral,
    } : r) }));
    toast.success('Aplicado a las filas incluidas');
  }

  async function commit() {
    if (!prev) return;
    if (projMode === 'nuevo' && !nuevoNombre.trim()) { toast.error('Escribe el nombre del proyecto nuevo'); return; }
    const incluidas = prev.alertas.filter(r => r.incluir && r.insumoid);
    if (!incluidas.length && projMode === 'existing') {
      if (!window.confirm('No hay alertas a crear. ¿Guardar solo el presupuesto/utilidad del proyecto?')) return;
    }
    // Autorización para el reemplazo total de alertas (solo si hay algo que poner).
    if (reemplazarAlertas && incluidas.length > 0) {
      const nom = projMode === 'existing'
        ? ((proyectos || []).find(p => p.id === Number(selProjId))?.nombre || 'el proyecto seleccionado')
        : nuevoNombre.trim();
      if (!window.confirm(`Se ELIMINARÁN todas las alertas actuales de "${nom}" y se reemplazarán por las ${incluidas.length} nuevas. Esta acción no se puede deshacer. ¿Continuar?`)) return;
    }
    setSaving(true);
    try {
      const body = {
        proyecto: projMode === 'existing'
          ? { id: Number(selProjId) || 0, nombre_detectado: prev.proyecto?.nombre_detectado || '' }
          : { id: 0, nombre_nuevo: nuevoNombre.trim(), nombre_detectado: prev.proyecto?.nombre_detectado || '' },
        moneda: prev.moneda, tc: prev.tc,
        presupuesto_total: Math.round((Number(prev.admin.total)||0) * (1 + (Number(prev.admin.impuesto_pct)||0)/100) * 100) / 100,
        seed_proyeccion: seedProy,
        reemplazar_alertas: reemplazarAlertas,
        utilidad: {
          original:   Number(prev.utilidad.original)   || 0,
          revisado:   Number(prev.utilidad.revisado)   || 0,
          proyectado: Number(prev.utilidad.proyectado) || 0,
        },
        alertas: prev.alertas.map(r => ({
          insumoid: r.insumoid, clave: r.clave, codigofamilia: r.codigofamilia,
          descripcion: r.descripcion, monto_mxn: r.monto_mxn,
          pct_umbral: r.pct_umbral, fecha_inicio: r.fecha_inicio, fecha_fin: r.fecha_fin,
          incluir: r.incluir, reemplazar: r.reemplazar,
        })),
        grupos_costos: (prev.grupos_costos || []).map(g => ({ nombre: g.nombre, total_mxn: g.total_mxn })),
      };
      const res = await apiFetch('import_presupuesto.php?action=commit', 'POST', body);
      toast.success(`Listo: ${res.creadas} creadas, ${res.actualizadas} actualizadas, ${res.omitidas} omitidas${res.alertas_borradas ? `, ${res.alertas_borradas} anteriores eliminadas` : ''}.`);
      setPrev(null);
      onNav && onNav('admin_proy');
    } catch (err) { toast.error(err.message); }
    finally { setSaving(false); }
  }

  const a = prev?.admin || {};
  const admTotal = Number(a.total) || 0;                 // Total sin IVA (MXN)
  const admIva   = Number(a.impuesto_pct) || 0;          // % de IVA indicado
  const admPresupuesto = Math.round(admTotal * (1 + admIva/100) * 100) / 100;   // Presupuesto = Total × (1+IVA%)
  const incluidasCount = prev ? prev.alertas.filter(r => r.incluir && r.insumoid).length : 0;
  const sinMatchCount  = prev ? prev.alertas.filter(r => r.sin_match).length : 0;
  const yaExisteCount  = prev ? prev.alertas.filter(r => r.ya_existe).length : 0;

  return (
    <div className="rg-app">
      <Sidebar active="import_presupuesto" onNav={onNav} user={user} onLogout={onLogout}/>
      <main className="rg-main">
        <Topbar crumbs="Catálogos / Importar Presupuesto (IA)" title="Importar Presupuesto por IA"
          actions={
            <div style={{ display:'flex', gap:8, alignItems:'center' }}>
              <select className="rg-select" value={moneda} onChange={e => { setMoneda(e.target.value); if (e.target.value==='MXN') setTc(1); }} title="Moneda del Excel">
                <option value="MXN">MXN</option>
                <option value="USD">USD</option>
                <option value="DOP">DOP</option>
              </select>
              {moneda !== 'MXN' && (
                <span style={{ display:'flex', alignItems:'center', gap:4, fontSize:12, color:'var(--rg-muted)' }}>
                  1 {moneda} =
                  <input className="rg-input rg-mono" type="number" step="0.01" min="0" value={tc}
                    onChange={e => setTc(e.target.value)} style={{ width:80 }}/>
                  MXN
                </span>
              )}
              <label style={{ display:'flex', alignItems:'center', gap:5, fontSize:12, color:'var(--rg-muted)' }} title="Muestra el paso a paso y la respuesta cruda de la IA (no guarda nada)">
                <input type="checkbox" checked={debugMode} onChange={e => setDebugMode(e.target.checked)}/> Modo diagnóstico
              </label>
              <input ref={fileRef} type="file" accept=".xlsx" style={{ display:'none' }} onChange={handleFile}/>
              <button className="rg-btn primary" onClick={() => fileRef.current && fileRef.current.click()} disabled={uploading}>
                {Icon.excel()} {uploading ? (debugMode ? 'Diagnosticando…' : 'Analizando con IA…') : (debugMode ? 'Diagnosticar (.xlsx)' : 'Subir presupuesto (.xlsx)')}
              </button>
            </div>
          }/>

        <div className="rg-content">
          {/* ── Diagnóstico paso a paso ── */}
          {debug && (
            <div className="rg-card" style={{ marginBottom:16, border:'2px solid var(--rg-flag-warn)' }}>
              <div className="rg-card-header">
                <div><h3>Diagnóstico paso a paso</h3><div className="sub">No guarda nada. Si algo falla, aquí verás la respuesta cruda de la IA (incluido el motivo del error).</div></div>
                <button className="rg-btn" onClick={() => setDebug(null)}>Cerrar</button>
              </div>
              <div style={{ padding:'4px 16px 16px', display:'grid', gap:10 }}>
                {(debug.steps || []).map((s, i) => (
                  <div key={i} style={{ border:'1px solid var(--rg-line-2)', borderRadius:8, overflow:'hidden' }}>
                    <div style={{ display:'flex', alignItems:'center', gap:8, padding:'8px 12px', background:'var(--rg-cream)', fontWeight:600, fontSize:13 }}>
                      <span style={{ width:18, height:18, borderRadius:'50%', display:'inline-flex', alignItems:'center', justifyContent:'center', color:'#fff', fontSize:11, fontWeight:700, background: s.ok ? 'var(--rg-flag-ok)' : 'var(--rg-flag-over)' }}>{s.ok ? '✓' : '!'}</span>
                      {i+1}. {s.label}
                    </div>
                    {s.detail != null && (
                      <pre className="rg-mono" style={{ margin:0, padding:'10px 12px', fontSize:11, lineHeight:1.5, whiteSpace:'pre-wrap', wordBreak:'break-word', maxHeight:360, overflow:'auto' }}>
                        {typeof s.detail === 'string' ? s.detail : JSON.stringify(s.detail, null, 2)}
                      </pre>
                    )}
                  </div>
                ))}
              </div>
            </div>
          )}

          {!prev && !debug && (
            <div className="rg-card" style={{ padding:24 }}>
              <h3 style={{ marginTop:0 }}>Importación masiva por IA</h3>
              <p style={{ color:'var(--rg-muted)', maxWidth:720, lineHeight:1.6 }}>
                Sube el Excel del presupuesto de un proyecto. La IA (Claude) lee la <strong>primera hoja</strong> para
                obtener <strong>subtotal, total y total + impuesto</strong>, y la hoja <strong>CATALOGO DE INSUMOS</strong>
                para los importes por clave. Luego revisas y ajustas en masa (fechas, umbral) y al aprobar se llenan
                <strong> ADMINISTRADOR DE PROYECTOS</strong> y las <strong>alertas de Presupuesto Global por Insumo</strong>.
                Selecciona la moneda y el tipo de cambio antes de subir.
              </p>
            </div>
          )}

          {prev && (
            <>
              {/* ── Proyecto destino + moneda ── */}
              <div className="rg-card" style={{ marginBottom:16, border:'2px solid var(--rg-accent, #c9a961)' }}>
                <div className="rg-card-header">
                  <div><h3>Proyecto destino</h3>
                    <div className="sub">Detectado por la IA: <strong>{prev.proyecto?.nombre_detectado || '—'}</strong>{' '}
                      {prev.proyecto?.id ? <>· mejor match: <strong>{prev.proyecto.nombre_match}</strong> <ScoreBadgeP score={prev.proyecto.score}/></> : <span style={{ color:'var(--rg-flag-warn)' }}>· sin match en el sistema</span>}
                    </div></div>
                  <div style={{ fontSize:12, color:'var(--rg-muted)' }}>Moneda: <strong>{prev.moneda}</strong>{prev.moneda!=='MXN' && <> · 1 {prev.moneda} = {prev.tc} MXN</>}</div>
                </div>
                <div style={{ padding:'4px 16px 16px', display:'flex', gap:24, flexWrap:'wrap', alignItems:'flex-end' }}>
                  <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:13 }}>
                    <input type="radio" checked={projMode==='existing'} onChange={() => setProjMode('existing')}/> Usar proyecto existente
                  </label>
                  <select className="rg-select" value={selProjId} disabled={projMode!=='existing'} onChange={e => setSelProjId(e.target.value)} style={{ minWidth:280 }}>
                    <option value="">— selecciona —</option>
                    {(proyectos||[]).map(p => <option key={p.id} value={p.id}>{p.clave} · {p.nombre}</option>)}
                  </select>
                  <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:13 }}>
                    <input type="radio" checked={projMode==='nuevo'} onChange={() => setProjMode('nuevo')}/> Crear proyecto nuevo
                  </label>
                  <input className="rg-input" placeholder="Nombre del proyecto nuevo" value={nuevoNombre} disabled={projMode!=='nuevo'} onChange={e => setNuevoNombre(e.target.value)} style={{ minWidth:280 }}/>
                </div>
              </div>

              {/* ── ADMINISTRADOR: subtotal / total / total+impuesto / utilidad ── */}
              <div className="rg-card" style={{ marginBottom:16 }}>
                <div className="rg-card-header"><div><h3>ADMINISTRADOR DE PROYECTOS</h3><div className="sub">Montos en <strong>MXN</strong>{prev.moneda!=='MXN' && <> (convertidos de {prev.moneda} × {prev.tc})</>}. <strong>Subtotal = Total</strong> (sin IVA) · <strong>Presupuesto = Total × (1 + IVA%)</strong>.</div></div></div>
                <div style={{ padding:'4px 16px 18px', display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(180px,1fr))', gap:14 }}>
                  <div className="rg-field"><label>Total (sin IVA)</label>
                    <input className="rg-input rg-mono" type="number" step="0.01" value={a.total} onChange={e => setAdmin('total', e.target.value)}/>
                  </div>
                  <div className="rg-field"><label>IVA %</label>
                    <input className="rg-input rg-mono" type="number" step="0.01" value={a.impuesto_pct} onChange={e => setAdmin('impuesto_pct', e.target.value)}/>
                  </div>
                  <div className="rg-field"><label>Subtotal (= Total)</label>
                    <input className="rg-input rg-mono" type="number" value={admTotal} readOnly tabIndex={-1} style={{ background:'var(--rg-cream)', color:'var(--rg-muted)' }}/>
                  </div>
                  <div className="rg-field"><label>Presupuesto (con IVA)</label>
                    <input className="rg-input rg-mono" value={moneyP(admPresupuesto)} readOnly tabIndex={-1} style={{ fontWeight:700, borderColor:'var(--rg-accent,#c9a961)', background:'var(--rg-cream)' }}/>
                  </div>
                </div>
                <div style={{ padding:'0 16px 18px' }}>
                  <div style={{ fontSize:12, fontWeight:600, color:'var(--rg-muted)', marginBottom:6 }}>
                    Proyección de Utilidad {prev.utilidad?.encontrada ? '(detectada en el Excel)' : '(no detectada — captúrala si aplica)'}
                  </div>
                  <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(160px,1fr))', gap:14 }}>
                    {[['original','Original'],['revisado','Revisado'],['proyectado','Proyectado']].map(([k,lbl]) => (
                      <div key={k} className="rg-field"><label>{lbl}</label>
                        <input className="rg-input rg-mono" type="number" step="0.01" value={prev.utilidad[k]} onChange={e => setUtil(k, e.target.value)}/>
                      </div>
                    ))}
                  </div>
                </div>
              </div>

              {/* ── Proyección de Costos (proyectado final por grupo, del Excel) ── */}
              <div className="rg-card" style={{ marginBottom:16 }}>
                <div className="rg-card-header">
                  <div><h3>Proyección de Costos · {(prev.grupos_costos||[]).length} grupos</h3>
                    <div className="sub">Proyectado Final por grupo (Movilización, Materiales, etc.), del desglose del Excel. <strong>Editables</strong>: cambia nombre/monto, agrega o quita. Al marcar la casilla de abajo se <strong>reemplaza</strong> la Proyección de Costos del proyecto con estos grupos.</div></div>
                  <button className="rg-btn" onClick={addGrupo}>+ Agregar grupo</button>
                </div>
                {(prev.grupos_costos||[]).length === 0 && (
                  <div style={{ padding:'6px 16px 12px', color:'var(--rg-flag-warn)', fontSize:12.5 }}>
                    No se detectó el desglose en el Excel. Agrégalo con “+ Agregar grupo” o revisa con Modo diagnóstico.
                  </div>
                )}
                <div style={{ padding:'2px 16px 16px' }}>
                  <table className="rg-table" style={{ width:'100%' }}>
                    <thead>
                      <tr style={{ background:'var(--rg-cream)', fontSize:10, textTransform:'uppercase', letterSpacing:'0.05em', color:'var(--rg-muted)' }}>
                        <th style={{ textAlign:'left', padding:'8px 10px' }}>Grupo</th>
                        <th style={{ textAlign:'right', padding:'8px 10px' }}>Proyectado Final (MXN)</th>
                        <th style={{ width:44 }}></th>
                      </tr>
                    </thead>
                    <tbody>
                      {(prev.grupos_costos||[]).map((g, i) => (
                        <tr key={i} style={{ borderTop:'1px solid var(--rg-line-2)' }}>
                          <td style={{ padding:'4px 10px' }}><input className="rg-input" value={g.nombre} onChange={e => setGrupo(i,'nombre', e.target.value)} style={{ height:28 }}/></td>
                          <td style={{ padding:'4px 10px', textAlign:'right' }}>
                            <input className="rg-input rg-mono" type="number" step="0.01" value={g.total_mxn} onChange={e => setGrupo(i,'total_mxn', e.target.value)} style={{ width:170, textAlign:'right', height:28 }}/>
                            {prev.moneda!=='MXN' && Number(g.total_orig)>0 && <div style={{ fontSize:9, color:'var(--rg-muted)' }}>{prev.moneda} {fmtMoney(g.total_orig)}</div>}
                          </td>
                          <td style={{ textAlign:'center' }}>
                            <button className="rg-icon-btn danger" title="Quitar grupo" onClick={() => delGrupo(i)}>{Icon.x(12)}</button>
                          </td>
                        </tr>
                      ))}
                      {(prev.grupos_costos||[]).length > 0 && (
                        <tr style={{ borderTop:'2px solid var(--rg-line-2)', fontWeight:700 }}>
                          <td style={{ padding:'6px 10px' }}>Σ Proyectado Final</td>
                          <td style={{ padding:'6px 10px', textAlign:'right' }} className="rg-mono">{moneyP((prev.grupos_costos||[]).reduce((s,g)=>s+(Number(g.total_mxn)||0),0))}</td>
                          <td></td>
                        </tr>
                      )}
                    </tbody>
                  </table>
                </div>
              </div>

              {/* ── Alertas (Presupuesto Global por Insumo) ── */}
              <div className="rg-card">
                <div className="rg-card-header">
                  <div><h3>Alertas a crear · {incluidasCount} incluidas</h3>
                    <div className="sub">
                      {sinMatchCount>0 && <span style={{ color:'var(--rg-muted)' }}>{sinMatchCount} sin match (gris, excluidas) · </span>}
                      {yaExisteCount>0 && <span style={{ color:'var(--rg-flag-warn)' }}>{yaExisteCount} ya existen (ámbar, marca “reemplazar” para sobrescribir) · </span>}
                      montos en MXN.
                    </div></div>
                  <div style={{ display:'flex', flexDirection:'column', gap:6, alignItems:'flex-start' }}>
                    <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:12.5, fontWeight:600, color:'var(--rg-flag-over)' }} title="Antes de insertar, elimina TODAS las alertas actuales del proyecto (solo si hay alertas nuevas para poner)">
                      <input type="checkbox" checked={reemplazarAlertas} onChange={e => setReemplazarAlertas(e.target.checked)}/> Reemplazar TODAS las alertas del proyecto (elimina las anteriores)
                    </label>
                    <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:12.5 }}>
                      <input type="checkbox" checked={seedProy} onChange={e => setSeedProy(e.target.checked)}/> Reemplazar Proyección de Costos con los grupos del Excel
                    </label>
                  </div>
                </div>

                {/* Controles masivos */}
                <div style={{ display:'flex', gap:12, alignItems:'flex-end', flexWrap:'wrap', padding:'0 16px 12px' }}>
                  <div className="rg-field" style={{ margin:0 }}><label>Fecha inicio (todas)</label><input className="rg-input" type="date" value={bulkFi} onChange={e => setBulkFi(e.target.value)}/></div>
                  <div className="rg-field" style={{ margin:0 }}><label>Fecha fin (todas)</label><input className="rg-input" type="date" value={bulkFf} onChange={e => setBulkFf(e.target.value)}/></div>
                  <div className="rg-field" style={{ margin:0 }}><label>Umbral % (todas)</label><input className="rg-input rg-mono" type="number" min="1" max="100" value={bulkUmb} onChange={e => setBulkUmb(e.target.value)} style={{ width:90 }}/></div>
                  <button className="rg-btn" onClick={applyBulk}>Aplicar a incluidas</button>
                </div>

                <div style={{ overflowX:'auto', maxHeight:480, overflowY:'auto' }}>
                  <table className="rg-table" style={{ width:'100%', minWidth:1000 }}>
                    <thead>
                      <tr style={{ background:'var(--rg-cream)', fontSize:10, textTransform:'uppercase', letterSpacing:'0.05em', color:'var(--rg-muted)', position:'sticky', top:0 }}>
                        <th style={{ textAlign:'center', padding:'8px 10px' }}>Incl.</th>
                        <th style={{ textAlign:'left', padding:'8px 10px' }}>Clave</th>
                        <th style={{ textAlign:'left', padding:'8px 10px' }}>Descripción</th>
                        <th style={{ textAlign:'right', padding:'8px 10px' }}>Monto (MXN)</th>
                        <th style={{ textAlign:'center', padding:'8px 10px' }}>Umbral%</th>
                        <th style={{ textAlign:'center', padding:'8px 10px' }}>Inicio</th>
                        <th style={{ textAlign:'center', padding:'8px 10px' }}>Fin</th>
                        <th style={{ textAlign:'center', padding:'8px 10px' }}>Estado</th>
                      </tr>
                    </thead>
                    <tbody>
                      {prev.alertas.map((r, i) => {
                        const bg = r.sin_match ? 'rgba(120,120,120,0.08)' : (r.ya_existe ? 'rgba(201,161,97,0.14)' : 'transparent');
                        return (
                          <tr key={i} style={{ borderTop:'1px solid var(--rg-line-2)', background:bg }}>
                            <td style={{ padding:'6px 10px', textAlign:'center' }}>
                              <input type="checkbox" checked={!!r.incluir} disabled={r.sin_match} onChange={e => setRow(i,'incluir', e.target.checked)}/>
                            </td>
                            <td style={{ padding:'6px 10px', fontSize:11 }} className="rg-mono">
                              {r.clave}
                              {r.match_por === 'descripcion' && <div style={{ fontSize:9, fontWeight:700, color: r.match_score>=75 ? 'var(--rg-flag-ok)' : 'var(--rg-flag-warn)' }} title="Clave asignada por coincidencia de descripción">≈ desc {r.match_score}%</div>}
                              {r.match_por === 'clave' && <div style={{ fontSize:9, color:'var(--rg-muted)' }}>por clave</div>}
                              {r.clave_excel && r.clave_excel !== r.clave && <div style={{ fontSize:8.5, color:'var(--rg-muted)' }}>Excel: {r.clave_excel}</div>}
                            </td>
                            <td style={{ padding:'6px 10px', fontSize:11.5, maxWidth:300 }} title={r.descripcion + (r.descripcion_excel ? '\nExcel: ' + r.descripcion_excel : '')}>
                              <div style={{ whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis', maxWidth:300 }}>{r.descripcion}</div>
                              {r.match_por === 'descripcion' && r.descripcion_excel && (r.descripcion_excel||'').toUpperCase() !== (r.descripcion||'').toUpperCase() &&
                                <div style={{ fontSize:9, color:'var(--rg-muted)', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis', maxWidth:300 }}>Excel: {r.descripcion_excel}</div>}
                            </td>
                            <td style={{ padding:'4px 10px', textAlign:'right' }}>
                              <input className="rg-input rg-mono" type="number" step="0.01" value={r.monto_mxn} onChange={e => setRow(i,'monto_mxn', e.target.value)} style={{ width:120, textAlign:'right', height:28 }}/>
                              {prev.moneda!=='MXN' && <div style={{ fontSize:9, color:'var(--rg-muted)' }}>{prev.moneda} {fmtMoney(r.total_orig)}</div>}
                            </td>
                            <td style={{ padding:'4px 10px', textAlign:'center' }}>
                              <input className="rg-input rg-mono" type="number" min="1" max="100" value={r.pct_umbral} onChange={e => setRow(i,'pct_umbral', e.target.value)} style={{ width:60, textAlign:'center', height:28 }}/>
                            </td>
                            <td style={{ padding:'4px 8px' }}><input className="rg-input" type="date" value={r.fecha_inicio||''} onChange={e => setRow(i,'fecha_inicio', e.target.value)} style={{ height:28 }}/></td>
                            <td style={{ padding:'4px 8px' }}><input className="rg-input" type="date" value={r.fecha_fin||''} onChange={e => setRow(i,'fecha_fin', e.target.value)} style={{ height:28 }}/></td>
                            <td style={{ padding:'6px 10px', textAlign:'center', fontSize:11 }}>
                              {r.sin_match
                                ? <span style={{ color:'var(--rg-muted)' }}>sin match</span>
                                : r.ya_existe
                                  ? <label style={{ display:'inline-flex', alignItems:'center', gap:4, color:'var(--rg-flag-warn)', fontWeight:600 }}>
                                      <input type="checkbox" checked={!!r.reemplazar} onChange={e => setRow(i,'reemplazar', e.target.checked)}/> reemplazar
                                    </label>
                                  : <span style={{ color:'var(--rg-flag-ok)' }}>nueva</span>}
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </div>

                <div style={{ display:'flex', justifyContent:'flex-end', gap:10, padding:14, borderTop:'1px solid var(--rg-line-2)' }}>
                  <button className="rg-btn" onClick={() => setPrev(null)} disabled={saving}>Descartar</button>
                  <button className="rg-btn primary" onClick={commit} disabled={saving}>{saving ? 'Implementando…' : `Aprobar e implementar (${incluidasCount})`}</button>
                </div>
              </div>
            </>
          )}
        </div>
      </main>
    </div>
  );
}

Object.assign(window, { ImportPresupuestoView });
