/* Finanzas (Fase 2): Disponible · Presupuesto · Movimientos · Importar ·
   Reportes · Créditos. Disponible fija el ingreso del mes (lo que Proyectos usa
   en Análisis); Presupuesto lo reparte por categoría; Movimientos e Importar
   (cartola CSV) alimentan el gastado; Reportes resume mes y tendencia. */
const { useState, useEffect } = React;

window.fmtCLP = (n) => '$' + (Math.round(Number(n) || 0)).toLocaleString('es-CL');

function Login() {
  const [email, setEmail] = useState('');
  const [sent, setSent] = useState(false);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const enviar = async (e) => {
    e.preventDefault();
    if (!email || busy) return;
    setBusy(true); setErr('');
    try {
      const { error } = await window.sb.auth.signInWithOtp({ email, options: { emailRedirectTo: window.location.origin } });
      if (error) throw error; setSent(true);
    } catch (ex) { setErr(ex.message || 'No se pudo enviar'); } finally { setBusy(false); }
  };
  return (
    <div style={{ minHeight: '100vh', display: 'grid', placeItems: 'center', background: 'var(--paper)' }}>
      <div className="card" style={{ maxWidth: 380, width: '90%', padding: 28, textAlign: 'center' }}>
        <div className="brand-mark" style={{ margin: '0 auto 14px' }}>F</div>
        <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 6px' }}>Finanzas</h1>
        <p style={{ color: 'var(--ink-3)', fontSize: 13, margin: '0 0 20px' }}>Entrá con tu correo y te mandamos un enlace.</p>
        {sent ? (
          <div className="tag" style={{ display: 'inline-flex', padding: '10px 14px' }}><Icon name="check" size={14} /> Revisá tu correo: te enviamos el enlace a {email}.</div>
        ) : (
          <form onSubmit={enviar}>
            <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tu@correo.cl" autoFocus
              className="input" style={{ width: '100%', marginBottom: 12 }} />
            <button className="btn olive" type="submit" disabled={busy} style={{ width: '100%', justifyContent: 'center' }}>{busy ? 'Enviando…' : 'Enviarme el enlace'}</button>
            {err && <p style={{ color: 'var(--rust)', fontSize: 12, marginTop: 10 }}>{err}</p>}
          </form>
        )}
      </div>
    </div>
  );
}

function Disponible() {
  const [mes, setMes] = useState(() => new Date().toISOString().slice(0, 7));
  const [data, setData] = useState(null);
  const [ingreso, setIngreso] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const [ok, setOk] = useState('');

  const cargar = async (m) => {
    setErr('');
    try {
      const d = await window.api('/api/finanzas/app-data?mes=' + m);
      setData(d); setIngreso(d.ingreso ? String(d.ingreso) : '');
    } catch (e) { setErr(e.message); }
  };
  useEffect(() => { cargar(mes); }, [mes]);

  const guardar = async (e) => {
    e.preventDefault();
    if (busy) return; setBusy(true); setOk('');
    try {
      const d = await window.api('/api/finanzas/budget/disponible', { method: 'PUT', body: JSON.stringify({ mes, ingreso: Number(ingreso) || 0 }) });
      setData(d); setOk('Guardado. Este es el disponible que Proyectos usa en Análisis.');
      setTimeout(() => setOk(''), 4000);
    } catch (ex) { setErr(ex.message); } finally { setBusy(false); }
  };

  return (
    <div style={{ maxWidth: 560 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Disponible del mes</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 20px' }}>Fijá el ingreso disponible del mes. Es el número que Proyectos usa para saber si un proyecto “alcanza”.</p>

      <div className="card" style={{ padding: 20, display: 'grid', gap: 16 }}>
        <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12, color: 'var(--ink-3)' }}>
          Mes
          <input type="month" value={mes} onChange={(e) => setMes(e.target.value)}
            className="input" style={{ maxWidth: 200 }} />
        </label>
        <form onSubmit={guardar} style={{ display: 'grid', gap: 12 }}>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12, color: 'var(--ink-3)' }}>
            Ingreso disponible (CLP)
            <input inputMode="numeric" value={ingreso} onChange={(e) => setIngreso(e.target.value.replace(/[^\d]/g, ''))} placeholder="Ej: 850000"
              className="input mono" style={{ fontSize: 16 }} />
          </label>
          <button className="btn olive" type="submit" disabled={busy} style={{ justifySelf: 'start' }}><Icon name="check" size={14} /> {busy ? 'Guardando…' : 'Guardar'}</button>
        </form>

        {data && (
          <div style={{ borderTop: '1px solid var(--line)', paddingTop: 14, display: 'grid', gap: 6 }}>
            <Fila label="Ingreso del mes" valor={window.fmtCLP(data.ingreso)} />
            <Fila label="Gastado" valor={'− ' + window.fmtCLP(data.gastado)} />
            <Fila label="Disponible" valor={window.fmtCLP(data.disponible)} fuerte />
          </div>
        )}
        {err && <p style={{ color: 'var(--rust)', fontSize: 12, margin: 0 }}>{err}</p>}
        {ok && <p style={{ color: 'var(--olive)', fontSize: 12, margin: 0 }}>{ok}</p>}
      </div>
      <p style={{ color: 'var(--ink-4)', fontSize: 12, marginTop: 14 }}>El “gastado” saldrá de tus movimientos cuando se porte la ingesta de cartolas. Por ahora arranca en 0.</p>
    </div>
  );
}

