/* Fitness — raíz: login (magic link) + shell + vistas. Registro de entrenos según
   la planilla: sesiones con estado previo, ejercicios con plan y sets reales,
   biblioteca de ejercicios y medidas corporales. Mismo formato que Proyectos. */
const { useState, useEffect, useRef } = React;

const MESES = ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'];
const fmtFecha = (s) => { const p = String(s || '').slice(0, 10).split('-'); return p.length === 3 ? (+p[2]) + ' ' + MESES[(+p[1]) - 1] + ' ' + p[0] : (s || ''); };
const hoyISO = () => new Date().toISOString().slice(0, 10);

// Modal reutilizable (mismo que Finanzas/Proyectos).
function Modal({ titulo, onClose, children, ancho }) {
  useEffect(() => { const h = (e) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', h); return () => document.removeEventListener('keydown', h); }, [onClose]);
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={ancho ? { maxWidth: ancho } : undefined} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head"><h3>{titulo}</h3><button className="x" onClick={onClose} title="Cerrar"><Icon name="x" size={18} /></button></div>
        <div className="modal-body">{children}</div>
      </div>
    </div>
  );
}

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' }}>Fitness</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 olive" style={{ display: 'inline-flex', padding: '10px 14px' }}><Icon name="check" size={14} /> Revisá tu correo: enlace enviado a {email}.</div>
        ) : (
          <form onSubmit={enviar}>
            <input type="email" required value={email} onChange={e => setEmail(e.target.value)} placeholder="tu@correo.cl" autoFocus
              style={{ width: '100%', padding: '11px 13px', borderRadius: 12, border: '1px solid var(--line)', background: 'var(--card-elev)', color: 'var(--ink)', fontSize: 14, 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 AppSwitcher({ onClose }) {
  const cfg = window.SUITE_APPS || { actual: '', apps: [] };
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 40 }} />
      <div className="app-switch">
        <div className="app-switch-h">Cambiar de app</div>
        {cfg.apps.map((a) => {
          const actual = a.id === cfg.actual;
          return (
            <button key={a.id} className={'app-switch-item' + (actual ? ' on' : '')} onClick={() => { if (actual) { onClose(); return; } window.irApp(a.url); }}>
              <span className="mk2">{a.mark}</span>
              <span style={{ flex: 1, textAlign: 'left' }}>{a.label}</span>
              {actual && <Icon name="check" size={14} />}
            </button>
          );
        })}
      </div>
    </>
  );
}

function NavBtn({ n, active, onNav }) {
  return (
    <button className={'nav-item ' + (active ? 'active' : '')} onClick={() => onNav(n.id)} title={n.label} style={{ padding: '9px 12px' }}>
      <Icon name={n.icon} size={17} /> <span style={{ flex: 1, textAlign: 'left' }}>{n.label}</span>
    </button>
  );
}

function Campo({ label, span, children }) {
  return <label className="field" style={span ? { gridColumn: '1 / -1' } : null}><span>{label}</span>{children}</label>;
}

// Escala 1-10 compacta para el estado previo.
function Escala({ label, value, onChange }) {
  return (
    <div className="field"><span>{label}{value != null ? ' · ' + value : ''}</span>
      <input type="range" min="1" max="10" value={value || 5} onChange={(e) => onChange(Number(e.target.value))} />
    </div>
  );
}

// ── Formulario de sesión (crear/editar) ──────────────────────────────────────
function FormSesion({ inicial, onGuardado, onCancelar }) {
  const [f, setF] = useState(inicial || { fecha: hoyISO(), objetivo: '', fatiga: 3, doms: 2, motivacion: 7, sueno_horas: '', sueno_calidad: 'Regular', calentamiento: '', duracion_min: '', notas: '' });
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));
  const guardar = async (e) => {
    e.preventDefault(); if (busy) return; setBusy(true); setErr('');
    try {
      const path = inicial && inicial.id ? `/api/fitness/sesiones/${inicial.id}` : '/api/fitness/sesiones';
      const method = inicial && inicial.id ? 'PUT' : 'POST';
      const r = await window.api(path, { method, body: JSON.stringify(f) });
      onGuardado(r);
    } catch (ex) { setErr(ex.message); setBusy(false); }
  };
  return (
    <form className="form-sheet" onSubmit={guardar}>
      <div className="form-grid c2">
        <Campo label="Fecha"><input type="date" value={f.fecha || ''} onChange={(e) => set('fecha', e.target.value)} /></Campo>
        <Campo label="Objetivo de la sesión"><input value={f.objetivo || ''} onChange={(e) => set('objetivo', e.target.value)} placeholder="Ej: Tren superior (Push)" /></Campo>
      </div>
      <div className="sec-head" style={{ margin: '4px 0 0' }}><h3>Estado previo</h3></div>
      <div className="form-grid c3">
        <Escala label="Fatiga" value={f.fatiga} onChange={(v) => set('fatiga', v)} />
        <Escala label="Dolor (DOMS)" value={f.doms} onChange={(v) => set('doms', v)} />
        <Escala label="Motivación" value={f.motivacion} onChange={(v) => set('motivacion', v)} />
      </div>
      <div className="form-grid c3">
        <Campo label="Horas de sueño"><input inputMode="decimal" value={f.sueno_horas || ''} onChange={(e) => set('sueno_horas', e.target.value)} /></Campo>
        <Campo label="Calidad de sueño">
          <select value={f.sueno_calidad || ''} onChange={(e) => set('sueno_calidad', e.target.value)}>
            <option value="Mala">Mala</option><option value="Regular">Regular</option><option value="Buena">Buena</option>
          </select>
        </Campo>
        <Campo label="Duración (min)"><input inputMode="numeric" value={f.duracion_min || ''} onChange={(e) => set('duracion_min', e.target.value.replace(/[^\d]/g, ''))} /></Campo>
      </div>
      <Campo label="Calentamiento"><input value={f.calentamiento || ''} onChange={(e) => set('calentamiento', e.target.value)} placeholder="Protocolo / notas" /></Campo>
      <Campo label="Notas"><textarea value={f.notas || ''} onChange={(e) => set('notas', e.target.value)} /></Campo>
      {err && <p className="err-line">{err}</p>}
      <div className="form-actions">
        <button className="btn ghost" type="button" onClick={onCancelar}>Cancelar</button>
        <button className="btn olive" type="submit" disabled={busy}>{busy ? 'Guardando…' : 'Guardar sesión'}</button>
      </div>
    </form>
  );
}

