// admin.jsx — Panel de administración Banco Ortopédico (prototipo interactivo)
const { useState, useEffect, useRef } = React;

/* ------------------------------------------------------------------ */
/* Datos de ejemplo                                                    */
/* ------------------------------------------------------------------ */
const POSTS_INIT = [
  { id: 1, texto: "¡Nueva silla de ruedas disponible en el Banco Ortopédico! Consulta por WhatsApp al 098 679 089.", canales: ["web", "fb", "ig"], fecha: "10/05/2026", img: true },
  { id: 2, texto: "Gracias a todos los que participaron del Festival de India Muerta 🐎", canales: ["fb", "ig"], fecha: "03/03/2026", img: true },
];

const ROL_BADGE = { superadmin: "out", admin: "info", consulta: "ok" };

/* ------------------------------------------------------------------ */
/* LOGIN                                                               */
/* ------------------------------------------------------------------ */
function Login({ onEnter }) {
  const [email, setEmail] = useState("");
  const [pass, setPass] = useState("");
  const [err, setErr] = useState("");
  const submit = (e) => {
    e.preventDefault();
    setErr("");
    window.RotaryAPI.login(email, pass)
      .then(() => onEnter(email))
      .catch(() => setErr("Credenciales inválidas"));
  };
  return (
    <div className="login-wrap">
      <form className="login-card frm" onSubmit={submit}>
        <img src="../assets/logo-rotary-lascano.jpg" alt="Rotary Club de Lascano" />
        <h1>Panel de administración</h1>
        <p className="sub">Banco Ortopédico — Casa Rotaria de Lascano</p>
        <div className="one">
          <label>Correo electrónico</label>
          <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tucorreo@ejemplo.com" />
        </div>
        <div className="one">
          <label>Contraseña</label>
          <input type="password" value={pass} onChange={(e) => setPass(e.target.value)} placeholder="••••••••" />
        </div>
        {err && <div style={{ color: "var(--cranberry)", fontSize: 13, marginBottom: 10 }}>{err}</div>}
        <button type="submit" className="btn btn-azure btn-lg" style={{ width: "100%", justifyContent: "center", marginTop: 6 }}>Ingresar</button>
        <div style={{ textAlign: "center", marginTop: 18 }}>
          <a href="portal.html" style={{ fontSize: 14, fontWeight: 600 }}>← Volver al portal público</a>
        </div>
      </form>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* Helpers UI                                                          */
/* ------------------------------------------------------------------ */
function Panel({ title, action, children, pad }) {
  return (
    <div className={"panel" + (pad ? " pad" : "")}>
      <div className="panel-h"><h3>{title}</h3>{action}</div>
      <div className="panel-b">{children}</div>
    </div>
  );
}
function ChannelChip({ c }) {
  const map = { web: { bg: "var(--azure)", t: "W" }, fb: { bg: "#1877f2", t: "f" }, ig: { bg: "#d6249f", t: "◎" } };
  const m = map[c]; return <span className="ch" style={{ background: m.bg, width: 20, height: 20, borderRadius: 5, display: "inline-grid", placeItems: "center", color: "#fff", fontSize: 11, fontWeight: 800 }}>{m.t}</span>;
}

/* ------------------------------------------------------------------ */
/* VISTAS                                                              */
/* ------------------------------------------------------------------ */
function Dashboard({ go }) {
  const [m, setM] = useState(null);
  const [arts, setArts] = useState([]);
  const [prest, setPrest] = useState([]);
  useEffect(() => {
    window.RotaryAPI.get("/metricas").then(setM).catch(() => {});
    window.RotaryAPI.get("/articulos/admin").then(setArts).catch(() => {});
    window.RotaryAPI.get("/prestamos?activos=true").then(setPrest).catch(() => {});
  }, []);
  const kpis = [
    { ico: "📦", bg: "#eaf2fb", c: "var(--azure)", b: arts.length, s: "Tipos de equipamiento" },
    { ico: "🤝", bg: "#fdf0d6", c: "var(--gold-deep)", b: m ? m.prestamos_activos : "—", s: "Préstamos activos" },
    { ico: "⚠️", bg: "#fbdfe4", c: "#b0123e", b: m ? m.prestamos_mas_30_dias : "—", s: "Préstamos +30 días" },
    { ico: "🛠", bg: "#dcf3e8", c: "#0a7c52", b: m ? m.articulos_sin_stock : "—", s: "Sin stock" },
  ];
  return (
    <div className="view">
      <div className="kpis">
        {kpis.map((k, i) => (
          <div className="kpi" key={i}>
            <div className="ico" style={{ background: k.bg, color: k.c }}>{k.ico}</div>
            <b>{k.b}</b><span>{k.s}</span>
          </div>
        ))}
      </div>
      <Panel title="Préstamos activos" action={<button className="btn btn-ghost btn-sm" onClick={() => go("prestamos")}>Ver todos</button>}>
        <table className="tbl">
          <thead><tr><th>Nº</th><th>Persona</th><th>C.I.</th><th>Inicio</th></tr></thead>
          <tbody>
            {prest.map((p) => (
              <tr key={p.id}><td style={{ fontWeight: 700 }}>{p.id}</td><td>{p.persona_nombre}</td>
                <td>{p.persona_ci || "—"}</td><td>{p.fecha_inicio}</td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
      <Panel title="Disponibilidad de equipamiento">
        <table className="tbl">
          <thead><tr><th>Artículo</th><th>Disponibles</th><th>Total</th><th>Estado</th></tr></thead>
          <tbody>
            {arts.map((a) => (
              <tr key={a.id}><td style={{ fontWeight: 600 }}>{a.nombre}</td><td>{a.stock_disponible}</td><td>{a.stock_total}</td>
                <td><span className={"badge " + (a.stock_disponible === 0 ? "out" : a.stock_disponible === 1 ? "warn" : "ok")}>{a.stock_disponible === 0 ? "Sin stock" : a.stock_disponible === 1 ? "Último" : "Disponible"}</span></td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

function Articulos({ openModal }) {
  const [arts, setArts] = useState([]);
  const load = () => window.RotaryAPI.get("/articulos/admin").then(setArts).catch(() => {});
  useEffect(() => { load(); }, []);
  const toggle = (a) =>
    window.RotaryAPI.put("/articulos/" + a.id, { visible_publico: !a.visible_publico }).then(load);
  return (
    <div className="view">
      <Panel title="Artículos" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("articulo")}>+ Nuevo artículo</button>}>
        <table className="tbl">
          <thead><tr><th>Nombre</th><th>Unidad</th><th>Disp. / Total</th><th>Visible en portal</th><th></th></tr></thead>
          <tbody>
            {arts.map((a) => (
              <tr key={a.id}>
                <td style={{ fontWeight: 600, color: "var(--ink)" }}>{a.nombre}</td>
                <td>{a.unidad}</td>
                <td><b style={{ color: "var(--azure)" }}>{a.stock_disponible}</b> / {a.stock_total}</td>
                <td><button className={"sw" + (a.visible_publico ? " on" : "")} onClick={() => toggle(a)} aria-label="visible"></button></td>
                <td style={{ textAlign: "right" }}><button className="icon-btn" onClick={() => openModal("articulo")}>✎</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

function Prestamos({ openModal }) {
  const [items, setItems] = useState([]);
  const load = () => window.RotaryAPI.get("/prestamos").then(setItems).catch(() => {});
  useEffect(() => { load(); }, []);
  const cerrar = (id) => window.RotaryAPI.put("/prestamos/" + id + "/cerrar").then(load);
  return (
    <div className="view">
      <Panel title="Préstamos" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("prestamo")}>+ Nuevo préstamo</button>}>
        <table className="tbl">
          <thead><tr><th>Nº</th><th>Persona</th><th>C.I.</th><th>Inicio</th><th>Estado</th><th></th></tr></thead>
          <tbody>
            {items.map((p) => {
              const estado = p.fecha_devolucion ? "devuelto" : "activo";
              return (
                <tr key={p.id}>
                  <td style={{ fontWeight: 700 }}>{p.id}</td><td>{p.persona_nombre}</td><td>{p.persona_ci || "—"}</td><td>{p.fecha_inicio}</td>
                  <td><span className={"badge " + (estado === "activo" ? "info" : "ok")}>{estado}</span></td>
                  <td style={{ textAlign: "right" }}>{!p.fecha_devolucion && <button className="btn btn-ghost btn-sm" onClick={() => cerrar(p.id)}>Cerrar</button>}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

function Personas() {
  const [rows, setRows] = useState([]);
  useEffect(() => {
    window.RotaryAPI.get("/prestamos").then((ps) => {
      const map = {};
      ps.forEach((p) => {
        const k = (p.persona_ci || p.persona_nombre);
        if (!map[k]) map[k] = { nombre: p.persona_nombre, ci: p.persona_ci || "—", tel: p.persona_telefono || "—", prestamos: 0 };
        map[k].prestamos += 1;
      });
      setRows(Object.values(map));
    }).catch(() => {});
  }, []);
  return (
    <div className="view">
      <Panel title="Personas">
        <table className="tbl">
          <thead><tr><th>Nombre</th><th>C.I.</th><th>Teléfono</th><th>Préstamos</th></tr></thead>
          <tbody>
            {rows.map((p, i) => (
              <tr key={i}><td style={{ fontWeight: 600 }}>{p.nombre}</td><td>{p.ci}</td><td>{p.tel}</td><td>{p.prestamos}</td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

function Reparacion({ openModal }) {
  const [items, setItems] = useState([]);
  const load = () => window.RotaryAPI.get("/reparaciones").then(setItems).catch(() => {});
  useEffect(() => { load(); }, []);
  return (
    <div className="view">
      <Panel title="En reparación" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("reparacion")}>+ Enviar a reparación</button>}>
        <table className="tbl">
          <thead><tr><th>Artículo</th><th>Entrada</th><th>Responsable</th><th>Costo</th><th>Estado</th></tr></thead>
          <tbody>
            {items.map((r) => (
              <tr key={r.id}><td style={{ fontWeight: 600 }}>{r.articulo_nombre || ("#" + r.articulo_id)}</td><td>{r.fecha_entrada}</td><td>{r.responsable_nombre}</td><td>{r.costo != null ? "$ " + r.costo : "—"}</td>
                <td><span className={"badge " + (r.fecha_retorno ? "ok" : "warn")}>{r.fecha_retorno ? "retornado" : "en proceso"}</span></td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

function Usuarios({ openModal }) {
  const [items, setItems] = useState([]);
  useEffect(() => { window.RotaryAPI.get("/usuarios").then(setItems).catch(() => {}); }, []);
  return (
    <div className="view">
      <Panel title="Usuarios" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("usuario")}>+ Nuevo usuario</button>}>
        <table className="tbl">
          <thead><tr><th>Nombre</th><th>Email</th><th>Rol</th></tr></thead>
          <tbody>
            {items.map((u) => (
              <tr key={u.id}><td style={{ fontWeight: 600 }}>{u.nombre}</td><td>{u.email}</td>
                <td><span className={"badge " + ROL_BADGE[u.rol]}>{u.rol}</span></td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

/* ---- Publicaciones (web + redes) ---- */
function Publicaciones() {
  const [texto, setTexto] = useState("");
  const [canales, setCanales] = useState({ web: true, fb: true, ig: false });
  const [conImg, setConImg] = useState(true);
  const [posts, setPosts] = useState(POSTS_INIT);
  const [flash, setFlash] = useState("");

  const toggleCh = (c) => setCanales({ ...canales, [c]: !canales[c] });
  const activos = Object.keys(canales).filter((c) => canales[c]);
  const publicar = () => {
    if (!texto.trim() || activos.length === 0) return;
    const nuevo = { id: Date.now(), texto: texto.trim(), canales: activos, fecha: "Hoy", img: conImg };
    setPosts([nuevo, ...posts]);
    setTexto("");
    setFlash("✓ Publicado en: " + activos.map((c) => ({ web: "Web", fb: "Facebook", ig: "Instagram" }[c])).join(", "));
    setTimeout(() => setFlash(""), 3500);
  };

  return (
    <div className="view">
      <div className="pub-grid">
        {/* composer */}
        <div className="panel pad">
          <div className="panel-h" style={{ padding: 0, border: "none", marginBottom: 16 }}><h3>Nueva publicación</h3></div>
          <div className="frm">
            <div className="one">
              <label>Texto de la publicación</label>
              <textarea rows="5" value={texto} onChange={(e) => setTexto(e.target.value)} placeholder="Escribe la novedad del club o del banco ortopédico..."></textarea>
            </div>
            <div className="one">
              <label>Imagen</label>
              <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <button className={"sw" + (conImg ? " on" : "")} onClick={() => setConImg(!conImg)}></button>
                <span style={{ fontSize: 14, color: "var(--ink-soft)" }}>{conImg ? "Adjuntar imagen" : "Sin imagen"}</span>
              </div>
            </div>
            <div className="one">
              <label>Publicar en</label>
              <div className="chan">
                <button className={"chan-btn" + (canales.web ? " on" : "")} onClick={() => toggleCh("web")}><span className="ch" style={{ background: "var(--azure)" }}>W</span> Sitio web</button>
                <button className={"chan-btn" + (canales.fb ? " on" : "")} onClick={() => toggleCh("fb")}><span className="ch" style={{ background: "#1877f2" }}>f</span> Facebook</button>
                <button className={"chan-btn" + (canales.ig ? " on" : "")} onClick={() => toggleCh("ig")}><span className="ch" style={{ background: "#d6249f" }}>◎</span> Instagram</button>
              </div>
            </div>
            {flash && <div style={{ background: "#dcf3e8", color: "#0a7c52", padding: "11px 14px", borderRadius: 10, fontSize: 14, fontWeight: 600, marginBottom: 14 }}>{flash}</div>}
            <button className="btn btn-gold btn-lg" style={{ width: "100%", justifyContent: "center" }} onClick={publicar} disabled={!texto.trim() || activos.length === 0}>
              Publicar {activos.length > 0 ? "en " + activos.length + " canal" + (activos.length > 1 ? "es" : "") : ""}
            </button>
          </div>
        </div>
        {/* preview */}
        <div>
          <label className="frm" style={{ display: "block", fontSize: 13, fontWeight: 700, color: "var(--ink-soft)", marginBottom: 8 }}>Vista previa</label>
          <div className="preview">
            <div className="ph"><div className="av">R</div><div><b style={{ fontSize: 14 }}>Rotary Lascano</b><div style={{ fontSize: 12, color: "var(--muted)" }}>{activos.length ? activos.map((c) => ({ web: "Web", fb: "Facebook", ig: "Instagram" }[c])).join(" · ") : "Sin canal"}</div></div></div>
            {conImg && <div className="imgph pimg"><span>imagen de la publicación</span></div>}
            <div className="pb">{texto || "El texto de tu publicación aparecerá acá…"}</div>
          </div>
        </div>
      </div>

      <Panel title="Publicaciones recientes">
        {posts.map((p) => (
          <div className="post-row" key={p.id}>
            {p.img && <div className="imgph pimg"><span>img</span></div>}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 14, color: "var(--ink)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.texto}</div>
              <div style={{ fontSize: 12.5, color: "var(--muted)", marginTop: 4 }}>{p.fecha}</div>
            </div>
            <div className="chips">{p.canales.map((c) => <ChannelChip c={c} key={c} />)}</div>
          </div>
        ))}
      </Panel>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* TESORERÍA                                                           */
/* ------------------------------------------------------------------ */
function Tesoreria() {
  const COLORS = ['#0050a2','#019fcb','#17458f','#009999','#f7a81b','#d41367','#872175','#ff7600'];
  const [mes, setMes]     = useState('2026-06');
  const [fijos, setFijos] = useState([
    { id:'f1', cat:'UTE',     desc:'Energía eléctrica',   monto:'' },
    { id:'f2', cat:'OSE',     desc:'Agua',                monto:'' },
    { id:'f3', cat:'Antel',   desc:'Telefonía / Internet', monto:'' },
    { id:'f4', cat:'Sueldos', desc:'',                    monto:'' },
  ]);
  const [vars,  setVars]  = useState([
    { id:'v1', cat:'Donaciones', desc:'', monto:'' },
    { id:'v2', cat:'Florería',   desc:'', monto:'' },
    { id:'v3', cat:'Regalos',    desc:'', monto:'' },
  ]);
  const [docs,  setDocs]  = useState([]);
  const [proc,  setProc]  = useState(false);
  const [drag,  setDrag]  = useState(false);
  const [flash, setFlash] = useState('');
  const pieRef = useRef(null), barRef = useRef(null);
  const pieI   = useRef(null), barI   = useRef(null);

  const all  = [...fijos, ...vars];
  const vals = all.map(i => parseFloat(i.monto) || 0);
  const total = vals.reduce((a, b) => a + b, 0);
  const fmt = n => '$ ' + n.toLocaleString('es-UY');

  useEffect(() => {
    const C = window.Chart;
    if (!C || !pieRef.current || !barRef.current) return;
    if (pieI.current) { pieI.current.destroy(); pieI.current = null; }
    if (barI.current) { barI.current.destroy(); barI.current = null; }
    if (total === 0) return;
    const labels = all.map(i => i.cat);
    pieI.current = new C(pieRef.current, {
      type: 'doughnut',
      data: { labels, datasets: [{ data: vals, backgroundColor: COLORS, borderWidth: 2, borderColor: '#fff' }] },
      options: { maintainAspectRatio: false, cutout: '65%',
        plugins: { legend: { position: 'right', labels: { boxWidth: 11, font: { size: 11, family: "'Open Sans',sans-serif" } } } } }
    });
    barI.current = new C(barRef.current, {
      type: 'bar',
      data: { labels, datasets: [{ label: 'Gastos', data: vals, backgroundColor: COLORS, borderRadius: 6, borderSkipped: false }] },
      options: { maintainAspectRatio: false, plugins: { legend: { display: false } },
        scales: { x: { grid: { display: false }, ticks: { font: { size: 11 } } }, y: { grid: { color: '#e9eef5' }, ticks: { font: { size: 11 } } } } }
    });
    return () => {
      if (pieI.current) { pieI.current.destroy(); pieI.current = null; }
      if (barI.current) { barI.current.destroy(); barI.current = null; }
    };
  }, [fijos, vars]);

  const handleFile = file => {
    setProc(true);
    setTimeout(() => {
      const mock = { UTE: (Math.random()*800+900).toFixed(0), Antel: (Math.random()*400+600).toFixed(0), OSE: (Math.random()*120+180).toFixed(0) };
      setFijos(prev => prev.map(f => mock[f.cat] ? { ...f, monto: mock[f.cat] } : f));
      setDocs(prev => [...prev, { name: file.name, txn: Object.keys(mock).length }]);
      setFlash('✓ ' + Object.keys(mock).length + ' transacciones extraídas de "' + file.name + '"');
      setTimeout(() => setFlash(''), 4500);
      setProc(false);
    }, 2200);
  };

  const updF = (id,k,v) => setFijos(p => p.map(f => f.id===id ? {...f,[k]:v} : f));
  const updV = (id,k,v) => setVars(p  => p.map(x => x.id===id ? {...x,[k]:v} : x));

  return (
    <div className="view">
      <style>{`@keyframes spin{to{transform:rotate(360deg)}}.tsp{animation:spin 1s linear infinite}`}</style>

      {/* KPIs */}
      <div className="kpis" style={{ gridTemplateColumns:'repeat(3,1fr)', marginBottom:22 }}>
        <div className="kpi"><div className="ico" style={{background:'#eaf2fb',color:'var(--azure)'}}>💰</div>
          <b>{fmt(total)}</b><span>Total del mes</span></div>
        <div className="kpi"><div className="ico" style={{background:'#fdf0d6',color:'var(--gold-deep)'}}>🔒</div>
          <b>{fmt(fijos.reduce((a,f)=>a+(parseFloat(f.monto)||0),0))}</b><span>Gastos fijos</span></div>
        <div className="kpi"><div className="ico" style={{background:'#fbdfe4',color:'#b0123e'}}>📊</div>
          <b>{fmt(vars.reduce((a,v)=>a+(parseFloat(v.monto)||0),0))}</b><span>Gastos variables</span></div>
      </div>

      {/* Período */}
      <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:22 }}>
        <span style={{ fontWeight:700, fontSize:12, letterSpacing:'.1em', textTransform:'uppercase', color:'var(--muted)' }}>Período</span>
        <input type="month" value={mes} onChange={e => setMes(e.target.value)}
          style={{ border:'1.5px solid var(--line)', borderRadius:10, padding:'8px 12px', fontFamily:'var(--font)', fontSize:14, color:'var(--ink)', background:'#fff' }} />
      </div>

      {/* Zona de carga */}
      <Panel title="Cargar comprobante o estado bancario" action={<span style={{fontSize:12,color:'var(--muted)'}}>JPG · PNG · PDF</span>}>
        <div style={{ padding:'0 22px 20px' }}>
          <div
            onDragOver={e => { e.preventDefault(); setDrag(true); }}
            onDragLeave={() => setDrag(false)}
            onDrop={e => { e.preventDefault(); setDrag(false); if (e.dataTransfer.files[0]) handleFile(e.dataTransfer.files[0]); }}
            onClick={() => document.getElementById('tFileIn').click()}
            style={{ border:`2px dashed ${drag?'var(--azure)':'var(--line)'}`, borderRadius:14, padding:'32px 24px',
              textAlign:'center', background:drag?'#eaf2fb':'var(--paper)', cursor:'pointer', transition:'all .2s' }}>
            <input id="tFileIn" type="file" accept="image/*,.pdf" style={{ display:'none' }}
              onChange={e => { if (e.target.files[0]) handleFile(e.target.files[0]); e.target.value=''; }} />
            {proc ? (
              <div>
                <div className="tsp" style={{ width:44, height:44, border:'4px solid var(--line)', borderTopColor:'var(--azure)', borderRadius:'50%', margin:'0 auto 14px' }}></div>
                <b style={{ color:'var(--azure)' }}>Procesando documento…</b>
                <p style={{ fontSize:13, color:'var(--muted)', marginTop:6 }}>Extrayendo y clasificando transacciones</p>
              </div>
            ) : (
              <React.Fragment>
                <div style={{ fontSize:40, marginBottom:10 }}>📄</div>
                <b>Arrastrar o hacer clic para subir</b>
                <p style={{ fontSize:13, color:'var(--muted)', marginTop:6 }}>Facturas, capturas o extractos bancarios en PDF</p>
              </React.Fragment>
            )}
          </div>
          {flash && <div style={{ background:'#dcf3e8', color:'#0a7c52', padding:'11px 14px', borderRadius:10, fontSize:14, fontWeight:600, marginTop:12 }}>{flash}</div>}
          {docs.length > 0 && (
            <div style={{ marginTop:14, display:'grid', gap:8 }}>
              {docs.map((d,i) => (
                <div key={i} style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', background:'var(--paper-2)', borderRadius:10 }}>
                  <span style={{ fontSize:20 }}>📎</span>
                  <span style={{ flex:1, fontSize:14, fontWeight:600 }}>{d.name}</span>
                  <span className="badge ok">{d.txn} transacciones</span>
                </div>
              ))}
            </div>
          )}
        </div>
      </Panel>

      {/* Grilla de gastos */}
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:20, marginBottom:22 }}>
        <Panel title="Gastos fijos">
          {fijos.map(f => (
            <div key={f.id} style={{ display:'grid', gridTemplateColumns:'1fr 120px', gap:12, padding:'13px 22px', borderBottom:'1px solid var(--line-soft)', alignItems:'center' }}>
              <div>
                <div style={{ fontSize:11, letterSpacing:'.1em', textTransform:'uppercase', color:'var(--azure)', fontWeight:800 }}>{f.cat}</div>
                <input value={f.desc} onChange={e => updF(f.id,'desc',e.target.value)}
                  placeholder="Descripción" style={{ border:'none', background:'transparent', fontSize:13, color:'var(--ink-soft)', width:'100%', fontFamily:'var(--font)', marginTop:2 }} />
              </div>
              <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                <span style={{ color:'var(--muted)', fontSize:13, flexShrink:0 }}>$</span>
                <input type="number" value={f.monto} onChange={e => updF(f.id,'monto',e.target.value)}
                  placeholder="0" style={{ border:'1.5px solid var(--line)', borderRadius:8, padding:'6px 9px', fontSize:14, width:'100%', fontFamily:'var(--font)', color:'var(--ink)' }} />
              </div>
            </div>
          ))}
        </Panel>
        <Panel title="Gastos variables" action={<button className="btn btn-ghost btn-sm" onClick={() => setVars(p => [...p, { id:'v'+Date.now(), cat:'Otro', desc:'', monto:'' }])}>+ Agregar</button>}>
          {vars.map(v => (
            <div key={v.id} style={{ display:'grid', gridTemplateColumns:'1fr 110px 30px', gap:8, padding:'13px 22px', borderBottom:'1px solid var(--line-soft)', alignItems:'center' }}>
              <input value={v.cat} onChange={e => updV(v.id,'cat',e.target.value)}
                style={{ border:'1.5px solid var(--line)', borderRadius:8, padding:'6px 10px', fontSize:13, fontFamily:'var(--font)', color:'var(--azure)', fontWeight:700 }} />
              <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                <span style={{ color:'var(--muted)', fontSize:13, flexShrink:0 }}>$</span>
                <input type="number" value={v.monto} onChange={e => updV(v.id,'monto',e.target.value)}
                  placeholder="0" style={{ border:'1.5px solid var(--line)', borderRadius:8, padding:'6px 9px', fontSize:14, width:'100%', fontFamily:'var(--font)', color:'var(--ink)' }} />
              </div>
              <button className="icon-btn" style={{ fontSize:18, lineHeight:1 }} onClick={() => setVars(p => p.filter(x => x.id !== v.id))}>×</button>
            </div>
          ))}
        </Panel>
      </div>

      {/* Gráficos */}
      <Panel title="Gráficos de gastos">
        <div style={{ padding:22, display:'grid', gridTemplateColumns:'1fr 1.5fr', gap:28, alignItems:'center' }}>
          <div>
            <div style={{ fontSize:11, fontWeight:700, letterSpacing:'.1em', textTransform:'uppercase', color:'var(--muted)', marginBottom:12 }}>Por categoría</div>
            <div style={{ position:'relative', height:220 }}>
              <canvas ref={pieRef}></canvas>
              {total === 0 && <div style={{ position:'absolute', inset:0, display:'grid', placeItems:'center', color:'var(--muted)', fontSize:13, textAlign:'center', background:'var(--paper)', borderRadius:8 }}>Ingresa montos<br/>para ver el gráfico</div>}
            </div>
          </div>
          <div>
            <div style={{ fontSize:11, fontWeight:700, letterSpacing:'.1em', textTransform:'uppercase', color:'var(--muted)', marginBottom:12 }}>Desglose por rubro</div>
            <div style={{ position:'relative', height:220 }}>
              <canvas ref={barRef}></canvas>
              {total === 0 && <div style={{ position:'absolute', inset:0, display:'grid', placeItems:'center', color:'var(--muted)', fontSize:13, textAlign:'center', background:'var(--paper)', borderRadius:8 }}>Ingresa montos<br/>para ver el gráfico</div>}
            </div>
          </div>
        </div>
      </Panel>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* MODAL genérico — crea registros reales vía API                     */
/* ------------------------------------------------------------------ */
function Modal({ tipo, onClose, onSaved }) {
  const titulos = { articulo: "Nuevo artículo", prestamo: "Nuevo préstamo", reparacion: "Enviar a reparación", usuario: "Nuevo usuario", noticia: "Nueva noticia", evento: "Nuevo evento" };
  const [form, setForm] = useState({});
  const [arts, setArts] = useState([]);
  const [err, setErr] = useState("");
  const set = (k) => (e) => setForm({ ...form, [k]: e.target.value });

  useEffect(() => {
    if (tipo === "prestamo" || tipo === "reparacion") {
      window.RotaryAPI.get("/articulos/admin").then(setArts).catch(() => {});
    }
  }, [tipo]);

  const guardar = () => {
    setErr("");
    let path, body;
    if (tipo === "articulo") {
      path = "/articulos";
      body = {
        nombre: form.nombre, unidad: form.unidad || "Unidad",
        stock_total: parseInt(form.stock_total || 0, 10),
        stock_disponible: parseInt(form.stock_disponible || form.stock_total || 0, 10),
        visible_publico: form.visible_publico !== "No",
      };
    } else if (tipo === "prestamo") {
      path = "/prestamos";
      body = {
        articulo_id: parseInt(form.articulo_id, 10),
        cantidad: parseInt(form.cantidad || 1, 10),
        persona_nombre: form.persona_nombre,
        persona_ci: form.persona_ci || null,
        persona_telefono: form.persona_telefono || null,
        persona_mail: form.persona_mail || null,
        fecha_inicio: form.fecha_inicio,
      };
    } else if (tipo === "usuario") {
      path = "/usuarios";
      body = { nombre: form.nombre, email: form.email, password: form.password, rol: form.rol || "admin" };
    } else if (tipo === "reparacion") {
      path = "/reparaciones";
      body = {
        articulo_id: parseInt(form.articulo_id, 10),
        fecha_entrada: form.fecha_entrada,
        responsable_nombre: form.responsable_nombre,
        costo: form.costo ? parseFloat(form.costo) : null,
        notas: form.notas || null,
      };
    } else if (tipo === "noticia") {
      path = "/noticias";
      body = {
        titulo: form.titulo, fecha: form.fecha,
        resumen: form.resumen || "", imagen_url: form.imagen_url || null,
        cuerpo: form.cuerpo || null, publicado: form.publicado !== "No",
      };
    } else if (tipo === "evento") {
      path = "/agenda";
      body = {
        titulo: form.titulo, fecha: form.fecha,
        hora: form.hora || null, lugar: form.lugar || null,
        descripcion: form.descripcion || null, publicado: form.publicado !== "No",
      };
    }
    window.RotaryAPI.post(path, body).then(() => onSaved()).catch((e) => setErr(e.message || "Error al guardar"));
  };

  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal frm" onClick={(e) => e.stopPropagation()}>
        <div className="modal-h"><h3>{titulos[tipo]}</h3><button className="x" onClick={onClose}>×</button></div>
        <div className="modal-b">
          {tipo === "articulo" && (<>
            <div className="one"><label>Nombre *</label><input value={form.nombre || ""} onChange={set("nombre")} placeholder="Ej. Silla de ruedas" /></div>
            <div className="row"><div><label>Unidad *</label><input value={form.unidad || ""} onChange={set("unidad")} placeholder="Unidad / Par" /></div><div><label>Stock total *</label><input type="number" value={form.stock_total || ""} onChange={set("stock_total")} placeholder="0" /></div></div>
            <div className="row"><div><label>Stock disponible *</label><input type="number" value={form.stock_disponible || ""} onChange={set("stock_disponible")} placeholder="0" /></div><div><label>Visible en portal</label><select value={form.visible_publico || "Sí"} onChange={set("visible_publico")}><option>Sí</option><option>No</option></select></div></div>
          </>)}
          {tipo === "prestamo" && (<>
            <div className="one"><label>Artículo *</label><select value={form.articulo_id || ""} onChange={set("articulo_id")}><option value="">Seleccionar…</option>{arts.map((a) => <option key={a.id} value={a.id}>{a.nombre} ({a.stock_disponible} disp.)</option>)}</select></div>
            <div className="row"><div><label>Cantidad *</label><input type="number" value={form.cantidad || ""} onChange={set("cantidad")} placeholder="1" /></div><div><label>Fecha inicio *</label><input type="date" value={form.fecha_inicio || ""} onChange={set("fecha_inicio")} /></div></div>
            <div className="one"><label>Nombre de la persona *</label><input value={form.persona_nombre || ""} onChange={set("persona_nombre")} placeholder="Nombre y apellido" /></div>
            <div className="row"><div><label>Cédula de identidad</label><input value={form.persona_ci || ""} onChange={set("persona_ci")} placeholder="x.xxx.xxx-x" /></div><div><label>Teléfono</label><input value={form.persona_telefono || ""} onChange={set("persona_telefono")} placeholder="09x xxx xxx" /></div></div>
            <div className="one"><label>Correo (para recordatorios)</label><input type="email" value={form.persona_mail || ""} onChange={set("persona_mail")} placeholder="correo@ejemplo.com" /></div>
          </>)}
          {tipo === "reparacion" && (<>
            <div className="one"><label>Artículo *</label><select value={form.articulo_id || ""} onChange={set("articulo_id")}><option value="">Seleccionar…</option>{arts.map((a) => <option key={a.id} value={a.id}>{a.nombre}</option>)}</select></div>
            <div className="row"><div><label>Fecha de entrada *</label><input type="date" value={form.fecha_entrada || ""} onChange={set("fecha_entrada")} /></div><div><label>Costo estimado</label><input value={form.costo || ""} onChange={set("costo")} placeholder="0" /></div></div>
            <div className="one"><label>Responsable / Taller *</label><input value={form.responsable_nombre || ""} onChange={set("responsable_nombre")} placeholder="Nombre del taller" /></div>
            <div className="one"><label>Notas</label><textarea rows="2" value={form.notas || ""} onChange={set("notas")}></textarea></div>
          </>)}
          {tipo === "usuario" && (<>
            <div className="one"><label>Nombre *</label><input value={form.nombre || ""} onChange={set("nombre")} placeholder="Nombre completo" /></div>
            <div className="one"><label>Email *</label><input type="email" value={form.email || ""} onChange={set("email")} placeholder="correo@ejemplo.com" /></div>
            <div className="row"><div><label>Contraseña *</label><input type="password" value={form.password || ""} onChange={set("password")} placeholder="••••••••" /></div>
              <div><label>Rol *</label><select value={form.rol || "admin"} onChange={set("rol")}><option value="consulta">consulta — solo lectura</option><option value="admin">admin — gestión</option><option value="superadmin">superadmin — acceso total</option></select></div></div>
          </>)}
          {tipo === "noticia" && (<>
            <div className="row"><div><label>Título *</label><input value={form.titulo || ""} onChange={set("titulo")} placeholder="Título de la noticia" /></div><div><label>Fecha *</label><input type="date" value={form.fecha || ""} onChange={set("fecha")} /></div></div>
            <div className="one"><label>Resumen</label><textarea rows="2" value={form.resumen || ""} onChange={set("resumen")}></textarea></div>
            <div className="one"><label>URL de imagen</label><input value={form.imagen_url || ""} onChange={set("imagen_url")} placeholder="assets/noticia-freezer.jpg o https://…" /></div>
            <div className="row"><div><label>Cuerpo</label><textarea rows="2" value={form.cuerpo || ""} onChange={set("cuerpo")}></textarea></div><div><label>Publicado</label><select value={form.publicado || "Sí"} onChange={set("publicado")}><option>Sí</option><option>No</option></select></div></div>
          </>)}
          {tipo === "evento" && (<>
            <div className="row"><div><label>Título *</label><input value={form.titulo || ""} onChange={set("titulo")} placeholder="Título del evento" /></div><div><label>Fecha *</label><input type="date" value={form.fecha || ""} onChange={set("fecha")} /></div></div>
            <div className="row"><div><label>Hora</label><input value={form.hora || ""} onChange={set("hora")} placeholder="20:00 h" /></div><div><label>Lugar</label><input value={form.lugar || ""} onChange={set("lugar")} placeholder="Casa Rotaria" /></div></div>
            <div className="row"><div><label>Descripción</label><textarea rows="2" value={form.descripcion || ""} onChange={set("descripcion")}></textarea></div><div><label>Publicado</label><select value={form.publicado || "Sí"} onChange={set("publicado")}><option>Sí</option><option>No</option></select></div></div>
          </>)}
          {err && <div style={{ color: "var(--cranberry)", fontSize: 13, marginTop: 8 }}>{err}</div>}
        </div>
        <div className="modal-f">
          <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn btn-azure" onClick={guardar}>Guardar</button>
        </div>
      </div>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* NOTICIAS admin                                                      */
/* ------------------------------------------------------------------ */
function NoticiasAdmin({ openModal }) {
  const [items, setItems] = useState([]);
  const load = () => window.RotaryAPI.get("/noticias/admin").then(setItems).catch(() => {});
  useEffect(() => { load(); }, []);
  const borrar = (id) => window.RotaryAPI.del("/noticias/" + id).then(load);
  return (
    <div className="view">
      <Panel title="Noticias" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("noticia")}>+ Nueva noticia</button>}>
        <table className="tbl">
          <thead><tr><th>Título</th><th>Fecha</th><th>Publicado</th><th></th></tr></thead>
          <tbody>
            {items.map((n) => (
              <tr key={n.id}><td style={{ fontWeight: 600 }}>{n.titulo}</td><td>{n.fecha}</td>
                <td><span className={"badge " + (n.publicado ? "ok" : "warn")}>{n.publicado ? "sí" : "no"}</span></td>
                <td style={{ textAlign: "right" }}><button className="icon-btn" onClick={() => borrar(n.id)}>🗑</button></td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* AGENDA admin                                                        */
/* ------------------------------------------------------------------ */
function AgendaAdmin({ openModal }) {
  const [items, setItems] = useState([]);
  const load = () => window.RotaryAPI.get("/agenda/admin").then(setItems).catch(() => {});
  useEffect(() => { load(); }, []);
  const borrar = (id) => window.RotaryAPI.del("/agenda/" + id).then(load);
  return (
    <div className="view">
      <Panel title="Agenda" action={<button className="btn btn-azure btn-sm" onClick={() => openModal("evento")}>+ Nuevo evento</button>}>
        <table className="tbl">
          <thead><tr><th>Título</th><th>Fecha</th><th>Lugar</th><th>Publicado</th><th></th></tr></thead>
          <tbody>
            {items.map((e) => (
              <tr key={e.id}><td style={{ fontWeight: 600 }}>{e.titulo}</td><td>{e.fecha}</td><td>{e.lugar || "—"}</td>
                <td><span className={"badge " + (e.publicado ? "ok" : "warn")}>{e.publicado ? "sí" : "no"}</span></td>
                <td style={{ textAlign: "right" }}><button className="icon-btn" onClick={() => borrar(e.id)}>🗑</button></td></tr>
            ))}
          </tbody>
        </table>
      </Panel>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* APP                                                                 */
/* ------------------------------------------------------------------ */
const NAV = [
  { sec: "Gestión", items: [
    { id: "dashboard", ico: "▦", label: "Dashboard" },
    { id: "articulos", ico: "📦", label: "Artículos" },
    { id: "prestamos", ico: "🤝", label: "Préstamos" },
    { id: "personas", ico: "👥", label: "Personas" },
    { id: "reparacion", ico: "🛠", label: "En Reparación" },
  ]},
  { sec: "Comunicación", items: [
    { id: "publicaciones", ico: "📣", label: "Publicaciones", tag: "Web+Redes" },
    { id: "noticias", ico: "📰", label: "Noticias" },
    { id: "agenda", ico: "📅", label: "Agenda" },
  ]},
  { sec: "Tesorería", items: [
    { id: "tesoreria", ico: "💰", label: "Tesorería" },
  ]},
  { sec: "Sistema", items: [
    { id: "usuarios", ico: "🔑", label: "Usuarios" },
  ]},
];
const TITULOS = { dashboard: "Dashboard", articulos: "Artículos", prestamos: "Préstamos", personas: "Personas", reparacion: "En Reparación", publicaciones: "Publicaciones", tesoreria: "Tesorería", usuarios: "Usuarios", noticias: "Noticias", agenda: "Agenda" };

function App() {
  const [user, setUser] = useState(null);
  const [view, setView] = useState("dashboard");
  const [modal, setModal] = useState(null);
  const [sideOpen, setSideOpen] = useState(false);
  const [reloadKey, setReloadKey] = useState(0);

  useEffect(() => {
    if (window.RotaryAPI.token()) {
      window.RotaryAPI.me().then((u) => setUser(u.email)).catch(() => window.RotaryAPI.clearToken());
    }
  }, []);

  const logout = () => { window.RotaryAPI.clearToken(); setUser(null); };

  if (!user) return <Login onEnter={setUser} />;

  const go = (v) => { setView(v); setSideOpen(false); };

  return (
    <div className="app">
      <aside className={"side" + (sideOpen ? " open" : "")}>
        <div className="side-logo"><img src="../assets/logo-rotary-lascano.jpg" alt="Rotary" /></div>
        {NAV.map((g) => (
          <React.Fragment key={g.sec}>
            <div className="side-label">{g.sec}</div>
            {g.items.map((it) => (
              <button key={it.id} className={"nav-item" + (view === it.id ? " active" : "")} onClick={() => go(it.id)}>
                <span className="ico">{it.ico}</span>{it.label}{it.tag && <span className="tag">{it.tag}</span>}
              </button>
            ))}
          </React.Fragment>
        ))}
        <div className="side-foot">
          <a href="portal.html" className="nav-item" style={{ textDecoration: "none" }}><span className="ico">↗</span>Ver portal público</a>
          <button className="nav-item" onClick={logout}><span className="ico">⏻</span>Cerrar sesión</button>
        </div>
      </aside>

      <div className="main">
        <div className="topbar">
          <button className="icon-btn" onClick={() => setSideOpen(!sideOpen)} style={{ }} aria-label="menú">☰</button>
          <h2>{TITULOS[view]}</h2>
          <div className="right">
            <span style={{ fontSize: 13.5, color: "var(--muted)", fontWeight: 600 }} className="hide-sm">Casa Rotaria de Lascano</span>
            <div className="avatar">{(user[0] || "R").toUpperCase()}</div>
          </div>
        </div>

        {view === "dashboard" && <Dashboard key={"dashboard" + reloadKey} go={go} />}
        {view === "articulos" && <Articulos key={"articulos" + reloadKey} openModal={setModal} />}
        {view === "prestamos" && <Prestamos key={"prestamos" + reloadKey} openModal={setModal} />}
        {view === "personas" && <Personas key={"personas" + reloadKey} />}
        {view === "reparacion" && <Reparacion key={"reparacion" + reloadKey} openModal={setModal} />}
        {view === "publicaciones" && <Publicaciones />}
        {view === "tesoreria" && <Tesoreria />}
        {view === "usuarios" && <Usuarios key={"usuarios" + reloadKey} openModal={setModal} />}
        {view === "noticias" && <NoticiasAdmin key={"noticias" + reloadKey} openModal={setModal} />}
        {view === "agenda" && <AgendaAdmin key={"agenda" + reloadKey} openModal={setModal} />}
      </div>

      {modal && <Modal tipo={modal} onClose={() => setModal(null)} onSaved={() => { setModal(null); setReloadKey((k) => k + 1); }} />}
    </div>
  );
}

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