function Fila({ label, valor, fuerte }) {
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
      <span style={{ fontSize: fuerte ? 14 : 12.5, color: fuerte ? 'var(--ink)' : 'var(--ink-4)', fontWeight: fuerte ? 600 : 400 }}>{label}</span>
      <span style={{ marginLeft: 'auto', fontFamily: 'var(--mono)', fontSize: fuerte ? 18 : 13, fontWeight: fuerte ? 600 : 400 }}>{valor}</span>
    </div>
  );
}

function Creditos() {
  const [propuestos, setPropuestos] = useState([]);
  const [cuotas, setCuotas] = useState([]);
  const [busy, setBusy] = useState('');
  const [err, setErr] = useState('');

  const cargar = async () => {
    setErr('');
    try {
      const [p, c] = await Promise.all([
        window.api('/api/finanzas/propuestos'),
        window.api('/api/finanzas/cuotas'),
      ]);
      setPropuestos(p || []); setCuotas(c || []);
    } catch (e) { setErr(e.message); }
  };
  useEffect(() => { cargar(); }, []);

  const tomar = async (plan) => {
    setBusy(plan.id);
    try { await window.api('/api/finanzas/cuotas/tomar', { method: 'POST', body: JSON.stringify({ plan_id: plan.id }) }); await cargar(); }
    catch (e) { setErr(e.message); } finally { setBusy(''); }
  };

  return (
    <div style={{ maxWidth: 620 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Créditos</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 20px' }}>Los escenarios que “llevaste a Finanzas” desde Proyectos llegan como propuestos. Cuando el banco te lo apruebe, marcá “Ya lo tomé” y se vuelve una cuota real.</p>

      <section style={{ marginBottom: 22 }}>
        <h3 style={{ fontSize: 13, textTransform: 'uppercase', letterSpacing: '.05em', color: 'var(--ink-3)', margin: '0 0 10px' }}>Propuestos</h3>
        {propuestos.length === 0 ? (
          <p style={{ color: 'var(--ink-4)', fontSize: 13 }}>Nada propuesto. Desde Proyectos → Análisis, botón “Llevar a Finanzas”.</p>
        ) : (
          <div style={{ display: 'grid', gap: 8 }}>
            {propuestos.map((p) => (
              <div key={p.id} className="card" style={{ padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                <div style={{ flex: 1, minWidth: 160 }}>
                  <strong style={{ fontSize: 14, textTransform: 'capitalize' }}>{p.fuente}</strong>
                  <span style={{ color: 'var(--ink-4)', fontSize: 12 }}> · {p.proyecto_nombre || 'Proyecto'}</span>
                  <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2, fontFamily: 'var(--mono)' }}>
                    {window.fmtCLP(p.monto)}{p.cuotas ? ` · ${p.cuotas}× ${window.fmtCLP(p.cuota)}` : ''}
                  </div>
                </div>
                <button className="btn olive" disabled={busy === p.id} onClick={() => tomar(p)}><Icon name="check" size={14} /> {busy === p.id ? 'Tomando…' : 'Ya lo tomé'}</button>
              </div>
            ))}
          </div>
        )}
      </section>

      <section>
        <h3 style={{ fontSize: 13, textTransform: 'uppercase', letterSpacing: '.05em', color: 'var(--ink-3)', margin: '0 0 10px' }}>Cuotas reales</h3>
        {cuotas.length === 0 ? (
          <p style={{ color: 'var(--ink-4)', fontSize: 13 }}>Sin cuotas todavía.</p>
        ) : (
          <div style={{ display: 'grid', gap: 8 }}>
            {cuotas.map((c) => (
              <div key={c.id} className="card" style={{ padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
                <Icon name="bank" size={15} />
                <div style={{ flex: 1 }}>
                  <strong style={{ fontSize: 14 }}>{c.descripcion}</strong>
                  <div style={{ fontSize: 12, color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}>{c.cuotas_totales ? `${c.cuotas_totales}× ` : ''}{window.fmtCLP(c.cuota)} · total {window.fmtCLP(c.monto)}</div>
                </div>
                <span className="tag" style={{ fontSize: 11, padding: '3px 9px', borderRadius: 999, background: 'var(--olive-tint)', color: 'var(--olive)' }}>{c.estado}</span>
              </div>
            ))}
          </div>
        )}
      </section>
      {err && <p style={{ color: 'var(--rust)', fontSize: 12, marginTop: 14 }}>{err}</p>}
    </div>
  );
}

function Movimientos() {
  const [mes, setMes] = useState(() => new Date().toISOString().slice(0, 7));
  const [movs, setMovs] = useState([]);
  const [cats, setCats] = useState([]);
  const [f, setF] = useState({ tipo: 'gasto', monto: '', descripcion: '', fecha: '', category_id: '' });
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const cargar = async (m) => { try { setMovs(await window.api('/api/finanzas/movimientos?mes=' + m)); setErr(''); } catch (e) { setErr(e.message); } };
  useEffect(() => { cargar(mes); }, [mes]);
  useEffect(() => { window.api('/api/finanzas/categorias').then(setCats).catch(() => {}); }, []);
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));
  const agregar = async (e) => {
    e.preventDefault(); if (!f.monto || busy) return; setBusy(true);
    try {
      await window.api('/api/finanzas/movimientos', { method: 'POST', body: JSON.stringify({ tipo: f.tipo, monto: Number(f.monto) || 0, descripcion: f.descripcion.trim() || null, fecha: f.fecha || null, category_id: f.category_id || null }) });
      setF({ tipo: 'gasto', monto: '', descripcion: '', fecha: '', category_id: '' }); cargar(mes);
    } catch (ex) { alert(ex.message); } finally { setBusy(false); }
  };
  const borrar = async (id) => { try { await window.api('/api/finanzas/movimientos/' + id, { method: 'DELETE' }); cargar(mes); } catch (e) { alert(e.message); } };
  return (
    <div style={{ maxWidth: 640 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Movimientos</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 18px' }}>Cargá gastos e ingresos del mes. Los gastos bajan el disponible que ve Proyectos.</p>
      <div className="card" style={{ padding: 16, marginBottom: 14, display: 'grid', gap: 12 }}>
        <input type="month" value={mes} onChange={(e) => setMes(e.target.value)} className="input" style={{ maxWidth: 200 }} />
        <form onSubmit={agregar} style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
          <select value={f.tipo} onChange={(e) => set('tipo', e.target.value)} className="input">
            <option value="gasto">Gasto</option>
            <option value="ingreso">Ingreso</option>
          </select>
          <input inputMode="numeric" value={f.monto} onChange={(e) => set('monto', e.target.value.replace(/[^\d]/g, ''))} placeholder="Monto" className="input mono" style={{ width: 120 }} />
          {f.tipo === 'gasto' && (
            <select value={f.category_id} onChange={(e) => set('category_id', e.target.value)} className="input" style={{ maxWidth: 180 }}>
              <option value="">Sin categoría</option>
              {cats.map((ct) => <option key={ct.id} value={ct.id}>{ct.grupo} · {ct.nombre}</option>)}
            </select>
          )}
          <input value={f.descripcion} onChange={(e) => set('descripcion', e.target.value)} placeholder="Descripción" className="input" style={{ flex: 1, minWidth: 140 }} />
          <input type="date" value={f.fecha} onChange={(e) => set('fecha', e.target.value)} className="input" />
          <button className="btn olive" type="submit" disabled={busy}><Icon name="plus" size={14} /> Agregar</button>
        </form>
      </div>
      {err && <p style={{ color: 'var(--rust)', fontSize: 12 }}>{err}</p>}
      <div style={{ display: 'grid', gap: 8 }}>
        {movs.length === 0 ? (
          <p style={{ color: 'var(--ink-4)', fontSize: 13 }}>Sin movimientos este mes.</p>
        ) : movs.map((m) => (
          <div key={m.id} className="card" style={{ padding: '10px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--mono)', width: 82 }}>{(m.posted_at || '').slice(0, 10)}</span>
            <span style={{ flex: 1, fontSize: 14 }}>
              {m.merchant_raw || (m.direction === 'credit' ? 'Ingreso' : 'Gasto')}
              {m.categoria_nombre && <span className="tag" style={{ marginLeft: 8, fontSize: 10, padding: '2px 7px' }}>{m.categoria_nombre}</span>}
            </span>
            <span style={{ fontFamily: 'var(--mono)', fontSize: 14, color: m.direction === 'credit' ? 'var(--olive)' : 'var(--ink)' }}>
              {m.direction === 'credit' ? '+' : '−'} {window.fmtCLP(m.amount)}
            </span>
            <button className="btn" onClick={() => borrar(m.id)} title="Borrar" style={{ padding: '5px 8px' }}><Icon name="x" size={13} /></button>
          </div>
        ))}
      </div>
    </div>
  );
}

function Presupuesto() {
  const [mes, setMes] = useState(() => new Date().toISOString().slice(0, 7));
  const [data, setData] = useState(null);
  const [err, setErr] = useState('');
  const [edit, setEdit] = useState({}); // category_id -> string en edición
  const cargar = async (m) => { try { setData(await window.api('/api/finanzas/presupuesto?mes=' + m)); setErr(''); } catch (e) { setErr(e.message); } };
  useEffect(() => { cargar(mes); }, [mes]);
  const guardar = async (category_id, valor) => {
    const plan = Number(String(valor).replace(/[^\d]/g, '')) || 0;
    try {
      await window.api('/api/finanzas/presupuesto/linea', { method: 'PUT', body: JSON.stringify({ mes, category_id, plan }) });
      setEdit((s) => { const n = { ...s }; delete n[category_id]; return n; });
      cargar(mes);
    } catch (ex) { alert(ex.message); }
  };
  const fmt = window.fmtCLP;
  const planTotal = data ? data.plan_total : 0;
  const ingreso = data ? data.ingreso : 0;
  const sinAsignar = ingreso - planTotal;
  return (
    <div style={{ maxWidth: 720 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Presupuesto</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 18px' }}>Repartí el ingreso del mes por categoría y mirá cuánto llevás gastado en cada una.</p>
      <input type="month" value={mes} onChange={(e) => setMes(e.target.value)} className="input" style={{ maxWidth: 200, marginBottom: 14 }} />
      {data && (
        <div className="card" style={{ padding: 16, marginBottom: 16, display: 'flex', gap: 24, flexWrap: 'wrap' }}>
          <div><div style={{ fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>Ingreso</div><div style={{ fontFamily: 'var(--mono)', fontSize: 18 }}>{fmt(ingreso)}</div></div>
          <div><div style={{ fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>Planificado</div><div style={{ fontFamily: 'var(--mono)', fontSize: 18 }}>{fmt(planTotal)}</div></div>
          <div><div style={{ fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>Sin asignar</div><div style={{ fontFamily: 'var(--mono)', fontSize: 18, color: sinAsignar < 0 ? 'var(--rust)' : 'var(--olive)' }}>{fmt(sinAsignar)}</div></div>
          <div><div style={{ fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>Gastado</div><div style={{ fontFamily: 'var(--mono)', fontSize: 18 }}>{fmt(data.gastado_total)}</div></div>
        </div>
      )}
      {err && <p style={{ color: 'var(--rust)', fontSize: 12 }}>{err}</p>}
      {data && data.grupos.map((g) => (
        <div key={g.id} style={{ marginBottom: 18 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '.08em', margin: '0 0 8px' }}>{g.nombre}</div>
          <div style={{ display: 'grid', gap: 6 }}>
            {g.categorias.map((ct) => {
              const excede = ct.plan > 0 && ct.gastado > ct.plan;
              const pct = ct.plan > 0 ? Math.min(100, Math.round((ct.gastado / ct.plan) * 100)) : (ct.gastado > 0 ? 100 : 0);
              const enEdit = edit[ct.id] !== undefined;
              return (
                <div key={ct.id} className="card" style={{ padding: '10px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, marginBottom: 6 }}>{ct.nombre}</div>
                    <div style={{ height: 5, borderRadius: 3, background: 'var(--paper-2)', overflow: 'hidden' }}>
                      <div style={{ width: pct + '%', height: '100%', background: excede ? 'var(--rust)' : 'var(--olive)' }} />
                    </div>
                  </div>
                  <div style={{ textAlign: 'right', minWidth: 90 }}>
                    <div style={{ fontFamily: 'var(--mono)', fontSize: 13, color: excede ? 'var(--rust)' : 'var(--ink-3)' }}>{fmt(ct.gastado)}</div>
                    <div style={{ fontSize: 10, color: 'var(--ink-4)' }}>gastado</div>
                  </div>
                  {enEdit ? (
                    <input autoFocus inputMode="numeric" value={edit[ct.id]}
                      onChange={(e) => setEdit((s) => ({ ...s, [ct.id]: e.target.value.replace(/[^\d]/g, '') }))}
                      onBlur={(e) => guardar(ct.id, e.target.value)}
                      onKeyDown={(e) => { if (e.key === 'Enter') e.target.blur(); if (e.key === 'Escape') setEdit((s) => { const n = { ...s }; delete n[ct.id]; return n; }); }}
                      className="input mono" style={{ width: 100, textAlign: 'right' }} />
                  ) : (
                    <button className="btn" onClick={() => setEdit((s) => ({ ...s, [ct.id]: ct.plan ? String(ct.plan) : '' }))}
                      style={{ minWidth: 100, justifyContent: 'flex-end', fontFamily: 'var(--mono)', fontSize: 13 }} title="Editar plan">
                      {ct.plan ? fmt(ct.plan) : '—'} <Icon name="edit" size={12} />
                    </button>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

const MESES_CORTOS = ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'];
const mesCorto = (ym) => { const m = Number((ym || '').slice(5, 7)); return MESES_CORTOS[m - 1] || ym; };

function Reportes() {
  const [mes, setMes] = useState(() => new Date().toISOString().slice(0, 7));
  const [data, setData] = useState(null);
  const [err, setErr] = useState('');
  useEffect(() => { window.api('/api/finanzas/reportes?mes=' + mes).then((d) => { setData(d); setErr(''); }).catch((e) => setErr(e.message)); }, [mes]);
  const fmt = window.fmtCLP;
  const maxSerie = data ? Math.max(1, ...data.serie.flatMap((s) => [s.ingreso, s.gasto])) : 1;
  const maxCat = data && data.por_categoria.length ? Math.max(1, ...data.por_categoria.map((c) => c.gastado)) : 1;
  const card = { flex: 1, minWidth: 150, padding: '14px 16px' };
  const lab = { fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)' };
  const big = { fontFamily: 'var(--mono)', fontSize: 22, marginTop: 4 };
  return (
    <div style={{ maxWidth: 760 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Reportes</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 18px' }}>Resumen del mes, tendencia de los últimos 6 meses y en qué se va la plata.</p>
      <input type="month" value={mes} onChange={(e) => setMes(e.target.value)} className="input" style={{ maxWidth: 200, marginBottom: 16 }} />
      {err && <p style={{ color: 'var(--rust)', fontSize: 12 }}>{err}</p>}
      {data && (
        <>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 20 }}>
            <div className="card" style={card}><div style={lab}>Ingresos</div><div style={{ ...big, color: 'var(--olive)' }}>{fmt(data.ingresos)}</div></div>
            <div className="card" style={card}><div style={lab}>Gastos</div><div style={{ ...big, color: 'var(--rust)' }}>{fmt(data.gastos)}</div></div>
            <div className="card" style={card}><div style={lab}>Neto</div><div style={{ ...big, color: data.neto < 0 ? 'var(--rust)' : 'var(--ink)' }}>{fmt(data.neto)}</div></div>
          </div>

          <div className="card" style={{ padding: 16, marginBottom: 20 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '.08em', marginBottom: 14 }}>Tendencia · 6 meses</div>
            <div style={{ display: 'flex', alignItems: 'flex-end', gap: 14, height: 130 }}>
              {data.serie.map((s) => (
                <div key={s.mes} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, height: '100%' }}>
                  <div style={{ flex: 1, display: 'flex', alignItems: 'flex-end', gap: 3, width: '100%', justifyContent: 'center' }}>
                    <div title={'Ingreso ' + fmt(s.ingreso)} style={{ width: 12, height: (s.ingreso / maxSerie * 100) + '%', minHeight: 2, background: 'var(--olive)', borderRadius: '3px 3px 0 0' }} />
                    <div title={'Gasto ' + fmt(s.gasto)} style={{ width: 12, height: (s.gasto / maxSerie * 100) + '%', minHeight: 2, background: 'var(--rust)', borderRadius: '3px 3px 0 0' }} />
                  </div>
                  <span style={{ fontSize: 10, color: s.mes === mes ? 'var(--ink)' : 'var(--ink-4)', fontWeight: s.mes === mes ? 600 : 400 }}>{mesCorto(s.mes)}</span>
                </div>
              ))}
            </div>
            <div style={{ display: 'flex', gap: 16, marginTop: 12, fontSize: 11, color: 'var(--ink-4)' }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><span style={{ width: 9, height: 9, borderRadius: 2, background: 'var(--olive)' }} /> Ingreso</span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><span style={{ width: 9, height: 9, borderRadius: 2, background: 'var(--rust)' }} /> Gasto</span>
            </div>
          </div>

          <div className="card" style={{ padding: 16 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '.08em', marginBottom: 14 }}>En qué se fue · {mesCorto(mes)}</div>
            {data.por_categoria.length === 0 ? (
              <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: 0 }}>Sin gastos categorizados este mes.</p>
            ) : (
              <div style={{ display: 'grid', gap: 10 }}>
                {data.por_categoria.map((c, i) => (
                  <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                    <div style={{ width: 150, flexShrink: 0, fontSize: 13, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {c.nombre}{c.grupo && <span style={{ color: 'var(--ink-4)', fontSize: 11 }}> · {c.grupo}</span>}
                    </div>
                    <div style={{ flex: 1, height: 8, borderRadius: 4, background: 'var(--paper-2)', overflow: 'hidden' }}>
                      <div style={{ width: (c.gastado / maxCat * 100) + '%', height: '100%', background: 'var(--olive)' }} />
                    </div>
                    <div style={{ width: 90, textAlign: 'right', fontFamily: 'var(--mono)', fontSize: 13 }}>{fmt(c.gastado)}</div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
}

function Importar() {
  const [cuenta, setCuenta] = useState('Efectivo');
  const [nombre, setNombre] = useState('');
  const [prev, setPrev] = useState(null); // { total, descartadas, conCabecera, delimitador, filas }
  const [filas, setFilas] = useState([]);
  const [busy, setBusy] = useState(false);
  const [res, setRes] = useState(null);
  const [err, setErr] = useState('');
  const onFile = async (e) => {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    setRes(null); setErr('');
    try {
      const text = await file.text();
      const r = window.parseCartola(text);
      setNombre(file.name);
      setPrev(r); setFilas(r.filas.map((f) => ({ ...f })));
      if (r.errores && r.errores.length) setErr(r.errores.join(' '));
    } catch (ex) { setErr('No se pudo leer el archivo: ' + ex.message); }
  };
  const setTipo = (i, tipo) => setFilas((s) => s.map((f, j) => (j === i ? { ...f, tipo } : f)));
  const quitar = (i) => setFilas((s) => s.filter((_, j) => j !== i));
  const confirmar = async () => {
    if (!filas.length || busy) return; setBusy(true); setErr('');
    try {
      const r = await window.api('/api/finanzas/importar', { method: 'POST', body: JSON.stringify({ cuenta: cuenta.trim() || 'Efectivo', nombre, filas }) });
      setRes(r); setPrev(null); setFilas([]);
    } catch (ex) { setErr(ex.message); } finally { setBusy(false); }
  };
  const fmt = window.fmtCLP;
  const totalGasto = filas.filter((f) => f.tipo === 'gasto').reduce((s, f) => s + f.monto, 0);
  const totalIngreso = filas.filter((f) => f.tipo === 'ingreso').reduce((s, f) => s + f.monto, 0);
  return (
    <div style={{ maxWidth: 760 }}>
      <h1 style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 26, margin: '0 0 4px' }}>Importar cartola</h1>
      <p style={{ color: 'var(--ink-4)', fontSize: 13, margin: '0 0 18px' }}>Subí la cartola de tu banco en CSV. Revisás los movimientos y los confirmás; los repetidos se descartan solos.</p>
      <div className="card" style={{ padding: 16, marginBottom: 16, display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
        <label style={{ fontSize: 12, color: 'var(--ink-3)' }}>Cuenta
          <input value={cuenta} onChange={(e) => setCuenta(e.target.value)} placeholder="Efectivo" className="input" style={{ marginLeft: 8, width: 150 }} />
        </label>
        <label className="btn olive" style={{ cursor: 'pointer' }}>
          <Icon name="download" size={14} /> Elegir CSV
          <input type="file" accept=".csv,.txt,text/csv" onChange={onFile} style={{ display: 'none' }} />
        </label>
      </div>
      {err && <p style={{ color: 'var(--rust)', fontSize: 12 }}>{err}</p>}
      {res && (
        <div className="card" style={{ padding: 16, marginBottom: 16 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}><Icon name="check" size={16} /> <strong>Importación lista</strong></div>
          <p style={{ fontSize: 13, color: 'var(--ink-3)', margin: 0 }}>{res.nuevas} nuevos movimientos en «{res.cuenta}». {res.duplicadas > 0 && `${res.duplicadas} repetidos se omitieron.`}</p>
        </div>
      )}
      {prev && filas.length > 0 && (
        <>
          <div style={{ display: 'flex', gap: 16, alignItems: 'center', marginBottom: 10, flexWrap: 'wrap' }}>
            <span style={{ fontSize: 13, color: 'var(--ink-3)' }}>{filas.length} movimientos · gastos {fmt(totalGasto)} · ingresos {fmt(totalIngreso)}</span>
            <button className="btn olive" onClick={confirmar} disabled={busy} style={{ marginLeft: 'auto' }}><Icon name="check" size={14} /> Confirmar importación</button>
          </div>
          <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
            <div style={{ maxHeight: 420, overflowY: 'auto' }}>
              {filas.map((f, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '9px 14px', borderBottom: '1px solid var(--line)' }}>
                  <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--mono)', width: 82 }}>{f.fecha}</span>
                  <span style={{ flex: 1, fontSize: 13, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.descripcion || '—'}</span>
                  <select value={f.tipo} onChange={(e) => setTipo(i, e.target.value)} className="input" style={{ padding: '4px 6px', fontSize: 12 }}>
                    <option value="gasto">Gasto</option>
                    <option value="ingreso">Ingreso</option>
                  </select>
                  <span style={{ fontFamily: 'var(--mono)', fontSize: 13, width: 100, textAlign: 'right', color: f.tipo === 'ingreso' ? 'var(--olive)' : 'var(--ink)' }}>{f.tipo === 'ingreso' ? '+' : '−'} {fmt(f.monto)}</span>
                  <button className="btn" onClick={() => quitar(i)} title="Quitar" style={{ padding: '4px 7px' }}><Icon name="x" size={12} /></button>
                </div>
              ))}
            </div>
          </div>
        </>
      )}
    </div>
  );
}

const NAV = [
  { id: 'disponible', label: 'Disponible', icon: 'bank' },
  { id: 'presupuesto', label: 'Presupuesto', icon: 'sheet' },
  { id: 'movimientos', label: 'Movimientos', icon: 'history' },
  { id: 'importar', label: 'Importar', icon: 'download' },
  { id: 'reportes', label: 'Reportes', icon: 'chart' },
  { id: 'creditos', label: 'Créditos', icon: 'wallet' },
];

function Shell({ user }) {
  const [view, setView] = useState('disponible');
  const logout = () => window.sb.auth.signOut();
  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: 'var(--paper)', color: 'var(--ink)' }}>
      <aside style={{ width: 232, flexShrink: 0, borderRight: '1px solid var(--line)', background: 'var(--card)', display: 'flex', flexDirection: 'column', padding: '16px 12px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 8px 18px' }}>
          <div className="brand-mark">F</div>
          <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.15 }}>
            <span style={{ fontSize: 9, letterSpacing: '.14em', color: 'var(--ink-4)', textTransform: 'uppercase' }}>Simplificando</span>
            <span style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 18 }}>Finanzas</span>
          </div>
        </div>
        <nav style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
          {NAV.map((n) => (
            <button key={n.id} className={'nav-item ' + (view === n.id ? 'active' : '')} onClick={() => setView(n.id)}
              style={{ display: 'flex', alignItems: 'center', gap: 10, width: '100%', padding: '9px 12px' }}>
              <Icon name={n.icon} size={16} /> <span>{n.label}</span>
            </button>
          ))}
        </nav>
        <div style={{ marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: 8, paddingTop: 12 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '8px 10px', borderRadius: 12, background: 'var(--paper-2)' }}>
            <div style={{ width: 30, height: 30, borderRadius: '50%', background: 'var(--olive)', color: '#fff', display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 600 }}>{(user.email || '?').slice(0, 2).toUpperCase()}</div>
            <span style={{ fontSize: 11, color: 'var(--ink-3)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{user.email}</span>
          </div>
          <button className="btn" onClick={logout} style={{ justifyContent: 'center' }}><Icon name="logout" size={14} /> Cerrar sesión</button>
        </div>
      </aside>
      <main style={{ flex: 1, minWidth: 0, padding: '24px 26px 60px' }}>
        {view === 'disponible' && <Disponible />}
        {view === 'presupuesto' && <Presupuesto />}
        {view === 'movimientos' && <Movimientos />}
        {view === 'importar' && <Importar />}
        {view === 'reportes' && <Reportes />}
        {view === 'creditos' && <Creditos />}
      </main>
    </div>
  );
}

function App() {
  const session = window.useSession();
  if (session === null) return <div style={{ minHeight: '100vh', display: 'grid', placeItems: 'center', background: 'var(--paper)', color: 'var(--ink-3)' }}>Cargando…</div>;
  if (!session) return <Login />;
  return <Shell user={session.user} />;
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