// ── Lista de sesiones (Entrenos) ─────────────────────────────────────────────
function EntrenosView({ onAbrir }) {
  const [sesiones, setSesiones] = useState(null);
  const [crear, setCrear] = useState(false);
  const [err, setErr] = useState('');
  const cargar = () => window.api('/api/fitness/sesiones').then((d) => { setSesiones(d.sesiones || []); setErr(''); }).catch((e) => setErr(e.message));
  useEffect(() => { cargar(); }, []);
  return (
    <div>
      <div className="mkt-head">
        <div><h1 className="proy-h1">Entrenos</h1><p className="proy-sub">Registrá cada sesión: estado previo, ejercicios y sets.</p></div>
        <button className="btn olive" onClick={() => setCrear(true)}><Icon name="plus" size={14} /> Nueva sesión</button>
      </div>
      {crear && <Modal titulo="Nueva sesión" onClose={() => setCrear(false)} ancho={640}>
        <FormSesion onGuardado={(s) => { setCrear(false); cargar(); onAbrir(s.id); }} onCancelar={() => setCrear(false)} />
      </Modal>}
      {err && <div className="card" style={{ padding: 14, color: 'var(--rust)' }}>{err}</div>}
      {sesiones === null ? <p className="hint">Cargando…</p>
        : sesiones.length === 0 ? (
          <div className="card" style={{ padding: 36, textAlign: 'center', maxWidth: 460, margin: '20px auto' }}>
            <div style={{ opacity: .5, marginBottom: 10 }}><Icon name="flame" size={30} /></div>
            <h2 style={{ fontSize: 17, margin: '0 0 6px' }}>Sin entrenos todavía</h2>
            <p className="hint">Creá tu primera sesión para empezar a registrar.</p>
          </div>
        ) : (
          <div className="list">
            {sesiones.map((s) => (
              <button key={s.id} className="row" onClick={() => onAbrir(s.id)} style={{ cursor: 'pointer', textAlign: 'left', font: 'inherit' }}>
                <div style={{ width: 40, height: 40, borderRadius: 10, background: 'var(--olive-tint)', color: 'var(--olive-2)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="flame" size={18} /></div>
                <div className="rmain">
                  <div className="rtitle">{s.objetivo || 'Sesión'}</div>
                  <div className="rsub">{fmtFecha(s.fecha)} · {s.n_ejercicios} ejercicio(s){s.duracion_min ? ' · ' + s.duracion_min + ' min' : ''}</div>
                </div>
                <Icon name="chevronRight" size={16} />
              </button>
            ))}
          </div>
        )}
    </div>
  );
}

// ── Agregar ejercicio a la sesión (busca en biblioteca o texto libre) ─────────
function AgregarEjercicio({ sesionId, orden, onAgregado, onCancelar }) {
  const [q, setQ] = useState('');
  const [res, setRes] = useState([]);
  const [f, setF] = useState({ nombre: '', ejercicio_id: '', series_plan: '', reps_plan: '', peso_plan: '', rir_plan: '', descanso: '', obs: '' });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));
  useEffect(() => {
    if (!q.trim()) { setRes([]); return; }
    let vivo = true; const t = setTimeout(() => {
      window.api('/api/fitness/ejercicios?limit=8&q=' + encodeURIComponent(q.trim())).then((d) => { if (vivo) setRes(d.ejercicios || []); }).catch(() => {});
    }, 220);
    return () => { vivo = false; clearTimeout(t); };
  }, [q]);
  const elegir = (e) => { set('nombre', e.nombre_es); setF((s) => ({ ...s, ejercicio_id: e.id, nombre: e.nombre_es })); setQ(''); setRes([]); };
  const guardar = async (ev) => {
    ev.preventDefault(); if (!f.nombre.trim() || busy) return; setBusy(true);
    try { await window.api(`/api/fitness/sesiones/${sesionId}/ejercicios`, { method: 'POST', body: JSON.stringify({ ...f, orden }) }); onAgregado(); }
    catch (e) { alert(e.message); setBusy(false); }
  };
  return (
    <form className="form-sheet" onSubmit={guardar}>
      <Campo label="Buscar en la biblioteca">
        <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Ej: press inclinado…" autoFocus />
      </Campo>
      {res.length > 0 && (
        <div className="list" style={{ maxHeight: 180, overflowY: 'auto' }}>
          {res.map((e) => (
            <button key={e.id} type="button" className="row" onClick={() => elegir(e)} style={{ cursor: 'pointer', textAlign: 'left', font: 'inherit' }}>
              <div className="rmain"><div className="rtitle">{e.nombre_es}</div><div className="rsub">{[e.grupo_muscular, e.equipo].filter(Boolean).join(' · ')}</div></div>
              <Icon name="plus" size={15} />
            </button>
          ))}
        </div>
      )}
      <Campo label="Ejercicio"><input value={f.nombre} onChange={(e) => set('nombre', e.target.value)} placeholder="Nombre (o elegí uno de arriba)" /></Campo>
      <div className="form-grid c3">
        <Campo label="Series"><input inputMode="numeric" value={f.series_plan} onChange={(e) => set('series_plan', e.target.value.replace(/[^\d]/g, ''))} /></Campo>
        <Campo label="Reps o tiempo"><input value={f.reps_plan} onChange={(e) => set('reps_plan', e.target.value)} placeholder="6 a 10" /></Campo>
        <Campo label="Descanso"><input value={f.descanso} onChange={(e) => set('descanso', e.target.value)} placeholder="2 a 3 min" /></Campo>
      </div>
      <div className="form-grid c2">
        <Campo label="Peso / carga (plan)"><input value={f.peso_plan} onChange={(e) => set('peso_plan', e.target.value)} placeholder="40 KG · 5 Placas · P. Corporal" /></Campo>
        <Campo label="RIR (plan)"><input value={f.rir_plan} onChange={(e) => set('rir_plan', e.target.value)} placeholder="1 a 2" /></Campo>
      </div>
      <Campo label="Observación"><input value={f.obs} onChange={(e) => set('obs', e.target.value)} placeholder="Opcional" /></Campo>
      <div className="form-actions">
        <button className="btn ghost" type="button" onClick={onCancelar}>Cancelar</button>
        <button className="btn olive" type="submit" disabled={busy}>{busy ? 'Guardando…' : 'Agregar'}</button>
      </div>
    </form>
  );
}

