// Rumbo — Transactions · v3 · Drawer + Currency Selector + Unified Form

const { useState: useStT, useEffect: useEffT, useRef: useRfT } = React;

/* ─────────────────────────────────────────────────────────────
   Currency Selector con buscador integrado
───────────────────────────────────────────────────────────── */
const CurrencyPicker = ({ value, onChange, onClose }) => {
  const [q, setQ] = useStT('');
  const filtered = SUPPORTED_CURRENCIES.filter(c =>
    c.code.toLowerCase().includes(q.toLowerCase()) ||
    c.name.toLowerCase().includes(q.toLowerCase())
  );
  return (
    <>
      <div className="drawer-backdrop" onClick={onClose} />
      <div className="drawer" style={{ maxHeight: '65vh' }}>
        <div className="drawer-handle" />
        <div style={{ padding: '12px 20px 0' }}>
          <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--t1)', marginBottom: 12 }}>Seleccionar moneda</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, background: 'var(--surface-2)', border: '1.5px solid var(--border)', borderRadius: 'var(--r-md)', padding: '9px 14px', marginBottom: 12 }}>
            <Icon name="search" size={15} color="var(--t5)" />
            <input autoFocus type="text" placeholder="Buscar moneda..." value={q}
              onChange={e => setQ(e.target.value)}
              style={{ flex: 1, background: 'none', border: 'none', outline: 'none', color: 'var(--t1)', fontSize: 14, fontFamily: 'var(--font)' }} />
          </div>
        </div>
        <div style={{ overflowY: 'auto', maxHeight: 'calc(65vh - 110px)' }}>
          {filtered.map(c => (
            <button key={c.code}
              onClick={() => { onChange(c.code); onClose(); }}
              style={{
                width: '100%', display: 'flex', alignItems: 'center', gap: 14,
                padding: '13px 20px', background: value === c.code ? 'var(--accent-muted)' : 'none',
                border: 'none', cursor: 'pointer', transition: 'background 0.15s',
                borderBottom: '1px solid var(--border)',
              }}
              onMouseEnter={e => { if (value !== c.code) e.currentTarget.style.background='var(--surface-2)'; }}
              onMouseLeave={e => { if (value !== c.code) e.currentTarget.style.background='none'; }}>
              <span style={{ fontSize: 24 }}>{c.flag}</span>
              <div style={{ flex: 1, textAlign: 'left' }}>
                <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--t1)' }}>{c.code}</div>
                <div style={{ fontSize: 12, color: 'var(--t4)' }}>{c.name}</div>
              </div>
              <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--t3)' }}>{c.symbol}</span>
              {value === c.code && <Icon name="checkCircle" size={18} color="var(--accent)" />}
            </button>
          ))}
        </div>
      </div>
    </>
  );
};

/* ─────────────────────────────────────────────────────────────
   Mini-drawer "Nueva categoría" — para crear categorías custom
───────────────────────────────────────────────────────────── */
const NewCategoryDrawer = ({ initialType, onAdd, onClose }) => {
  // Paleta muted alineada con CATEGORIES en Data.jsx (sutil, sin saturación alta).
  const CAT_PALETTE = [
    { color:'#0F8A6A', bg:'#E8F5F0' },
    { color:'#1D4ED8', bg:'#E1E8F8' },
    { color:'#C2410C', bg:'#FBEBDD' },
    { color:'#B91C1C', bg:'#F8E5E5' },
    { color:'#6D28D9', bg:'#EBE5F7' },
    { color:'#9D174D', bg:'#F4E4ED' },
    { color:'#B45309', bg:'#F8EDD7' },
    { color:'#4F46E5', bg:'#E8E9FB' },
    { color:'#0369A1', bg:'#E0F0F8' },
    { color:'#64748B', bg:'#EDF1F5' },
  ];

  const [name, setName]           = useStT('');
  const [type, setType]           = useStT(initialType || 'expense');
  const [iconName, setIcon]       = useStT('package');
  const [palIdx, setPalIdx]       = useStT(0);
  const [showIconPicker, setShowIconPicker] = useStT(false);

  const secCard  = { background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'14px 18px', marginBottom:14 };
  const lbl      = { fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:8 };
  const rawInput = { width:'100%', background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:15, fontFamily:'var(--font)', fontWeight:500 };

  const submit = () => {
    const trimmed = name.trim();
    if (!trimmed) { window.showToast('Poné un nombre para la categoría', 'warning'); return; }
    const palette = CAT_PALETTE[palIdx];
    onAdd({ name: trimmed, type, iconName, color: palette.color, bg: palette.bg });
    onClose();
  };

  return (
    <>
      <div className="drawer-backdrop" onClick={onClose} style={{ zIndex: 700 }} />
      <div className="drawer" style={{ zIndex: 701, maxHeight: '85vh' }}>
        <div className="drawer-handle" />

        {/* Header */}
        <div style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 20px 16px', borderBottom:'1px solid var(--border)' }}>
          <button onClick={onClose} style={{ width:34,height:34,borderRadius:'var(--r-md)',background:'var(--surface-2)',border:'1px solid var(--border)',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0 }}>
            <Icon name="x" size={17} color="var(--t3)" />
          </button>
          <div>
            <div style={{ fontSize:16, fontWeight:800, color:'var(--t1)' }}>Nueva categoría</div>
            <div style={{ fontSize:12, color:'var(--t4)' }}>Crea una propia y queda guardada</div>
          </div>
        </div>

        <div style={{ padding:'18px 20px' }}>

          {/* Preview */}
          <div style={{ display:'flex', alignItems:'center', gap:12, padding:'14px 16px', marginBottom:14, background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)' }}>
            <div style={{ width:44, height:44, borderRadius:12, background:CAT_PALETTE[palIdx].bg, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
              <Icon name={iconName} size={22} color={CAT_PALETTE[palIdx].color} strokeWidth={1.7} />
            </div>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={{ fontSize:14, fontWeight:700, color:'var(--t1)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                {name.trim() || 'Tu categoría'}
              </div>
              <div style={{ fontSize:11, color:'var(--t5)' }}>{type === 'expense' ? 'Gasto' : 'Ingreso'}</div>
            </div>
          </div>

          {/* Tipo */}
          <div style={secCard}>
            <div style={lbl}>Tipo</div>
            <div style={{ display:'flex', gap:8 }}>
              {[{v:'expense',l:'Gasto'},{v:'income',l:'Ingreso'}].map(t => {
                const active = type === t.v;
                return (
                  <button key={t.v} type="button" onClick={() => setType(t.v)}
                    style={{
                      flex:1, padding:'9px 4px', borderRadius:'var(--r-md)', cursor:'pointer',
                      fontSize:13, fontWeight:700, textAlign:'center', transition:'all 0.15s',
                      background: active ? (t.v==='expense'?'var(--danger)':'var(--success)') : 'var(--surface)',
                      color:      active ? '#fff' : 'var(--t3)',
                      border:     `1.5px solid ${active ? 'transparent' : 'var(--border)'}`,
                    }}>
                    {t.l}
                  </button>
                );
              })}
            </div>
          </div>

          {/* Nombre */}
          <div style={secCard}>
            <div style={{ ...lbl, display:'flex', justifyContent:'space-between' }}>
              <span>Nombre <span style={{ color:'var(--danger)' }}>*</span></span>
              <span style={{ fontWeight:400, textTransform:'none', letterSpacing:0 }}>{name.length}/30</span>
            </div>
            <input type="text" placeholder="Ej. Mascotas, Gimnasio, Regalos…" value={name} maxLength={30}
              onChange={e => setName(e.target.value)} style={rawInput} />
          </div>

          {/* Ícono — botón que abre el IconPicker */}
          <div style={secCard}>
            <div style={lbl}>Ícono</div>
            <button type="button" onClick={() => setShowIconPicker(true)}
              style={{
                width:'100%', display:'flex', alignItems:'center', gap:12,
                padding:'10px 12px', background:'var(--surface)', border:'1.5px solid var(--border)',
                borderRadius:'var(--r-md)', cursor:'pointer', fontFamily:'var(--font)',
              }}>
              <div style={{ width:36, height:36, borderRadius:'var(--r-md)', background:CAT_PALETTE[palIdx].bg, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                <Icon name={iconName} size={18} color={CAT_PALETTE[palIdx].color} strokeWidth={1.7} />
              </div>
              <span style={{ flex:1, textAlign:'left', fontSize:13, color:'var(--t3)', fontWeight:600 }}>
                Cambiar ícono
              </span>
              <Icon name="chevronRight" size={15} color="var(--t5)" />
            </button>
          </div>

          {/* Color */}
          <div style={secCard}>
            <div style={lbl}>Color</div>
            <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
              {CAT_PALETTE.map((p, i) => (
                <button key={i} type="button" onClick={() => setPalIdx(i)}
                  style={{
                    width:32, height:32, borderRadius:'50%', background:p.color, cursor:'pointer',
                    border: palIdx===i ? `3px solid var(--t1)` : '3px solid transparent',
                    boxShadow: palIdx===i ? `0 0 0 2px var(--surface), 0 0 0 4px ${p.color}` : 'none',
                    transition:'all 0.15s',
                  }} />
              ))}
            </div>
          </div>

          {/* Botón */}
          <button onClick={submit} className="btn btn-primary btn-full" style={{ borderRadius:'var(--r-lg)', padding:15, fontSize:15 }}>
            <Icon name="checkCircle" size={18} color="#fff" /> Crear categoría
          </button>
        </div>
      </div>

      {showIconPicker && (
        <IconPicker
          value={iconName}
          onChange={setIcon}
          onClose={() => setShowIconPicker(false)}
          accentColor={CAT_PALETTE[palIdx].color}
        />
      )}
    </>
  );
};

/* ─────────────────────────────────────────────────────────────
   Drawer "Nueva Transacción" — sube desde abajo en mobile
───────────────────────────────────────────────────────────── */
const TxDrawer = ({ onClose, onAdd, onAddAnother, accounts, theme, data, onAddCategory }) => {
  const [form, setF] = useStT({
    type: 'expense',
    date: new Date().toISOString().slice(0,10),
    time: new Date().toLocaleTimeString('es-AR',{hour:'2-digit',minute:'2-digit',hour12:false}),
    category: 'Comida',
    description: '',
    amount: '',
    currency: 'ARS',
    accountId: accounts[0]?.id || '',
    notes: '',
    attachment: null,
  });
  const [showCurrencyPicker, setShowCurrencyPicker] = useStT(false);
  const [useAutoTime,        setUseAutoTime]        = useStT(true);
  const [showNewCategory,    setShowNewCategory]    = useStT(false);
  const [attachLoading,      setAttachLoading]      = useStT(false);
  const fileInputRef = useRfT(null);

  const expCats = CATEGORIES.filter(c => c.type === 'expense');
  const incCats = CATEGORIES.filter(c => c.type === 'income');
  const cats    = form.type === 'expense' ? expCats : incCats;
  const selCat  = getCategoryMeta(form.category);
  const selCur  = SUPPORTED_CURRENCIES.find(c => c.code === form.currency) || SUPPORTED_CURRENCIES[0];

  // Helpers — formato decimal es-AR
  const parseAmount = (s) => {
    let v = String(s || '').replace(/[^\d,]/g, '');
    const parts = v.split(',');
    if (parts.length > 2) v = parts[0] + ',' + parts.slice(1).join('');
    const [i, d] = v.split(',');
    return d !== undefined ? `${i},${d.slice(0,2)}` : (i || '');
  };
  const fmtAmount = (raw) => {
    if (raw === '' || raw == null) return '';
    const [i, d] = String(raw).split(',');
    const intNum = Number(i || '0');
    const intFmt = isNaN(intNum) ? '0' : intNum.toLocaleString('es-AR');
    return d !== undefined ? `${intFmt},${d}` : intFmt;
  };
  const toNumber = (raw) => {
    if (raw === '' || raw == null) return 0;
    return parseFloat(String(raw).replace(',', '.')) || 0;
  };

  // Helpers para adjuntos — comprimir imagen antes de guardar
  const compressImage = (file) => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const MAX = 1200;
        let w = img.width, h = img.height;
        if (w > MAX || h > MAX) {
          if (w > h) { h = Math.round(h * MAX / w); w = MAX; }
          else        { w = Math.round(w * MAX / h); h = MAX; }
        }
        const canvas = document.createElement('canvas');
        canvas.width = w; canvas.height = h;
        canvas.getContext('2d').drawImage(img, 0, 0, w, h);
        resolve(canvas.toDataURL('image/jpeg', 0.82));
      };
      img.onerror = reject;
      img.src = e.target.result;
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });

  const readAsDataUrl = (file) => new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = e => resolve(e.target.result);
    r.onerror = reject;
    r.readAsDataURL(file);
  });

  const handleFileChange = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setAttachLoading(true);
    try {
      const isImg = file.type.startsWith('image/');
      const isPdf = file.type === 'application/pdf';
      if (!isImg && !isPdf) {
        window.showToast('Solo se aceptan imágenes o PDF', 'warning');
        return;
      }
      if (isPdf && file.size > 3 * 1024 * 1024) {
        window.showToast('El PDF es muy pesado (máx 3MB)', 'warning');
        return;
      }
      const dataUrl = isImg ? await compressImage(file) : await readAsDataUrl(file);
      setF(f => ({ ...f, attachment: {
        name: file.name,
        type: isImg ? 'image' : 'pdf',
        mime: isImg ? 'image/jpeg' : 'application/pdf',
        dataUrl,
        size: dataUrl.length,
      }}));
    } catch (err) {
      window.showToast('No se pudo cargar el archivo', 'warning');
    } finally {
      setAttachLoading(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  };

  const removeAttachment = () => setF(f => ({ ...f, attachment: null }));

  // Contexto financiero — saldo neto del mes actual + impacto
  const ym = new Date().toISOString().slice(0,7);
  const monthTxs = (data?.transactions || []).filter(t => (t.date||'').startsWith(ym));
  const monthBalance = monthTxs.reduce((s,t) => s + (t.type==='income' ? (t.amount||0) : -(t.amount||0)), 0);
  const newAmount = toNumber(form.amount);
  const delta = form.type==='income' ? newAmount : -newAmount;
  const monthBalanceFinal = monthBalance + delta;

  // Helpers para mostrar fecha/hora
  const formatDate = (d) => d.toLocaleDateString('es-AR', { weekday:'short', day:'numeric', month:'long' });
  const formatTime = (d) => d.toLocaleTimeString('es-AR', { hour:'2-digit', minute:'2-digit', hour12:false });

  // Handlers de ajuste manual
  const handleAjustar = () => {
    const now = new Date();
    setF(f => ({ ...f,
      date: now.toISOString().slice(0,10),
      time: formatTime(now),
    }));
    setUseAutoTime(false);
  };
  const handleVolverAhora = () => setUseAutoTime(true);

  const submit = (addAnother = false) => {
    if (!form.amount || !form.description) {
      window.showToast('Completá monto y descripción', 'warning'); return;
    }
    const now = new Date();
    const finalDate = useAutoTime ? now.toISOString().slice(0,10) : form.date;
    const finalTime = useAutoTime ? formatTime(now)              : form.time;
    const tx = { ...form, date: finalDate, time: finalTime, amount: toNumber(form.amount), id: 't' + Date.now() };
    if (addAnother) {
      onAddAnother(tx);
      setF(f => ({ ...f, description: '', amount: '', notes: '', attachment: null, date: new Date().toISOString().slice(0,10) }));
      setUseAutoTime(true);
      window.showToast('Guardado ✓ Podés agregar otro', 'success');
    } else {
      onAdd(tx);
      onClose();
    }
  };

  const Row = ({ label, required, children }) => (
    <div style={{ marginBottom: 14 }}>
      <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--t4)', marginBottom: 7, display: 'flex', gap: 4 }}>
        {label} {required && <span style={{ color: 'var(--danger)' }}>*</span>}
      </div>
      {children}
    </div>
  );

  return (
    <>
      <div className="drawer-backdrop" onClick={onClose} />
      <div className="drawer">
        <div className="drawer-handle" />

        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 20px 16px', borderBottom: '1px solid var(--border)' }}>
          <button onClick={onClose} style={{ width: 34, height: 34, borderRadius: 'var(--r-md)', background: 'var(--surface-2)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <Icon name="x" size={17} color="var(--t3)" />
          </button>
          <div>
            <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--t1)' }}>Nueva transacción</div>
            <div style={{ fontSize: 12, color: 'var(--t4)' }}>Registra un ingreso o gasto</div>
          </div>
        </div>

        <div style={{ padding: '18px 20px' }}>

          {/* Tira de contexto financiero */}
          <div style={{
            display:'flex', alignItems:'center', justifyContent:'space-between', gap:12,
            padding:'10px 14px', marginBottom:14,
            background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)',
          }}>
            <div style={{ display:'flex', alignItems:'center', gap:8 }}>
              <div style={{ width:28, height:28, borderRadius:'var(--r-md)', background:'var(--accent-muted)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                <Icon name="chartBar" size={14} color="var(--accent)" />
              </div>
              <div style={{ display:'flex', flexDirection:'column' }}>
                <span style={{ fontSize:10, color:'var(--t5)', fontWeight:700, textTransform:'uppercase', letterSpacing:'0.4px' }}>Saldo del mes</span>
                <span style={{ fontSize:13, color:'var(--t2)', fontWeight:700, fontVariantNumeric:'tabular-nums' }}>
                  {newAmount > 0
                    ? <>{fmtFull(monthBalance)} → <span style={{ color: monthBalanceFinal >= 0 ? 'var(--success)' : 'var(--danger)' }}>{fmtFull(monthBalanceFinal)}</span></>
                    : fmtFull(monthBalance)
                  }
                </span>
              </div>
            </div>
            {newAmount > 0 && (
              <div style={{ fontSize:12, fontWeight:800, color: form.type==='income' ? 'var(--success)' : 'var(--danger)', fontVariantNumeric:'tabular-nums' }}>
                {form.type==='income' ? '+' : '−'}{fmtFull(newAmount)}
              </div>
            )}
          </div>

          {/* Tipo Gasto / Ingreso */}
          <div className="pill-tabs" style={{ marginBottom: 18 }}>
            <button className={`pill-tab${form.type==='expense'?' active':''}`}
              style={form.type==='expense' ? { background:'var(--danger)', color:'#fff', boxShadow:'0 2px 8px rgba(220,38,38,0.25)' } : {}}
              onClick={() => setF(f => ({ ...f, type:'expense', category: expCats[0]?.name||'' }))}>
              <Icon name="arrowDown" size={13} color={form.type==='expense'?'#fff':'var(--t4)'} strokeWidth={2.5} /> Gasto
            </button>
            <button className={`pill-tab${form.type==='income'?' active':''}`}
              style={form.type==='income' ? { background:'var(--success)', color:'#fff', boxShadow:'0 2px 8px rgba(5,150,105,0.25)' } : {}}
              onClick={() => setF(f => ({ ...f, type:'income', category: incCats[0]?.name||'' }))}>
              <Icon name="arrowUp" size={13} color={form.type==='income'?'#fff':'var(--t4)'} strokeWidth={2.5} /> Ingreso
            </button>
          </div>

          {/* Monto + moneda */}
          <div style={{ background: 'var(--surface-2)', border: '1.5px solid var(--border)', borderRadius: 'var(--r-lg)', padding: '16px 18px', marginBottom: 14 }}>
            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--t5)', textTransform: 'uppercase', letterSpacing: '0.4px', marginBottom: 10 }}>
              Monto <span style={{ color: 'var(--danger)' }}>*</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <span style={{ fontSize: 22, fontWeight: 900, color: form.type==='expense'?'var(--danger)':'var(--success)', lineHeight: 1 }}>
                {form.type==='expense'?'–':'+'}
              </span>
              <input type="text" inputMode="decimal" placeholder="0" value={fmtAmount(form.amount)}
                onChange={e => setF(f => ({ ...f, amount: parseAmount(e.target.value) }))}
                style={{ flex:1, background:'none', border:'none', outline:'none', fontSize:30, fontWeight:900, color:'var(--t1)', fontFamily:'var(--font)', fontVariantNumeric:'tabular-nums' }} />
              {/* Selector de moneda */}
              <button onClick={() => setShowCurrencyPicker(true)}
                style={{ display:'flex', alignItems:'center', gap:6, background:'var(--surface)', border:'1.5px solid var(--border)', borderRadius:'var(--r-md)', padding:'7px 10px', color:'var(--t2)', fontWeight:700, fontSize:13, flexShrink:0 }}>
                <span style={{ fontSize:18 }}>{selCur.flag}</span>
                <span>{selCur.code}</span>
                <Icon name="chevronDown" size={13} color="var(--t4)" />
              </button>
            </div>
          </div>

          {/* Descripción */}
          <div style={{ background: 'var(--surface-2)', border: '1.5px solid var(--border)', borderRadius: 'var(--r-lg)', padding: '14px 18px', marginBottom: 14 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
              <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--t5)', textTransform: 'uppercase', letterSpacing: '0.4px' }}>
                Descripción <span style={{ color: 'var(--danger)' }}>*</span>
              </div>
              <span style={{ fontSize: 11, color: 'var(--t5)' }}>{(form.description||'').length}/100</span>
            </div>
            <input type="text" placeholder="Ej. Supermercado, Salario, Gasolina…"
              value={form.description} maxLength={100}
              onChange={e => setF(f => ({ ...f, description: e.target.value }))}
              style={{ width:'100%', background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:15, fontFamily:'var(--font)', fontWeight:500 }} />
          </div>

          {/* Fecha + Hora — barra compacta con modo "Ahora" o ajuste manual */}
          {useAutoTime ? (
            <div style={{
              display:'flex', alignItems:'center', gap:10, padding:'12px 16px', marginBottom:14,
              background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)',
            }}>
              <div style={{ width:34, height:34, borderRadius:'var(--r-md)', background:'var(--accent-muted)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                <Icon name="clock" size={16} color="var(--accent)" />
              </div>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:13, fontWeight:700, color:'var(--t1)', display:'flex', alignItems:'center', gap:6 }}>
                  <span style={{ background:'var(--accent)', color:'#fff', fontSize:10, fontWeight:800, padding:'2px 7px', borderRadius:'var(--r-full)', textTransform:'uppercase', letterSpacing:'0.5px' }}>Ahora</span>
                  <span style={{ fontVariantNumeric:'tabular-nums', color:'var(--t3)' }}>
                    {formatDate(new Date())}, {formatTime(new Date())}
                  </span>
                </div>
              </div>
              <button type="button" onClick={handleAjustar}
                style={{
                  background:'none', border:'1.5px solid var(--border)', borderRadius:'var(--r-md)',
                  padding:'7px 12px', cursor:'pointer', color:'var(--t3)', fontSize:12, fontWeight:700,
                  fontFamily:'var(--font)', flexShrink:0, whiteSpace:'nowrap',
                }}>
                Cambiar
              </button>
            </div>
          ) : (
            <>
              <div style={{
                display:'flex', alignItems:'center', gap:10, padding:'10px 14px', marginBottom:12,
                background:'var(--accent-muted)', border:'1.5px solid transparent', borderRadius:'var(--r-lg)',
              }}>
                <Icon name="edit" size={14} color="var(--accent)" />
                <span style={{ flex:1, fontSize:12, color:'var(--accent-text)', fontWeight:600 }}>
                  Cargando con fecha/hora manuales
                </span>
                <button type="button" onClick={handleVolverAhora}
                  style={{
                    background:'var(--accent)', border:'none', borderRadius:'var(--r-md)',
                    padding:'6px 12px', cursor:'pointer', color:'#fff', fontSize:12, fontWeight:700,
                    fontFamily:'var(--font)', flexShrink:0, whiteSpace:'nowrap',
                  }}>
                  Volver a "Ahora"
                </button>
              </div>

              {/* Fecha — DatePicker custom */}
              <DatePicker
                label="Fecha"
                value={form.date}
                onChange={v => setF(f => ({ ...f, date: v }))}
                required
              />

              {/* Hora */}
              <div style={{ background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'14px 18px', marginBottom:14 }}>
                <div style={{ fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:8 }}>Hora</div>
                <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                  <div style={{ width:34, height:34, borderRadius:'var(--r-md)', background:'var(--surface)', border:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                    <Icon name="clock" size={16} color="var(--t4)" />
                  </div>
                  <input type="time" value={form.time}
                    onChange={e => setF(f => ({ ...f, time: e.target.value }))}
                    style={{
                      flex:1, background:'var(--surface)', border:'1.5px solid var(--border)',
                      borderRadius:'var(--r-md)', padding:'8px 12px', outline:'none', cursor:'pointer',
                      color:'var(--t1)', fontSize:15, fontFamily:'var(--font)', fontWeight:700, letterSpacing:'0.5px', minWidth:0,
                    }} />
                </div>
              </div>
            </>
          )}

          {/* Categoría */}
          <div style={{ background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'13px 16px', marginBottom:14 }}>
            <div style={{ fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:2 }}>Categoría</div>
            <div style={{ fontSize:11, fontWeight:400, color:'var(--t5)', marginBottom:10, fontStyle:'italic' }}>
              {form.type==='expense' ? '¿En qué fue el gasto?' : '¿De dónde vino?'}
            </div>
            <div style={{ display:'flex', alignItems:'center', gap:12 }}>
              <CategoryIcon category={form.category} size="sm" />
              <select value={form.category} onChange={e => setF(f => ({ ...f, category: e.target.value }))}
                style={{ flex:1, background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:14, fontWeight:600, fontFamily:'var(--font)', cursor:'pointer' }}>
                {cats.map(c => <option key={c.name} value={c.name}>{c.name}</option>)}
              </select>
              <Icon name="chevronDown" size={15} color="var(--t5)" />
              <button type="button" onClick={() => setShowNewCategory(true)}
                style={{
                  display:'flex', alignItems:'center', gap:4, padding:'6px 10px',
                  background:'var(--accent-muted)', border:'1.5px solid transparent', borderRadius:'var(--r-md)',
                  color:'var(--accent)', fontSize:12, fontWeight:700, cursor:'pointer',
                  fontFamily:'var(--font)', whiteSpace:'nowrap', flexShrink:0,
                }} title="Crear categoría nueva">
                <Icon name="plus" size={13} color="var(--accent)" strokeWidth={2.5} />
                Nueva
              </button>
            </div>
          </div>

          {/* Cuenta */}
          <div style={{ background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'13px 16px', marginBottom:14 }}>
            <div style={{ fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:2 }}>Cuenta</div>
            <div style={{ fontSize:11, fontWeight:400, color:'var(--t5)', marginBottom:8, fontStyle:'italic' }}>
              {form.type==='expense' ? '¿Con qué pagaste?' : '¿Dónde llegó el dinero?'}
            </div>
            <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
              {accounts.map(a => (
                <label key={a.id} style={{ display:'flex', alignItems:'center', gap:10, cursor:'pointer' }}>
                  <div style={{ width:32, height:32, borderRadius:'var(--r-md)', background:'var(--surface-2)', border:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                    <Icon name={a.type==='cash'?'banknote':a.type==='digital'?'smartphone':a.type==='investment'?'trending':'landmark'} size={15} color={a.color} strokeWidth={1.7} />
                  </div>
                  <div style={{ flex:1 }}>
                    <div style={{ fontSize:13, fontWeight:600, color:'var(--t1)' }}>{a.name}</div>
                    <div style={{ fontSize:11, color:'var(--t4)' }}>Saldo: {fmtFull(a.balance, a.currency)}</div>
                  </div>
                  <input type="radio" name="txAccount" value={a.id} checked={form.accountId===a.id}
                    onChange={() => setF(f => ({ ...f, accountId: a.id }))}
                    style={{ accentColor:'var(--accent)', width:18, height:18 }} />
                </label>
              ))}
            </div>
          </div>

          {/* Notas */}
          <div style={{ background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'13px 16px', marginBottom:20 }}>
            <div style={{ display:'flex', justifyContent:'space-between', marginBottom:8 }}>
              <div style={{ fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px' }}>Notas (opcional)</div>
              <span style={{ fontSize:11, color:'var(--t5)' }}>{(form.notes||'').length}/200</span>
            </div>
            <textarea placeholder="Agrega un detalle…" value={form.notes} maxLength={200} rows={2}
              onChange={e => setF(f => ({ ...f, notes: e.target.value }))}
              style={{ width:'100%', background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:14, fontFamily:'var(--font)', resize:'none', lineHeight:1.5 }} />
          </div>

          {/* Comprobante (opcional) */}
          <div style={{ background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-lg)', padding:'13px 16px', marginBottom:20 }}>
            <div style={{ fontSize:11, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:2 }}>Comprobante (opcional)</div>
            <div style={{ fontSize:11, fontWeight:400, color:'var(--t5)', marginBottom:10, fontStyle:'italic' }}>
              Foto del ticket o PDF de la factura
            </div>

            <input ref={fileInputRef} type="file" accept="image/*,application/pdf" capture="environment"
              onChange={handleFileChange} style={{ display:'none' }} />

            {!form.attachment ? (
              <button type="button" onClick={() => fileInputRef.current?.click()} disabled={attachLoading}
                style={{
                  width:'100%', display:'flex', alignItems:'center', justifyContent:'center', gap:8,
                  padding:'12px', background:'var(--surface)', border:'1.5px dashed var(--border)',
                  borderRadius:'var(--r-md)', cursor: attachLoading ? 'wait' : 'pointer',
                  color:'var(--t3)', fontSize:13, fontWeight:600, fontFamily:'var(--font)',
                  opacity: attachLoading ? 0.6 : 1, transition:'all 0.15s',
                }}>
                <Icon name="paperclip" size={15} color="var(--t3)" />
                {attachLoading ? 'Procesando…' : 'Adjuntar foto o PDF'}
              </button>
            ) : (
              <div style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 12px', background:'var(--surface)', border:'1.5px solid var(--border)', borderRadius:'var(--r-md)' }}>
                {form.attachment.type === 'image' ? (
                  <img src={form.attachment.dataUrl} alt=""
                    style={{ width:48, height:48, borderRadius:'var(--r-sm)', objectFit:'cover', flexShrink:0, border:'1px solid var(--border)' }} />
                ) : (
                  <div style={{ width:48, height:48, borderRadius:'var(--r-sm)', background:'var(--accent-muted)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                    <Icon name="fileText" size={22} color="var(--accent)" />
                  </div>
                )}
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:13, fontWeight:700, color:'var(--t1)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                    {form.attachment.name}
                  </div>
                  <div style={{ fontSize:11, color:'var(--t5)', marginTop:2 }}>
                    {form.attachment.type === 'image' ? 'Imagen' : 'PDF'} · {Math.round(form.attachment.size/1024)} KB
                  </div>
                </div>
                <button type="button" onClick={removeAttachment}
                  style={{ background:'none', border:'none', padding:6, cursor:'pointer', flexShrink:0 }}
                  title="Quitar comprobante">
                  <Icon name="trash" size={15} color="var(--danger)" />
                </button>
              </div>
            )}
          </div>

          {/* Acciones */}
          <button onClick={() => submit(false)} className="btn btn-primary btn-full" style={{ marginBottom:10, borderRadius:'var(--r-lg)', padding:15, fontSize:15 }}>
            <Icon name="checkCircle" size={18} color="#fff" /> Guardar transacción
          </button>
          <button onClick={() => submit(true)} className="btn btn-ghost btn-full" style={{ fontSize:13 }}>
            Guardar y agregar otra
          </button>
        </div>
      </div>

      {/* Currency picker nested */}
      {showCurrencyPicker && (
        <CurrencyPicker
          value={form.currency}
          onChange={c => setF(f => ({ ...f, currency: c }))}
          onClose={() => setShowCurrencyPicker(false)}
        />
      )}

      {/* Mini-drawer crear categoría custom */}
      {showNewCategory && (
        <NewCategoryDrawer
          initialType={form.type}
          onAdd={(newCat) => {
            if (onAddCategory) onAddCategory(newCat);
            if (newCat.type === form.type) {
              setF(f => ({ ...f, category: newCat.name }));
            }
            window.showToast(`Categoría "${newCat.name}" creada`, 'success');
          }}
          onClose={() => setShowNewCategory(false)}
        />
      )}
    </>
  );
};

/* ─────────────────────────────────────────────────────────────
   Visor de comprobante adjunto — overlay full-screen
───────────────────────────────────────────────────────────── */
const AttachmentViewer = ({ attachment, onClose }) => {
  if (!attachment) return null;
  const downloadFile = () => {
    const a = document.createElement('a');
    a.href = attachment.dataUrl;
    a.download = attachment.name || (attachment.type === 'pdf' ? 'comprobante.pdf' : 'comprobante.jpg');
    a.click();
  };
  return (
    <div style={{
      position:'fixed', inset:0, zIndex:900, background:'rgba(0,0,0,0.85)',
      display:'flex', flexDirection:'column',
    }} onClick={onClose}>
      <div style={{
        display:'flex', alignItems:'center', gap:10, padding:'14px 18px',
        background:'rgba(0,0,0,0.5)', backdropFilter:'blur(8px)',
      }} onClick={e => e.stopPropagation()}>
        <button onClick={onClose}
          style={{ width:36, height:36, borderRadius:'var(--r-md)', background:'rgba(255,255,255,0.1)', border:'1px solid rgba(255,255,255,0.2)', display:'flex', alignItems:'center', justifyContent:'center', cursor:'pointer', flexShrink:0 }}>
          <Icon name="x" size={17} color="#fff" />
        </button>
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontSize:14, fontWeight:700, color:'#fff', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
            {attachment.name || 'Comprobante'}
          </div>
          <div style={{ fontSize:11, color:'rgba(255,255,255,0.6)' }}>
            {attachment.type === 'image' ? 'Imagen' : 'PDF'} · {Math.round((attachment.size||0)/1024)} KB
          </div>
        </div>
        <button onClick={downloadFile}
          style={{ width:36, height:36, borderRadius:'var(--r-md)', background:'rgba(255,255,255,0.1)', border:'1px solid rgba(255,255,255,0.2)', display:'flex', alignItems:'center', justifyContent:'center', cursor:'pointer', flexShrink:0 }}
          title="Descargar">
          <Icon name="download" size={16} color="#fff" />
        </button>
      </div>
      <div style={{ flex:1, overflow:'auto', display:'flex', alignItems:'center', justifyContent:'center', padding:16 }}
        onClick={e => e.stopPropagation()}>
        {attachment.type === 'image' ? (
          <img src={attachment.dataUrl} alt={attachment.name||'comprobante'}
            style={{ maxWidth:'100%', maxHeight:'100%', objectFit:'contain', borderRadius:'var(--r-md)', boxShadow:'0 8px 32px rgba(0,0,0,0.5)' }} />
        ) : (
          <iframe src={attachment.dataUrl} title={attachment.name||'PDF'}
            style={{ width:'100%', height:'100%', border:'none', borderRadius:'var(--r-md)', background:'#fff' }} />
        )}
      </div>
    </div>
  );
};

/* ─────────────────────────────────────────────────────────────
   Pantalla de Transacciones
───────────────────────────────────────────────────────────── */
const Transactions = ({ data, setData, theme, toggleTheme, setScreen, selectedMonth, setSelectedMonth, openNewTx }) => {
  const [filterTab,  setFilterTab]  = useStT('all');
  const [filterCat,  setFilterCat]  = useStT('all');
  const [showSearch, setShowSearch] = useStT(false);
  const [search,     setSearch]     = useStT('');
  const [viewAttach, setViewAttach] = useStT(null);
  const [scopeAll,   setScopeAll]   = useStT(false); // false = solo mes seleccionado, true = todo
  const [showAllCats, setShowAllCats] = useStT(false); // drawer "+ Más" categorías
  const [catSearch,   setCatSearch]   = useStT('');
  const searchRef = useRfT(null);

  const { transactions, accounts } = data;
  const curMonth = selectedMonth || `${new Date().getFullYear()}-${String(new Date().getMonth()+1).padStart(2,'0')}`;

  useEffT(() => { if (showSearch && searchRef.current) searchRef.current.focus(); }, [showSearch]);

  const handleDelete = id => {
    const updated = { ...data, transactions: data.transactions.filter(t => t.id !== id) };
    setData(updated); saveData(updated);
    window.showToast('Movimiento eliminado');
  };
  const exportCSV = () => {
    const rows = [['Fecha','Tipo','Categoría','Descripción','Monto','Moneda'],
      ...filtered.map(t => [t.date, t.type, t.category, t.description, t.amount, t.currency||'ARS'])];
    const blob = new Blob([rows.map(r=>r.join(',')).join('\n')], { type:'text/csv' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob); a.download = 'rumbo_movimientos.csv'; a.click();
    window.showToast('CSV exportado', 'success');
  };

  const filtered = [...transactions]
    .sort((a,b) => b.date.localeCompare(a.date))
    .filter(t => scopeAll || (t.date||'').startsWith(curMonth))
    .filter(t => filterTab === 'all' || t.type === filterTab)
    .filter(t => filterCat === 'all' || t.category === filterCat)
    .filter(t => !search || t.description.toLowerCase().includes(search.toLowerCase()) || t.category.toLowerCase().includes(search.toLowerCase()));

  // Categorías existentes (de transactions reales)
  const allCatsRaw = [...new Set(transactions.map(t => t.category))];

  // Sincronización tipo→categoría: si filtraste por gastos, no muestres categorías de ingresos.
  const catTypeOf = (cat) => getCategoryMeta(cat).type;
  const catsForTab = filterTab === 'all'
    ? allCatsRaw
    : allCatsRaw.filter(c => catTypeOf(c) === filterTab);

  // Si la categoría seleccionada ya no aplica al tipo nuevo, resetearla a 'all'
  useEffT(() => {
    if (filterCat !== 'all' && filterTab !== 'all' && catTypeOf(filterCat) !== filterTab) {
      setFilterCat('all');
    }
  }, [filterTab]);

  // Top N categorías por frecuencia de uso (en todo el historial, no solo el mes)
  const usageMap = {};
  transactions.forEach(t => { usageMap[t.category] = (usageMap[t.category] || 0) + 1; });
  const sortedByUse = [...catsForTab].sort((a,b) => (usageMap[b]||0) - (usageMap[a]||0));
  const TOP_N = 5;
  const topCats = sortedByUse.slice(0, TOP_N);
  const restCats = sortedByUse.slice(TOP_N);
  // Si la cat seleccionada está en "rest", la promovemos a visible
  const visibleCats = filterCat !== 'all' && !topCats.includes(filterCat) && catsForTab.includes(filterCat)
    ? [filterCat, ...topCats.slice(0, TOP_N-1)]
    : topCats;

  const totalInc = filtered.filter(t=>t.type==='income').reduce((s,t)=>s+t.amount,0);
  const totalExp = filtered.filter(t=>t.type==='expense').reduce((s,t)=>s+t.amount,0);
  const balance  = totalInc - totalExp;

  // Agrupar por fecha
  const groups = {};
  filtered.forEach(t => { if (!groups[t.date]) groups[t.date]=[]; groups[t.date].push(t); });
  const groupEntries = Object.entries(groups).sort((a,b)=>b[0].localeCompare(a[0]));

  return (
    <div style={{ background:'var(--bg)', minHeight:'100%' }}>

      {/* Header */}
      <div className="screen-header screen-header--compact">
        <div>
          <h1 className="screen-title">Transacciones</h1>
          <p className="screen-sub">Historial de ingresos y gastos</p>
        </div>
        <div style={{ display:'flex', gap:8, marginTop:2, flexWrap:'wrap', justifyContent:'flex-end' }}>
          {setSelectedMonth && !scopeAll && (
            <MonthSwitcher value={curMonth} onChange={setSelectedMonth} transactions={transactions} compact />
          )}
          <button onClick={() => setScopeAll(s => !s)}
            title={scopeAll ? 'Filtrar por mes seleccionado' : 'Ver historial completo'}
            style={{ height:36, padding:'0 12px', borderRadius:'var(--r-md)', background: scopeAll?'var(--accent)':'var(--surface)', border:`1px solid ${scopeAll?'var(--accent)':'var(--border)'}`, color: scopeAll?'#fff':'var(--t3)', display:'flex', alignItems:'center', gap:6, boxShadow:'var(--sh-xs)', fontSize:12, fontWeight:700, cursor:'pointer' }}>
            <Icon name="list" size={14} color={scopeAll?'#fff':'var(--t3)'} />
            {scopeAll ? 'Todo' : 'Mes'}
          </button>
          <button onClick={() => setShowSearch(s=>!s)} style={{ width:36, height:36, borderRadius:'var(--r-md)', background:'var(--surface)', border:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'center', boxShadow:'var(--sh-xs)' }}>
            <Icon name="search" size={16} color="var(--t3)" />
          </button>
          <button onClick={exportCSV} style={{ width:36, height:36, borderRadius:'var(--r-md)', background:'var(--surface)', border:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'center', boxShadow:'var(--sh-xs)' }}>
            <Icon name="download" size={16} color="var(--t3)" />
          </button>
          <button className="theme-toggle" onClick={toggleTheme}>
            <Icon name={theme==='dark'?'sun':'moon'} size={15} color="var(--t3)" />
          </button>
        </div>
      </div>

      {/* Buscador */}
      {showSearch && (
        <div style={{ padding:'10px 20px 0' }}>
          <div style={{ display:'flex', alignItems:'center', gap:8, background:'var(--surface)', border:'1.5px solid var(--accent)', borderRadius:'var(--r-md)', padding:'10px 14px', boxShadow:'0 0 0 3px var(--accent-muted)' }}>
            <Icon name="search" size={15} color="var(--t5)" />
            <input ref={searchRef} type="text" placeholder="Buscar movimientos…" value={search}
              onChange={e => setSearch(e.target.value)}
              style={{ flex:1, background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:14, fontFamily:'var(--font)' }} />
            {search && <button onClick={() => setSearch('')} style={{ background:'none', border:'none', color:'var(--t5)', fontSize:18, lineHeight:1 }}>×</button>}
          </div>
        </div>
      )}

      {/* Bloque 1: Filtro por TIPO (tabs) */}
      <div style={{ padding:'16px 20px 0' }}>
        <div style={{ fontSize:10, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.5px', marginBottom:8 }}>Filtrar por tipo</div>
        <div className="pill-tabs">
          {[['all','Todas'],['expense','↓ Gastos'],['income','↑ Ingresos']].map(([v,l]) => (
            <button key={v} className={`pill-tab${filterTab===v?' active':''}`}
              style={filterTab===v&&v==='expense'?{background:'var(--danger)',color:'#fff'}:
                     filterTab===v&&v==='income' ?{background:'var(--success)',color:'#fff'}:{}}
              onClick={() => setFilterTab(v)}>{l}</button>
          ))}
        </div>
      </div>

      {/* Bloque 2: Filtro por CATEGORÍA — top 5 más usadas + "Más" para el resto.
          Sincronizado con el tipo: si elegiste Gastos, solo muestra cats de gastos. */}
      <div style={{ padding:'18px 20px 0' }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:8 }}>
          <div style={{ fontSize:10, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.5px' }}>Filtrar por categoría</div>
          {filterCat !== 'all' && (
            <button onClick={() => setFilterCat('all')}
              style={{ background:'none', border:'none', cursor:'pointer', color:'var(--accent)', fontSize:11, fontWeight:700, padding:0 }}>
              Limpiar
            </button>
          )}
        </div>
        <div style={{ display:'flex', flexWrap:'wrap', gap:7 }}>
          {/* Chip "Todas" siempre primero */}
          <button onClick={() => setFilterCat('all')}
            style={{
              padding:'6px 12px', borderRadius:'var(--r-full)', fontSize:12, fontWeight:600,
              background: filterCat==='all'?'var(--accent)':'var(--surface)',
              color: filterCat==='all'?'#fff':'var(--t4)',
              border: `1px solid ${filterCat==='all'?'transparent':'var(--border)'}`,
              boxShadow: filterCat==='all'?'none':'var(--sh-xs)',
              transition:'all 0.15s', whiteSpace:'nowrap', cursor:'pointer',
            }}>
            Todas
          </button>
          {/* Top N visibles */}
          {visibleCats.map(c => (
            <button key={c} onClick={() => setFilterCat(c)}
              style={{
                padding:'6px 12px', borderRadius:'var(--r-full)', fontSize:12, fontWeight:600,
                background: filterCat===c?getCategoryColor(c):'var(--surface)',
                color: filterCat===c?'#fff':'var(--t4)',
                border: `1px solid ${filterCat===c?'transparent':'var(--border)'}`,
                boxShadow: filterCat===c?'none':'var(--sh-xs)',
                transition:'all 0.15s', whiteSpace:'nowrap',
                display:'inline-flex', alignItems:'center', gap:5, cursor:'pointer',
              }}>
              <Icon name={getCategoryIconName(c)} size={12} color={filterCat===c?'#fff':getCategoryColor(c)} strokeWidth={2} /> {c}
            </button>
          ))}
          {/* "+ Más" — solo si hay categorías que no entraron en el top */}
          {restCats.filter(c => !visibleCats.includes(c)).length > 0 && (
            <button onClick={() => { setCatSearch(''); setShowAllCats(true); }}
              style={{
                padding:'6px 12px', borderRadius:'var(--r-full)', fontSize:12, fontWeight:700,
                background:'var(--surface-2)', color:'var(--t3)',
                border:'1px dashed var(--border)', cursor:'pointer',
                display:'inline-flex', alignItems:'center', gap:5,
              }}>
              <Icon name="plus" size={12} color="var(--t3)" strokeWidth={2.5} />
              Más ({restCats.filter(c => !visibleCats.includes(c)).length})
            </button>
          )}
        </div>
      </div>

      {/* Bloque 3: Totales del filtro actual — separado con divider sutil */}
      <div style={{ padding:'20px 20px 0' }}>
        <div style={{ fontSize:10, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.5px', marginBottom:8 }}>Totales del filtro</div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:9 }} className="stats-grid-3">
          {[
            { l:'Gasto total',   v:`–${fmtFull(totalExp)}`, c:'var(--danger)'  },
            { l:'Ingreso total', v:`+${fmtFull(totalInc)}`, c:'var(--success)' },
            { l:'Saldo neto',    v:fmtFull(balance),        c:balance>=0?'var(--accent)':'var(--danger)' },
          ].map(({l,v,c}) => (
            <div key={l} style={{ background:'var(--surface)', border:'1px solid var(--border)', borderRadius:'var(--r-lg)', padding:'11px 13px', boxShadow:'var(--sh-xs)' }}>
              <div style={{ fontSize:10, fontWeight:700, color:'var(--t5)', textTransform:'uppercase', letterSpacing:'0.4px', marginBottom:4 }}>{l}</div>
              <div style={{ fontSize:15, fontWeight:800, color:c, fontVariantNumeric:'tabular-nums' }}>{v}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Lista agrupada — con separación visual respecto al bloque de totales */}
      <div style={{ padding:'24px 20px 100px' }}>
        {filtered.length === 0 && (
          <div style={{ textAlign:'center', padding:'60px 0', color:'var(--t5)' }}>
            <Icon name="receipt" size={36} color="var(--t6)" />
            <div style={{ marginTop:10, fontSize:14 }}>Sin movimientos</div>
          </div>
        )}

        {groupEntries.map(([date, txs]) => {
          const dayTotal = txs.reduce((s,t)=>t.type==='expense'?s-t.amount:s+t.amount, 0);
          return (
            <div key={date} style={{ marginBottom:14 }}>
              <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'6px 4px', marginBottom:5 }}>
                <span style={{ fontSize:13, fontWeight:700, color:'var(--t2)' }}>{fmtDateLabel(date)}</span>
                {/* Subtotal del día — atenuado para no robar primer plano. Respeta colores: rojo si gasto neto, verde si ingreso neto. */}
                <span style={{ fontSize:11, fontWeight:600, color: dayTotal>=0?'var(--success)':'var(--danger)', opacity:0.65, fontVariantNumeric:'tabular-nums' }}>
                  {dayTotal>=0?'+':''}{fmtFull(dayTotal)}
                </span>
              </div>
              <div style={{ background:'var(--surface)', border:'1px solid var(--border)', borderRadius:'var(--r-lg)', overflow:'hidden', boxShadow:'var(--sh-xs)' }}>
                {txs.map((t, i) => {
                  const meta = getCategoryMeta(t.category);
                  return (
                    <div key={t.id}
                      style={{ display:'flex', alignItems:'center', gap:12, padding:'12px 15px', borderBottom: i<txs.length-1?'1px solid var(--border)':'none', transition:'background 0.15s' }}
                      onMouseEnter={e => e.currentTarget.style.background='var(--surface-2)'}
                      onMouseLeave={e => e.currentTarget.style.background=''}>
                      <CategoryIcon category={t.category} size="md" />
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ fontSize:14, fontWeight:600, color:'var(--t1)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{t.description}</div>
                        <div style={{ display:'flex', alignItems:'center', gap:6, marginTop:3 }}>
                          <span style={{ fontSize:11, color:'var(--t5)' }}>{accounts.find(a=>a.id===t.accountId)?.name||''}</span>
                          <span style={{ fontSize:11, color:meta.color, background:meta.bg, borderRadius:'var(--r-full)', padding:'1px 7px', fontWeight:700 }}>{t.category}</span>
                          {t.currency && t.currency!=='ARS' && (
                            <span className="badge badge-blue">{t.currency}</span>
                          )}
                          {t.attachment && (
                            <button onClick={(e) => { e.stopPropagation(); setViewAttach(t.attachment); }}
                              style={{ display:'inline-flex', alignItems:'center', gap:3, padding:'1px 6px', background:'var(--accent-muted)', border:'none', borderRadius:'var(--r-full)', cursor:'pointer', color:'var(--accent)', fontSize:10, fontWeight:700 }}
                              title="Ver comprobante">
                              <Icon name="paperclip" size={10} color="var(--accent)" strokeWidth={2.2} />
                              {t.attachment.type === 'pdf' ? 'PDF' : 'Foto'}
                            </button>
                          )}
                        </div>
                      </div>
                      <div style={{ textAlign:'right', flexShrink:0 }}>
                        {/* Codificación coherente: rojo gasto, verde ingreso (antes el gasto iba en --t1 que rompía la lógica) */}
                        <div style={{ fontSize:14, fontWeight:800, color:t.type==='income'?'var(--success)':'var(--danger)', fontVariantNumeric:'tabular-nums' }}>
                          {t.type==='income'?'+':'–'}{fmtFull(t.amount, t.currency)}
                        </div>
                        {t.time && <div style={{ fontSize:11, color:'var(--t5)', marginTop:2 }}>{t.time}</div>}
                      </div>
                      <button onClick={()=>handleDelete(t.id)}
                        style={{ background:'none', border:'none', padding:4, opacity:0.2, transition:'opacity 0.15s', flexShrink:0 }}
                        onMouseEnter={e=>e.currentTarget.style.opacity=1}
                        onMouseLeave={e=>e.currentTarget.style.opacity=0.2}>
                        <Icon name="trash" size={14} color="var(--danger)" />
                      </button>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>

      {/* FAB — abre TxDrawer global */}
      <button className="fab fab-fixed" onClick={openNewTx} aria-label="Nuevo movimiento">
        <Icon name="plus" size={24} color="#fff" strokeWidth={2.5} />
      </button>

      {/* Visor de comprobante */}
      {viewAttach && <AttachmentViewer attachment={viewAttach} onClose={() => setViewAttach(null)} />}

      {/* Drawer "+ Más categorías" — lista completa con búsqueda */}
      {showAllCats && (() => {
        const q = catSearch.trim().toLowerCase();
        const list = catsForTab.filter(c => !q || c.toLowerCase().includes(q));
        return (
          <>
            <div className="drawer-backdrop" onClick={() => setShowAllCats(false)} style={{ zIndex:760 }} />
            <div className="drawer" style={{ zIndex:761, maxHeight:'70vh' }}>
              <div className="drawer-handle" />
              <div style={{ padding:'12px 20px 0' }}>
                <div style={{ fontSize:15, fontWeight:800, color:'var(--t1)', marginBottom:4 }}>Todas las categorías</div>
                <div style={{ fontSize:12, color:'var(--t4)', marginBottom:12 }}>
                  {filterTab==='all' ? 'De todos los tipos' : filterTab==='expense' ? 'Solo gastos' : 'Solo ingresos'} · {catsForTab.length} disponibles
                </div>
                <div style={{ display:'flex', alignItems:'center', gap:8, background:'var(--surface-2)', border:'1.5px solid var(--border)', borderRadius:'var(--r-md)', padding:'9px 14px', marginBottom:12 }}>
                  <Icon name="search" size={15} color="var(--t5)" />
                  <input autoFocus type="text" placeholder="Buscar categoría..." value={catSearch}
                    onChange={e => setCatSearch(e.target.value)}
                    style={{ flex:1, background:'none', border:'none', outline:'none', color:'var(--t1)', fontSize:14, fontFamily:'var(--font)' }} />
                </div>
              </div>
              <div style={{ overflowY:'auto', maxHeight:'calc(70vh - 130px)', padding:'0 12px 16px' }}>
                {list.length === 0 ? (
                  <div style={{ textAlign:'center', padding:'30px 20px', color:'var(--t5)', fontSize:13 }}>
                    Sin resultados para "{catSearch}"
                  </div>
                ) : list.map(c => {
                  const isSel = filterCat === c;
                  return (
                    <button key={c}
                      onClick={() => { setFilterCat(c); setShowAllCats(false); }}
                      style={{
                        width:'100%', display:'flex', alignItems:'center', gap:12,
                        padding:'12px 14px', marginBottom:4,
                        background: isSel ? 'var(--accent-muted)' : 'none',
                        border: `1px solid ${isSel ? 'var(--accent)' : 'transparent'}`,
                        borderRadius:'var(--r-md)', cursor:'pointer',
                        transition:'background 0.15s',
                      }}
                      onMouseEnter={e => { if (!isSel) e.currentTarget.style.background='var(--surface-2)'; }}
                      onMouseLeave={e => { if (!isSel) e.currentTarget.style.background='none'; }}>
                      <CategoryIcon category={c} size="sm" />
                      <div style={{ flex:1, textAlign:'left' }}>
                        <div style={{ fontSize:14, fontWeight:isSel?800:600, color:'var(--t1)' }}>{c}</div>
                        <div style={{ fontSize:11, color:'var(--t5)' }}>
                          {usageMap[c] || 0} {(usageMap[c]||0) === 1 ? 'movimiento' : 'movimientos'}
                        </div>
                      </div>
                      {isSel && <Icon name="checkCircle" size={18} color="var(--accent)" />}
                    </button>
                  );
                })}
              </div>
            </div>
          </>
        );
      })()}
    </div>
  );
};

Object.assign(window, { Transactions, CurrencyPicker, AttachmentViewer, TxDrawer });