// Editor de sets reales de un ejercicio.
function SetsEditor({ ej, onCambio }) {
  const nPlan = Math.max(1, Number(ej.series_plan) || (ej.sets || []).length || 1);
  const init = () => {
    const base = (ej.sets && ej.sets.length) ? ej.sets.map((s) => ({ reps: s.reps || '', peso: s.peso != null ? s.peso : '', rir: s.rir != null ? s.rir : '' })) : [];
    while (base.length < nPlan) base.push({ reps: '', peso: '', rir: '' });
    return base;
  };
  const [sets, setSets] = useState(init);
  const [busy, setBusy] = useState(false);
  const [ok, setOk] = useState(false);
  const upd = (i, k, v) => { setSets((s) => s.map((x, j) => j === i ? { ...x, [k]: v } : x)); setOk(false); };
  const addFila = () => setSets((s) => [...s, { reps: '', peso: '', rir: '' }]);
  const guardar = async () => {
    setBusy(true);
    try {
      const payload = sets.map((s, i) => ({ nro: i + 1, reps: s.reps || null, peso: s.peso === '' ? null : Number(s.peso), rir: s.rir === '' ? null : Number(s.rir) }))
        .filter((s) => s.reps || s.peso != null || s.rir != null);
      await window.api(`/api/fitness/sesion-ejercicios/${ej.id}/sets`, { method: 'PUT', body: JSON.stringify({ sets: payload }) });
      setOk(true); if (onCambio) onCambio();
    } catch (e) { alert(e.message); } finally { setBusy(false); }
  };
  return (
    <div style={{ marginTop: 8 }}>
      <div className="sets-grid">
        <div className="sh">#</div><div className="sh">Reps / tiempo</div><div className="sh">Peso</div><div className="sh">RIR</div>
        {sets.map((s, i) => (
          <React.Fragment key={i}>
            <div className="sn">{i + 1}</div>
            <input className="sc" value={s.reps} onChange={(e) => upd(i, 'reps', e.target.value)} placeholder="—" />
            <input className="sc" inputMode="decimal" value={s.peso} onChange={(e) => upd(i, 'peso', e.target.value)} placeholder="—" />
            <input className="sc" inputMode="decimal" value={s.rir} onChange={(e) => upd(i, 'rir', e.target.value)} placeholder="—" />
          </React.Fragment>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 8, marginTop: 8, alignItems: 'center' }}>
        <button className="add-more" type="button" onClick={addFila}><Icon name="plus" size={12} /> otra serie</button>
        <button className="btn olive" style={{ marginLeft: 'auto', padding: '5px 12px' }} onClick={guardar} disabled={busy}>{busy ? '…' : (ok ? '✓ Guardado' : 'Guardar sets')}</button>
      </div>
    </div>
  );
}

// ── Detalle de una sesión ────────────────────────────────────────────────────
function SesionDetalle({ sesionId, onVolver }) {
  const [s, setS] = useState(null);
  const [err, setErr] = useState('');
  const [agregar, setAgregar] = useState(false);
  const [editSesion, setEditSesion] = useState(false);
  const cargar = () => window.api('/api/fitness/sesiones/' + sesionId).then((d) => { setS(d); setErr(''); }).catch((e) => setErr(e.message));
  useEffect(() => { cargar(); }, [sesionId]);
  const borrarEj = async (ej) => { if (!window.confirm(`¿Quitar "${ej.nombre}"?`)) return; try { await window.api('/api/fitness/sesion-ejercicios/' + ej.id, { method: 'DELETE' }); cargar(); } catch (e) { alert(e.message); } };
  if (err) return <div className="card" style={{ padding: 18, color: 'var(--rust)' }}>{err}</div>;
  if (!s) return <p className="hint">Cargando…</p>;
  const ejs = s.sesion_ejercicios || [];
  const chip = (lab, val) => val != null && val !== '' ? <span className="tag neutral">{lab} {val}</span> : null;
  return (
    <div>
      {onVolver && <button className="btn ghost" onClick={onVolver} style={{ marginBottom: 14 }}><Icon name="chevronLeft" size={14} /> Volver</button>}
      <div className="mkt-head">
        <div>
          <h1 className="proy-h1">{s.objetivo || 'Sesión'}</h1>
          <p className="proy-sub" style={{ margin: 0 }}>{fmtFecha(s.fecha)}</p>
        </div>
        <button className="btn ghost" onClick={() => setEditSesion(true)}><Icon name="edit" size={14} /> Editar</button>
      </div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', margin: '4px 0 18px' }}>
        {chip('Fatiga', s.fatiga)}{chip('DOMS', s.doms)}{chip('Motivación', s.motivacion)}
        {chip('Sueño', s.sueno_horas ? s.sueno_horas + 'h' : null)}{s.sueno_calidad && <span className="tag neutral">{s.sueno_calidad}</span>}
        {chip('Duración', s.duracion_min ? s.duracion_min + ' min' : null)}
      </div>
      {s.calentamiento && <p className="hint" style={{ marginBottom: 14 }}><b>Calentamiento:</b> {s.calentamiento}</p>}

      <div className="sec-head"><h3>Ejercicios</h3><span className="act"><button className="btn ghost" onClick={() => setAgregar(true)}><Icon name="plus" size={14} /> Ejercicio</button></span></div>
      {agregar && <Modal titulo="Agregar ejercicio" onClose={() => setAgregar(false)} ancho={640}>
        <AgregarEjercicio sesionId={sesionId} orden={ejs.length} onAgregado={() => { setAgregar(false); cargar(); }} onCancelar={() => setAgregar(false)} />
      </Modal>}
      {editSesion && <Modal titulo="Editar sesión" onClose={() => setEditSesion(false)} ancho={640}>
        <FormSesion inicial={s} onGuardado={() => { setEditSesion(false); cargar(); }} onCancelar={() => setEditSesion(false)} />
      </Modal>}

      {ejs.length === 0 ? <p className="hint">Sin ejercicios. Agregá el primero.</p> : (
        <div style={{ display: 'grid', gap: 12 }}>
          {ejs.map((ej) => (
            <div key={ej.id} className="card" style={{ padding: 14 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>
                <strong style={{ fontSize: 15 }}>{ej.nombre}</strong>
                <span className="rsub" style={{ marginTop: 0 }}>
                  {[ej.series_plan ? ej.series_plan + ' series' : null, ej.reps_plan, ej.peso_plan, ej.rir_plan ? 'RIR ' + ej.rir_plan : null, ej.descanso].filter(Boolean).join(' · ')}
                </span>
                <button className="icon-btn danger" style={{ marginLeft: 'auto' }} onClick={() => borrarEj(ej)} title="Quitar"><Icon name="x" size={16} /></button>
              </div>
              {ej.obs && <p className="hint" style={{ margin: '4px 0 0' }}>{ej.obs}</p>}
              <SetsEditor ej={ej} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Biblioteca de ejercicios ─────────────────────────────────────────────────
function BibliotecaView() {
  const [q, setQ] = useState('');
  const [grupo, setGrupo] = useState('');
  const [grupos, setGrupos] = useState([]);
  const [ejs, setEjs] = useState(null);
  const [crear, setCrear] = useState(false);
  useEffect(() => { window.api('/api/fitness/ejercicios/grupos').then((d) => setGrupos(d.grupos || [])).catch(() => {}); }, []);
  const cargar = () => {
    const p = new URLSearchParams(); if (q.trim()) p.set('q', q.trim()); if (grupo) p.set('grupo', grupo); p.set('limit', '80');
    window.api('/api/fitness/ejercicios?' + p.toString()).then((d) => setEjs(d.ejercicios || [])).catch(() => setEjs([]));
  };
  useEffect(() => { const t = setTimeout(cargar, 200); return () => clearTimeout(t); }, [q, grupo]);
  return (
    <div>
      <div className="mkt-head">
        <div><h1 className="proy-h1">Biblioteca</h1><p className="proy-sub">Ejercicios de referencia (de tu planilla). Buscá, filtrá y sumá los tuyos.</p></div>
        <button className="btn ghost" onClick={() => setCrear(true)}><Icon name="plus" size={14} /> Ejercicio propio</button>
      </div>
      <div className="mv-frow" style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 14 }}>
        <input className="input" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar ejercicio…" style={{ flex: '1 1 220px' }} />
        <select className="input" value={grupo} onChange={(e) => setGrupo(e.target.value)} style={{ maxWidth: 220 }}>
          <option value="">Todos los grupos</option>
          {grupos.map((g) => <option key={g} value={g}>{g}</option>)}
        </select>
      </div>
      {crear && <Modal titulo="Nuevo ejercicio" onClose={() => setCrear(false)} ancho={560}>
        <FormEjercicio grupos={grupos} onGuardado={() => { setCrear(false); cargar(); }} onCancelar={() => setCrear(false)} />
      </Modal>}
      {ejs === null ? <p className="hint">Cargando…</p> : ejs.length === 0 ? <p className="hint">Nada coincide con la búsqueda.</p> : (
        <div className="list">
          {ejs.map((e) => (
            <div key={e.id} className="row">
              <div className="rmain">
                <div className="rtitle">{e.nombre_es} {e.hogar_id && <span className="tag olive" style={{ fontSize: 10 }}>propio</span>}</div>
                <div className="rsub">{[e.grupo_muscular, e.musculo_principal, e.equipo, e.dificultad].filter(Boolean).join(' · ')}</div>
              </div>
              {e.video_demo && <a className="icon-btn" href={e.video_demo} target="_blank" rel="noreferrer" title="Ver demo"><Icon name="play" size={16} /></a>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function FormEjercicio({ grupos, onGuardado, onCancelar }) {
  const [f, setF] = useState({ nombre_es: '', grupo_muscular: '', musculo_principal: '', equipo: '', dificultad: '', video_demo: '' });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));
  const guardar = async (e) => { e.preventDefault(); if (!f.nombre_es.trim() || busy) return; setBusy(true); try { await window.api('/api/fitness/ejercicios', { method: 'POST', body: JSON.stringify(f) }); onGuardado(); } catch (ex) { alert(ex.message); setBusy(false); } };
  return (
    <form className="form-sheet" onSubmit={guardar}>
      <Campo label="Nombre"><input value={f.nombre_es} autoFocus onChange={(e) => set('nombre_es', e.target.value)} /></Campo>
      <div className="form-grid c2">
        <Campo label="Grupo muscular"><input list="grupos-dl" value={f.grupo_muscular} onChange={(e) => set('grupo_muscular', e.target.value)} /><datalist id="grupos-dl">{(grupos || []).map((g) => <option key={g} value={g} />)}</datalist></Campo>
        <Campo label="Músculo principal"><input value={f.musculo_principal} onChange={(e) => set('musculo_principal', e.target.value)} /></Campo>
      </div>
      <div className="form-grid c2">
        <Campo label="Equipo"><input value={f.equipo} onChange={(e) => set('equipo', e.target.value)} placeholder="Barra, mancuerna…" /></Campo>
        <Campo label="Dificultad">
          <select value={f.dificultad} onChange={(e) => set('dificultad', e.target.value)}>
            <option value="">—</option><option>Principiante</option><option>Intermedio</option><option>Avanzado</option>
          </select>
        </Campo>
      </div>
      <Campo label="Video (URL, opcional)"><input value={f.video_demo} onChange={(e) => set('video_demo', e.target.value)} placeholder="https://…" /></Campo>
      <div className="form-actions">
        <button className="btn ghost" type="button" onClick={onCancelar}>Cancelar</button>
        <button className="btn olive" type="submit" disabled={busy}>{busy ? 'Guardando…' : 'Guardar'}</button>
      </div>
    </form>
  );
}

// ── Medidas corporales ───────────────────────────────────────────────────────
const MEDIDA_CAMPOS = [['peso_kg', 'Peso (kg)'], ['cuello', 'Cuello'], ['cintura', 'Cintura'], ['abdomen', 'Abdomen'], ['cadera', 'Cadera'], ['bajo_ombligo', 'Bajo ombligo'], ['brazo', 'Brazo'], ['muslo', 'Muslo'], ['pliegue_gluteo', 'Pliegue glúteo']];
function MedidasView() {
  const [medidas, setMedidas] = useState(null);
  const [crear, setCrear] = useState(false);
  const cargar = () => window.api('/api/fitness/medidas').then((d) => setMedidas(d.medidas || [])).catch(() => setMedidas([]));
  useEffect(() => { cargar(); }, []);
  const borrar = async (m) => { if (!window.confirm('¿Borrar esta medida?')) return; try { await window.api('/api/fitness/medidas/' + m.id, { method: 'DELETE' }); cargar(); } catch (e) { alert(e.message); } };
  return (
    <div>
      <div className="mkt-head">
        <div><h1 className="proy-h1">Medidas</h1><p className="proy-sub">Peso y contorno corporal para seguir el progreso.</p></div>
        <button className="btn olive" onClick={() => setCrear(true)}><Icon name="plus" size={14} /> Nueva medida</button>
      </div>
      {crear && <Modal titulo="Nueva medida" onClose={() => setCrear(false)} ancho={620}><FormMedida onGuardado={() => { setCrear(false); cargar(); }} onCancelar={() => setCrear(false)} /></Modal>}
      {medidas === null ? <p className="hint">Cargando…</p> : medidas.length === 0 ? <p className="hint">Sin medidas todavía.</p> : (
        <div className="list">
          {medidas.map((m) => (
            <div key={m.id} className="row">
              <div className="rmain">
                <div className="rtitle">{fmtFecha(m.fecha)}{m.peso_kg != null ? ' · ' + m.peso_kg + ' kg' : ''}</div>
                <div className="rsub">{MEDIDA_CAMPOS.slice(1).filter(([k]) => m[k] != null).map(([k, l]) => l + ' ' + m[k]).join(' · ') || 'sólo peso'}</div>
              </div>
              <button className="icon-btn danger" onClick={() => borrar(m)} title="Borrar"><Icon name="x" size={16} /></button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function FormMedida({ onGuardado, onCancelar }) {
  const [f, setF] = useState({ fecha: hoyISO() });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));
  const guardar = async (e) => { e.preventDefault(); if (busy) return; setBusy(true); try { await window.api('/api/fitness/medidas', { method: 'POST', body: JSON.stringify(f) }); onGuardado(); } catch (ex) { alert(ex.message); setBusy(false); } };
  return (
    <form className="form-sheet" onSubmit={guardar}>
      <Campo label="Fecha"><input type="date" value={f.fecha || ''} onChange={(e) => set('fecha', e.target.value)} /></Campo>
      <div className="form-grid c3">
        {MEDIDA_CAMPOS.map(([k, l]) => (
          <Campo key={k} label={l}><input inputMode="decimal" value={f[k] || ''} onChange={(e) => set(k, e.target.value)} /></Campo>
        ))}
      </div>
      <Campo label="Notas"><input value={f.notas || ''} onChange={(e) => set('notas', e.target.value)} placeholder="Opcional" /></Campo>
      <div className="form-actions">
        <button className="btn ghost" type="button" onClick={onCancelar}>Cancelar</button>
        <button className="btn olive" type="submit" disabled={busy}>{busy ? 'Guardando…' : 'Guardar'}</button>
      </div>
    </form>
  );
}

// ── Progreso (peso + entrenos) ───────────────────────────────────────────────
function ProgresoView() {
  const [medidas, setMedidas] = useState(null);
  const [sesiones, setSesiones] = useState([]);
  useEffect(() => {
    window.api('/api/fitness/medidas').then((d) => setMedidas(d.medidas || [])).catch(() => setMedidas([]));
    window.api('/api/fitness/sesiones').then((d) => setSesiones(d.sesiones || [])).catch(() => {});
  }, []);
  if (medidas === null) return <p className="hint">Cargando…</p>;
  const pesos = medidas.filter((m) => m.peso_kg != null).slice().reverse(); // asc
  const vals = pesos.map((m) => Number(m.peso_kg));
  const min = Math.min(...vals, Infinity), max = Math.max(...vals, -Infinity);
  const rango = max - min || 1;
  return (
    <div>
      <h1 className="proy-h1">Progreso</h1>
      <p className="proy-sub">Tu peso en el tiempo y el ritmo de entrenos.</p>
      <div className="rs-tiles" style={{ marginBottom: 24 }}>
        <div className="rs-tile"><div className="lab">Entrenos</div><div className="val">{sesiones.length}</div></div>
        <div className="rs-tile disp"><div className="lab">Peso actual</div><div className="val">{vals.length ? vals[vals.length - 1] + ' kg' : '—'}</div></div>
        <div className="rs-tile"><div className="lab">Medidas</div><div className="val">{medidas.length}</div></div>
        <div className="rs-tile"><div className="lab">Variación</div><div className="val">{vals.length >= 2 ? (vals[vals.length - 1] - vals[0] >= 0 ? '+' : '') + (vals[vals.length - 1] - vals[0]).toFixed(1) + ' kg' : '—'}</div></div>
      </div>
      {pesos.length >= 2 ? (
        <div className="card" style={{ padding: 18 }}>
          <div className="rs-sec" style={{ marginBottom: 12 }}><h2>Peso corporal</h2></div>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, height: 160 }}>
            {pesos.map((m, i) => {
              const h = 12 + ((Number(m.peso_kg) - min) / rango) * 130;
              return (
                <div key={i} title={fmtFecha(m.fecha) + ': ' + m.peso_kg + ' kg'} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, justifyContent: 'flex-end' }}>
                  <span style={{ fontSize: 10, fontFamily: 'var(--mono)', color: 'var(--ink-4)' }}>{m.peso_kg}</span>
                  <div style={{ width: '100%', maxWidth: 34, height: h, background: 'var(--olive)', borderRadius: '6px 6px 3px 3px' }} />
                </div>
              );
            })}
          </div>
        </div>
      ) : <p className="hint">Cargá al menos dos medidas de peso para ver la curva.</p>}
    </div>
  );
}

// ── Hoy: el entreno del día (estado previo + calentamiento + planificación) ──
function HoyView({ onAbrir, onSetear }) {
  const [sesiones, setSesiones] = useState(null);
  const [crear, setCrear] = useState(false);
  const cargar = () => window.api('/api/fitness/sesiones').then((d) => setSesiones(d.sesiones || [])).catch(() => setSesiones([]));
  useEffect(() => { cargar(); }, []);
  if (sesiones === null) return <p className="hint">Cargando…</p>;
  const today = hoyISO();
  const hoy = sesiones.find((s) => (s.fecha || '').slice(0, 10) === today) || sesiones[0] || null;
  const otros = sesiones.filter((s) => !hoy || s.id !== hoy.id);
  return (
    <div>
      <div className="mkt-head">
        <div><h1 className="proy-h1">Hoy</h1><p className="proy-sub">{fmtFecha(today)}</p></div>
        <span style={{ display: 'flex', gap: 8 }}>
          <button className="btn" onClick={onSetear}><Icon name="calendar" size={14} /> Setear semana</button>
          <button className="btn olive" onClick={() => setCrear(true)}><Icon name="plus" size={14} /> Nueva sesión</button>
        </span>
      </div>
      {crear && <Modal titulo="Nueva sesión" onClose={() => setCrear(false)} ancho={640}>
        <FormSesion inicial={{ fecha: today }} onGuardado={(s) => { setCrear(false); onAbrir(s.id); }} onCancelar={() => setCrear(false)} />
      </Modal>}
      {!hoy ? (
        <div className="card" style={{ padding: 36, textAlign: 'center', maxWidth: 460, margin: '20px auto' }}>
          <div style={{ opacity: .5, marginBottom: 10 }}><Icon name="flame" size={30} /></div>
          <h2 style={{ fontSize: 17, margin: '0 0 6px' }}>No hay entreno de hoy</h2>
          <p className="hint">Creá la sesión del día o armá tu semana.</p>
        </div>
      ) : <SesionDetalle sesionId={hoy.id} onVolver={null} />}
      {otros.length > 0 && (
        <div style={{ marginTop: 26 }}>
          <div className="sec-head"><h3>Otros entrenos</h3></div>
          <div className="list">
            {otros.slice(0, 8).map((s) => (
              <button key={s.id} className="row" onClick={() => onAbrir(s.id)} style={{ cursor: 'pointer', textAlign: 'left', font: 'inherit' }}>
                <div className="rmain"><div className="rtitle">{s.objetivo || 'Sesión'}</div><div className="rsub">{fmtFecha(s.fecha)} · {s.n_ejercicios} ejercicio(s)</div></div>
                <Icon name="chevronRight" size={16} />
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ── Semana: planificador Lun–Dom + rotación de 12 + ajustes del domingo ──────
const DIAS_SEM = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
function isoSemana(d) {
  const dt = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
  const day = (dt.getUTCDay() + 6) % 7; dt.setUTCDate(dt.getUTCDate() - day + 3);
  const firstThu = new Date(Date.UTC(dt.getUTCFullYear(), 0, 4));
  const week = 1 + Math.round(((dt - firstThu) / 86400000 - 3 + ((firstThu.getUTCDay() + 6) % 7)) / 7);
  return dt.getUTCFullYear() + '-W' + String(week).padStart(2, '0');
}
function lunesDe(d) { const x = new Date(d); const day = (x.getDay() + 6) % 7; x.setDate(x.getDate() - day); x.setHours(0, 0, 0, 0); return x; }
function SemanaView({ onAbrir }) {
  const [sesiones, setSesiones] = useState(null);
  const [meta, setMeta] = useState(null);
  const [crearFecha, setCrearFecha] = useState(null);
  const [busy, setBusy] = useState(false);
  const iso = isoSemana(new Date());
  const cargar = () => {
    window.api('/api/fitness/sesiones').then((d) => setSesiones(d.sesiones || [])).catch(() => setSesiones([]));
    window.api('/api/fitness/semana/' + iso).then(setMeta).catch(() => setMeta({ iso, confirmada: false }));
  };
  useEffect(() => { cargar(); }, []);
  if (sesiones === null || meta === null) return <p className="hint">Cargando…</p>;
  const lun = lunesDe(new Date());
  const dias = DIAS_SEM.map((d, i) => { const dt = new Date(lun); dt.setDate(lun.getDate() + i); const f = dt.toISOString().slice(0, 10); return { d, fecha: f, ses: sesiones.find((s) => (s.fecha || '').slice(0, 10) === f) || null }; });
  // Rotación: semanas transcurridas desde el primer entreno, mod 12.
  const fechas = sesiones.map((s) => (s.fecha || '').slice(0, 10)).filter(Boolean).sort();
  let rot = 1;
  if (fechas.length) { const wk = Math.round((lunesDe(new Date()) - lunesDe(new Date(fechas[0] + 'T00:00:00'))) / (7 * 86400000)); rot = ((wk % 12) + 12) % 12 + 1; }
  const today = hoyISO();
  const setMetaField = (patch) => { const next = { ...meta, ...patch }; setMeta(next); return next; };
  const guardarMeta = async (patch) => { const next = setMetaField(patch); setBusy(true); try { await window.api('/api/fitness/semana/' + iso, { method: 'PUT', body: JSON.stringify(next) }); } catch (e) { alert(e.message); } finally { setBusy(false); } };
  return (
    <div>
      <div className="mkt-head">
        <div><h1 className="proy-h1">Semana</h1><p className="proy-sub">Setear de lunes a domingo · rotación de 12 semanas.</p></div>
        <button className={'btn' + (meta.confirmada ? '' : ' olive')} disabled={busy} onClick={() => guardarMeta({ confirmada: !meta.confirmada })}>
          <Icon name="check" size={14} /> {meta.confirmada ? 'Semana confirmada' : 'Confirmar semana'}
        </button>
      </div>
      <div className="card" style={{ padding: '14px 16px', marginBottom: 16 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: 'var(--ink-3)', marginBottom: 6, gap: 10, flexWrap: 'wrap' }}>
          <span><b>Semana {rot}</b> de 12</span>
          <input className="input" value={meta.bloque || ''} onChange={(e) => setMetaField({ bloque: e.target.value })} onBlur={() => guardarMeta({})} placeholder="Bloque (ej. Hipertrofia)" style={{ maxWidth: 200, fontSize: 12, padding: '4px 8px' }} />
        </div>
        <div className="rot"><i style={{ width: (rot / 12 * 100) + '%' }} /></div>
      </div>
      <div className="wk-strip">
        {dias.map((x) => (
          <button key={x.fecha} className={'wk-day' + (x.fecha === today ? ' hoy' : '') + (x.ses ? '' : ' rest')} onClick={() => x.ses ? onAbrir(x.ses.id) : setCrearFecha(x.fecha)}>
            <div className="d">{x.d}</div>
            <div className="t">{x.ses ? (x.ses.objetivo || 'Sesión') : '—'}</div>
            <div className="st">{x.ses ? (x.ses.n_ejercicios + ' ej.') : '+ armar'}</div>
          </button>
        ))}
      </div>
      <p className="hint" style={{ margin: '12px 0 0' }}>Tocá un día para armarlo (buscás ejercicios en la biblioteca por nombre) o abrirlo.</p>
      {crearFecha && <Modal titulo={'Armar día · ' + fmtFecha(crearFecha)} onClose={() => setCrearFecha(null)} ancho={640}>
        <FormSesion inicial={{ fecha: crearFecha }} onGuardado={(s) => { setCrearFecha(null); onAbrir(s.id); }} onCancelar={() => setCrearFecha(null)} />
      </Modal>}

      <div className="card" style={{ padding: 16, marginTop: 18, background: 'var(--paper-2)' }}>
        <div className="sec-head" style={{ margin: '0 0 10px' }}><h3>Ajustes del domingo</h3></div>
        <p className="hint" style={{ margin: '0 0 12px' }}>Al cerrar la semana, definís las subidas/bajadas para la próxima (progresión de la rotación).</p>
        <div className="form-grid c3">
          <label className="field"><span>Peso</span>
            <select value={meta.ajuste_peso || ''} onChange={(e) => guardarMeta({ ajuste_peso: e.target.value })}>
              <option value="">Mantener</option><option>Subir 2.5%</option><option>Subir 5%</option><option>Bajar (deload)</option>
            </select></label>
          <label className="field"><span>Reps</span>
            <select value={meta.ajuste_reps || ''} onChange={(e) => guardarMeta({ ajuste_reps: e.target.value })}>
              <option value="">Mantener</option><option>+1 rep</option><option>+2 reps</option>
            </select></label>
          <label className="field"><span>Series</span>
            <select value={meta.ajuste_series || ''} onChange={(e) => guardarMeta({ ajuste_series: e.target.value })}>
              <option value="">Mantener</option><option>+1 serie</option><option>-1 (descarga)</option>
            </select></label>
        </div>
      </div>
    </div>
  );
}

// ── Shell ────────────────────────────────────────────────────────────────────
function Shell({ user }) {
  const [view, setView] = useState('hoy');
  const [sesion, setSesion] = useState(null);
  const [appMenu, setAppMenu] = useState(false);
  const logout = () => window.sb.auth.signOut();
  const initials = (user.email || '?').slice(0, 2).toUpperCase();
  const nav = [
    { id: 'hoy', label: 'Hoy', icon: 'flame' },
    { id: 'semana', label: 'Semana', icon: 'calendar' },
    { id: 'medidas', label: 'Medidas', icon: 'user' },
    { id: 'progreso', label: 'Resumen', icon: 'chart' },
  ];
  const irNav = (v) => { setSesion(null); setView(v); };
  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: 'var(--paper)', color: 'var(--ink)' }}>
      <aside style={{ width: 248, flexShrink: 0, borderRight: '1px solid var(--line)', background: 'var(--paper)', display: 'flex', flexDirection: 'column', padding: '16px 12px' }}>
        <div style={{ position: 'relative' }}>
          <div className="side-brand" onClick={() => setAppMenu((v) => !v)} style={{ cursor: 'pointer' }} title="Cambiar de app">
            <div className="mk">F</div>
            <div style={{ lineHeight: 1.1, minWidth: 0 }}>
              <div style={{ fontSize: 9, letterSpacing: '.16em', color: 'var(--ink-4)', textTransform: 'uppercase' }}>Simplificando</div>
              <div style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontSize: 19 }}>Fitness</div>
            </div>
            <Icon name="chevronDown" size={16} />
          </div>
          {appMenu && <AppSwitcher onClose={() => setAppMenu(false)} />}
        </div>
        <nav style={{ display: 'flex', flexDirection: 'column', gap: 3, marginTop: 14 }}>
          {nav.map((n) => <NavBtn key={n.id} n={n} active={view === n.id && !sesion} onNav={irNav} />)}
        </nav>
        <div className="side-user">
          <div className="ava">{initials}</div>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={user.email}>{user.email}</div>
            <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>Sesión iniciada</div>
          </div>
          <button onClick={logout} title="Cerrar sesión" style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-4)', display: 'flex', padding: 4 }}><Icon name="logout" size={16} /></button>
        </div>
      </aside>
      <main style={{ flex: 1, minWidth: 0, overflowX: 'hidden' }}>
        <div style={{ padding: '24px 26px 76px', minWidth: 0 }}>
          {sesion ? <SesionDetalle sesionId={sesion} onVolver={() => setSesion(null)} />
            : view === 'hoy' ? <HoyView onAbrir={(id) => setSesion(id)} onSetear={() => irNav('semana')} />
              : view === 'semana' ? <SemanaView onAbrir={(id) => setSesion(id)} />
                : view === 'medidas' ? <MedidasView />
                  : <ProgresoView />}
        </div>
      </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 />);
