/* ============================================================
   ONLYCLEAN — Client app screens (app/client.jsx)
   ============================================================ */

/* ---------------- Login (shared client + admin) ---------------- */
function LoginScreen({ onLogin }) {
  const [email, setEmail] = useState("");
  const [pass, setPass] = useState("");
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);

  async function submit(e) {
    e.preventDefault();
    setBusy(true);setErr("");
    const res = await window.DB.login(email, pass);
    setBusy(false);
    if (!res) {setErr("Correo o contraseña incorrectos.");return;}
    onLogin(res);
  }

  return (
    <Phone>
      <Screen className="login-screen">
        <div className="login2-hero">
          <img className="bg" src="assets/brand.png" alt="ONLYCLEAN" />
          <div className="scrim"></div>
          <div className="login2-logo-wrap fade-in">
            <img className="login2-logo" src="assets/logo-word.svg" alt="ONLYCLEAN · Calisthenics" />
          </div>
        </div>

        <div className="login2-panel">
          <h2 className="login2-title">Iniciar sesión</h2>
          <form onSubmit={submit}>
            <div className="login2-field">
              <span className="login2-ic"><Icon name="mail" /></span>
              <input type="email" autoComplete="username" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Correo" />
            </div>
            <div className="login2-field">
              <span className="login2-ic"><Icon name="lock" /></span>
              <input type="password" autoComplete="current-password" value={pass} onChange={(e) => setPass(e.target.value)} placeholder="Contraseña" />
            </div>
            {err && <p className="login2-err">{err}</p>}
            <button type="submit" className="login2-btn" disabled={busy}>{busy ? "Entrando…" : "Entrar"}</button>
            <p className="login2-hint">
              Demo · Cliente <b>david@onlyclean.mx</b> / david2026<br />Admin <b>admin@onlyclean.mx</b> / onlyclean
            </p>
          </form>
        </div>
      </Screen>
    </Phone>);

}

/* ---------------- Blocked screen ---------------- */
function BlockedScreen({ onLogout }) {
  return (
    <Phone>
      <Screen>
        <div className="blocked">
          <img className="blocked-logo" src="assets/logo-word.svg" alt="ONLYCLEAN" />
          <div className="blocked-msg">
            <span className="blocked-ic"><Icon name="lock" /></span>
            <p>Para acceder contacta a tu entrenador</p>
          </div>
          <button className="back-pill" onClick={onLogout}><Icon name="logout" style={{ width: 15, height: 15 }} /> Salir</button>
        </div>
      </Screen>
    </Phone>);

}

/* ---------------- Client shell ---------------- */
function ClientApp({ clientId, onLogout }) {
  const [client, setClient] = useState(null);
  const [content, setContent] = useState(null);
  const [coach, setCoach] = useState(null);
  const [stack, setStack] = useState([{ view: "home" }]);
  const [video, setVideo] = useState(null);
  const top = stack[stack.length - 1];

  useEffect(() => {
    window.DB.getClient(clientId).then((cl) => {
      setClient(cl);
      if (cl && cl.content) setContent(cl.content); else window.DB.getContent().then(setContent);
      if (cl && cl.coachId) window.DB.getCoach(cl.coachId).then(setCoach); else setCoach(null);
    });
  }, [clientId]);

  const push = (v) => setStack((s) => [...s, v]);
  const pop = () => setStack((s) => s.length > 1 ? s.slice(0, -1) : s);
  const home = () => setStack([{ view: "home" }]);

  const screenRef = useRef(null);
  const [scrolled, setScrolled] = useState(false);
  const onScroll = (e) => setScrolled(e.target.scrollTop > 150);
  useEffect(() => { setScrolled(false); if (screenRef.current) screenRef.current.scrollTop = 0; }, [stack.length, top.view, top.routineId, top.recoveryId]);

  if (!client || !content) return <Phone><Screen><div className="pad" style={{ margin: "auto", color: "var(--muted)" }}>Cargando…</div></Screen></Phone>;

  if (client.blocked) return <BlockedScreen onLogout={onLogout} />;

  let body;
  if (top.view === "home") body = <ClientHome client={client} coach={coach} go={push} onLogout={onLogout} />;else
  if (top.view === "calendar") body = <CalendarScreen client={client} back={pop} openDay={(ctx) => push({ view: "day", ...ctx })} />;else
  if (top.view === "day") body = <DayScreen clientId={clientId} routineId={top.routineId} recoveryId={top.recoveryId} dayCtx={top.dayCtx} readOnly={top.readOnly} back={pop} onVideo={setVideo} />;else
  if (top.view === "methodology") body = <InfoMethodology data={content.methodology} back={pop} />;else
  if (top.view === "nutrition") body = <InfoNutrition data={content.nutrition} back={pop} />;else
  if (top.view === "recovery") body = <InfoRecovery data={content.recovery} back={pop} />;else
  if (top.view === "profile") body = <ProfileScreen client={client} back={pop} />;else
  if (top.view === "competition") body = <CompetitionScreen clientId={clientId} competition={client.competition} onUpdate={(comp) => setClient((c) => ({ ...c, competition: comp }))} back={pop} onVideo={setVideo} />;

  return (
    <Phone>
      <Screen key={top.view + (top.routineId || "") + (top.recoveryId || "")} innerRef={screenRef} onScroll={onScroll} className="fade-in">{body}</Screen>
      {top.view === "day" &&
        <button className={`day-back-float ${scrolled ? "show" : ""}`} onClick={pop} aria-label="Regresar">
          <Icon name="chevronLeft" /> Regresar
        </button>}
    </Phone>);

}

/* ---------------- Home ---------------- */
function ClientHome({ client, coach, go, onLogout }) {
  const menu = [
  { v: "calendar", t: "Ir a entrenar", s: "Tu calendario y rutina del día", img: "assets/icon-calendar.svg" },
  { v: "competition", t: "Próxima competencia", s: "Circuitos y circuito meta", img: "assets/icon-compe.svg" },
  { v: "methodology", t: "Metodología", s: "Cómo trabajamos por intensidad", img: "assets/icon-metodo.svg" },
  { v: "nutrition", t: "Alimentación", s: "Ventana, nutrientes y suplementos", img: "assets/icon-alimentacion.svg" },
  { v: "recovery", t: "Recuperación", s: "Sueño, frío, calor y fisioterapia", img: "assets/icon-recuperacion.svg" }];

  const comp = client.competition;
  const hasComp = !!(comp && ((comp.name && comp.name.trim()) || (comp.circuits && comp.circuits.length)));

  return (
    <div className="pad">
      <div style={{ display: "flex", alignItems: "center", justifyContent: "flex-end", marginBottom: 18 }}>
        <button className="back-pill" style={{ padding: "8px 14px" }} onClick={onLogout}><Icon name="logout" style={{ width: 15, height: 15 }} /> Salir</button>
      </div>

      <div className="card center" style={{ marginTop: 8 }}>
        {client.photo && <img className="home-avatar" src={client.photo} alt={client.name} />}
        <h1 className="info-title" style={{ textAlign: "center" }}>¡{client.name}, bienvenido a tu entrenamiento!</h1>
        {client.welcome && <p className="info-sub" style={{ textAlign: "center", maxWidth: 330, margin: "12px auto 0" }}>{client.welcome}</p>}
        <button className="profile-btn" onClick={() => go({ view: "profile" })}><Icon name="clients" style={{ width: 17, height: 17 }} /> Ver mi perfil</button>
      </div>

      {client.objectives?.length > 0 &&
      <div className="sec">
          <img className="sec-icon" src="assets/icon-objetivos.svg" alt="" />
          <div className="sec-h">Objetivos personales</div>
          <div className="box light" style={{ backgroundColor: "rgba(243, 243, 243, 0)" }}>
            <ul className="bullets">
              {client.objectives.map((o, i) => <li key={i}>{o}</li>)}
            </ul>
          </div>
        </div>
      }

      <div className="sec">
        <div className="sec-h">Aquí está tu plan</div>
        <p className="info-sub" style={{ marginTop: 0, marginBottom: 14 }}>Dale clic a donde quieras ir.</p>
        <div className="menu">
          {menu.filter((m) => m.v === "calendar" || (m.v === "competition" ? (hasComp && (client.contentShow ? client.contentShow.competition !== false : true)) : (client.contentShow ? client.contentShow[m.v] !== false : true))).map((m) =>
          <button className="menu-item" key={m.v} onClick={() => go({ view: m.v })}>
              <span className="mi-ic plain"><img src={m.img} alt="" /></span>
              <span><span className="mi-t" style={{ display: "block" }}>{m.t}</span><span className="mi-s">{m.s}</span></span>
              <Icon name="chevronRight" className="mi-arrow" style={{ width: 20, height: 20 }} />
            </button>
          )}
        </div>
      </div>

      {coach &&
      <div className="sec" style={{ marginTop: 40, marginBottom: 40 }}>
        <div className="sec-h">Tu entrenador personal</div>
        <div className="coach-card">
          <span className="coach-avatar">{coach.photo ? <img src={coach.photo} alt={coach.name} /> : <Icon name="user" />}</span>
          <div className="coach-info">
            <div className="coach-name">{coach.name}</div>
            <div className="coach-role">Coach ONLYCLEAN</div>
            <div className="coach-links">
              {coach.instagram &&
                <a className="coach-link ig" href={coach.instagram} target="_blank" rel="noopener noreferrer" aria-label="Instagram">
                  <Icon name="instagram" />
                </a>}
              {(() => {
                const wa = coach.whatsapp || coach.phone || "";
                if (!wa) return null;
                const href = /^https?:\/\//i.test(wa) ? wa : `https://wa.me/${wa.replace(/[^0-9]/g, "")}`;
                return (
                  <a className="coach-link wa" href={href} target="_blank" rel="noopener noreferrer" aria-label="WhatsApp">
                    <Icon name="whatsapp" />
                  </a>);
              })()}
            </div>
          </div>
        </div>
      </div>
      }
    </div>);

}

/* ---------------- Calendar ---------------- */
// Etiqueta de fecha del día: "Lunes 1 de junio" — derivada de la columna (día de la semana),
// el número de día y el mes tomado de la etiqueta del calendario.
const WEEKDAY_NAMES = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"];
const MONTH_NAMES = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
function dayDateLabel(colIndex, dayNumber, monthLabel) {
  const wd = WEEKDAY_NAMES[colIndex] || "";
  const lower = (monthLabel || "").toLowerCase();
  const month = MONTH_NAMES.find((m) => lower.includes(m)) || "";
  const parts = [wd, dayNumber, month ? "de " + month : ""].filter(Boolean);
  return parts.join(" ").trim();
}

function CalendarScreen({ client, back, openDay }) {
  const cals = client.calendars || [];
  const activeIdx = Math.max(0, cals.findIndex((c) => c.active));
  const [idx, setIdx] = useState(activeIdx === -1 ? 0 : activeIdx);
  const [histOpen, setHistOpen] = useState(false);
  const [recMap, setRecMap] = useState({});
  const [recList, setRecList] = useState([]);
  const cal = cals[idx];
  const isActive = cal && (cal.active || cals.length === 1);
  const dow = ["L", "M", "M", "J", "V", "S", "D"];
  const today = new Date();
  const todayDate = today.getDate();
  const todayMonth = today.getMonth(); // 5 = June
  const history = cals.filter((c) => !c.active);

  useEffect(() => {
    window.DB.listRoutines().then((rs) => {
      const m = {};
      const list = [];
      rs.forEach((r) => {if (r.intensity === "recovery") { m[r.id] = r.icon || "heart"; list.push({ id: r.id, title: r.title, icon: r.icon || "heart" }); }});
      setRecMap(m);
      setRecList(list);
    });
  }, []);

  if (!cal) return (
    <div className="pad">
      <BackPill onClick={back} />
      <div className="card" style={{ marginTop: 22, textAlign: "center" }}><p className="lead">Aún no tienes un calendario asignado.</p></div>
    </div>);


  return (
    <div className="pad">
      <BackPill onClick={back} />
      <div className="card" style={{ marginTop: 18 }}>
        <h2 className="h2 center">Planificación</h2>
        <p className="lead center" style={{ marginTop: 2 }}>{isActive ? "¿Qué toca hoy?" : "Planificación del histórico"}</p>

        {!isActive &&
        <div className="hist-banner"><Icon name="clock" style={{ width: 14, height: 14 }} /> Solo lectura · planificación anterior</div>
        }

        <p className="h3 center" style={{ marginTop: 16, marginBottom: 4, fontWeight: 600 }}>{cal.title}</p>
        <p className="lead center" style={{ marginTop: 0, marginBottom: 18, fontSize: 14 }}>{cal.monthLabel}</p>

        <div className="cal-grid" style={{ marginBottom: 12 }}>
          {dow.map((dd, i) => <div className="cal-dow" key={i}>{dd}</div>)}
        </div>
        {cal.weeks.map((week, wi) =>
        <div className="cal-grid" style={{ marginBottom: 10 }} key={wi}>
            {week.map((day, di) => {
            const meta = DAYTYPE[day.type] || DAYTYPE.empty;
            const isToday = isActive && !day.otherMonth && day.date === todayDate && todayMonth === 5;
            const clickable = !day.otherMonth && day.type !== "empty" && (day.routineId || day.recoveryId);
            const recIcon = day.recoveryId ? recMap[day.recoveryId] || "heart" : null;
            return (
              <button
                key={di}
                className={`cal-day ${day.otherMonth ? "muted" : meta.cls} ${isToday ? "today" : ""}`}
                disabled={!clickable}
                style={{ cursor: clickable ? "pointer" : "default", opacity: day.type === "empty" ? .55 : 1 }}
                onClick={() => clickable && openDay({ routineId: day.routineId, recoveryId: day.recoveryId, readOnly: !isActive, dayCtx: { date: day.date, calId: cal.id, calTitle: cal.title, dateLabel: dayDateLabel(di, day.date, cal.monthLabel) } })}
                aria-label={`${day.date} ${meta.label}${recIcon ? " · con recuperación" : ""}`}>
                
                  {meta.icon ? <Icon name={meta.icon} className="ic" /> : day.date}
                  {recIcon && <span className="rec-badge"><RecoIcon name={recIcon} /></span>}
                </button>);

          })}
          </div>
        )}
      </div>

      {history.length > 0 &&
      <div className="card hist-card" style={{ marginTop: 14 }}>
          {!isActive &&
          <button className="pill ghost block" style={{ marginBottom: 10 }} onClick={() => { setIdx(activeIdx); setHistOpen(false); }}><Icon name="chevronLeft" style={{ width: 15, height: 15 }} /> Volver a la planificación actual</button>
          }
          <button className="hist-toggle" onClick={() => setHistOpen((v) => !v)}>
            <span><Icon name="clock" style={{ width: 15, height: 15 }} /> Ver histórico de planificaciones</span>
            <Icon name="chevronDown" style={{ width: 16, height: 16, transform: histOpen ? "rotate(180deg)" : "none" }} />
          </button>
          {histOpen &&
          <div className="hist-list">
            {cals.map((c, i) => (
              <button key={c.id} className={`hist-item ${i === idx ? "on" : ""}`} onClick={() => { setIdx(i); setHistOpen(false); }}>
                <span className="hist-item-t">{c.title}{c.active && <span className="hist-active-tag">Actual</span>}</span>
                <span className="hist-item-s">{c.monthLabel}</span>
              </button>
            ))}
          </div>
          }
      </div>
      }

      <p className="small center" style={{ marginTop: 14 }}>Toca un día para ver su rutina y recuperación.</p>

      {/* legend */}
      <div style={{ marginTop: 22, paddingLeft: 8, paddingRight: 8 }}>
        <div className="sec-h" style={{ marginBottom: 14 }}>Símbolos y significados</div>
        <div className="legend" style={{ paddingLeft: 8, paddingRight: 8 }}>
          {["high", "low", "rest"].map((t) => {
            const m = DAYTYPE[t];
            return (
              <div className="legend-row" key={t}>
                <span className="lbl">{m.label}</span>
                <span className="legend-dot" style={{ background: t === "high" ? "var(--coral)" : t === "low" ? "var(--low)" : "var(--rest)" }}>
                  {m.icon && <Icon name={m.icon} className="ic" />}
                </span>
              </div>);

          })}
          {recList.map((rec) => (
            <div className="legend-row" key={rec.id}>
              <span className="lbl">{rec.title}</span>
              <span className="legend-dot" style={{ background: "#8b97a4" }}>
                <RecoIcon name={rec.icon} className="ic" />
              </span>
            </div>
          ))}
        </div>
      </div>
      <img className="day-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
    </div>);

}

/* ---------------- Day detail (rutina + recuperación recomendada) ---------------- */
function RoutineBlocks({ blocks, onVideo }) {
  return blocks.map((b) =>
  <div className="block" key={b.id}>
      <div className="block-head2">
        {b.scheme ?
      <React.Fragment><span className="block-kicker">{b.name}</span><span className="block-scheme2">{b.scheme}</span></React.Fragment> :
      <span className="block-scheme2" style={{ marginTop: 0 }}>{b.name}</span>}
      </div>
      <div className="block-card">
        {b.items.filter((it) => it.name || it.qty).map((it) =>
      <div className="ex-row" key={it.id}>
            {it.qty !== "" && it.qty != null && <span className="ex-qty">{it.qty}</span>}
            <span className="ex-body">
              <span className="ex-name">{it.name}</span>
              {it.meta && <span className="ex-meta">{it.meta}</span>}
            </span>
            {it.video && <a className="ex-video" href={it.video} target="_blank" rel="noopener noreferrer" aria-label="Ver video en YouTube"><Icon name="play" /></a>}
          </div>
      )}
      </div>
      {b.note && <div className="rest-bar"><Icon name="clock" /> {b.note}</div>}
    </div>
  );
}

function RecoverySection({ rec, onVideo }) {
  return (
    <div className="rec-section">
      <div className="rec-section-head">
        <span className="rec-section-ic"><RecoIcon name={rec.icon || "heart"} /></span>
        <div>
          <div className="rec-section-kicker">Recuperación recomendada</div>
          <div className="rec-section-title">{rec.title}</div>
        </div>
      </div>
      {rec.blocks.map((b) =>
      <div className="rec-block" key={b.id}>
          {b.scheme && <div className="rec-block-scheme">{b.scheme}</div>}
          {b.items.filter((it) => it.name || it.qty).map((it) =>
        <div className="ex-row" key={it.id}>
              {it.qty !== "" && it.qty != null && <span className="ex-qty slate">{it.qty}</span>}
              <span className="ex-body">
                <span className="ex-name">{it.name}</span>
                {it.meta && <span className="ex-meta">{it.meta}</span>}
              </span>
              {it.video && <a className="ex-video slate" href={it.video} target="_blank" rel="noopener noreferrer" aria-label="Ver video en YouTube"><Icon name="play" /></a>}
            </div>
        )}
          {b.note && <div className="rec-note">{b.note}</div>}
        </div>
      )}
      {rec.note && <div className="rec-foot">{rec.note}</div>}
    </div>);

}

/* ---------------- Feedback form (al final del día) ---------------- */
function FeedbackForm({ clientId, routine, dayCtx }) {
  const [text, setText] = useState("");
  const [saved, setSaved] = useState(false);
  const [editing, setEditing] = useState(true);
  const [busy, setBusy] = useState(false);
  const toast = useToast();

  useEffect(() => {
    window.DB.getFeedback(clientId, dayCtx.calId, dayCtx.date).then((fb) => {
      if (fb) { setText(fb.text); setSaved(true); setEditing(false); }
    });
  }, [clientId, dayCtx.calId, dayCtx.date]);

  async function submit() {
    if (!text.trim()) { toast("Escribe cómo te sentiste"); return; }
    setBusy(true);
    await window.DB.saveFeedback({
      clientId,
      routineId: routine ? routine.id : null,
      routineTitle: routine ? routine.title : "Día de descanso",
      calId: dayCtx.calId,
      calTitle: dayCtx.calTitle,
      date: dayCtx.date,
      text: text.trim(),
    });
    setBusy(false); setSaved(true); setEditing(false);
    toast("¡Feedback enviado!");
  }

  return (
    <div className="feedback">
      <div className="feedback-head">
        <span className="feedback-ic"><Icon name="chat" /></span>
        <div>
          <div className="feedback-kicker">¿Cómo te sentiste?</div>
          <div className="feedback-sub">Cuéntale a tu entrenador cómo viviste la rutina de hoy.</div>
        </div>
      </div>

      {!editing && saved ?
      <div className="feedback-saved">
        <p className="feedback-saved-text">"{text}"</p>
        <div className="feedback-saved-row">
          <span className="feedback-badge"><Icon name="check" style={{ width: 13, height: 13 }} /> Enviado</span>
          <button className="feedback-edit" onClick={() => setEditing(true)}>Editar</button>
        </div>
      </div> :
      <React.Fragment>
        <textarea className="feedback-input" value={text} onChange={(e) => setText(e.target.value)} placeholder="Hoy me sentí…" rows={4}></textarea>
        <button className="pill coral block" onClick={submit} disabled={busy}>{busy ? "Enviando…" : (saved ? "Actualizar feedback" : "Enviar feedback")}</button>
      </React.Fragment>}
    </div>);

}

function DayScreen({ clientId, routineId, recoveryId, dayCtx, readOnly, back, onVideo }) {
  const [r, setR] = useState(undefined); // undefined = loading, null = none
  const [rec, setRec] = useState(undefined);
  useEffect(() => {
    if (routineId) window.DB.getRoutine(routineId).then(setR);else setR(null);
    if (recoveryId) window.DB.getRoutine(recoveryId).then(setRec);else setRec(null);
  }, [routineId, recoveryId]);

  if (r === undefined || rec === undefined) return <div className="pad"><BackPill onClick={back} /><p className="lead" style={{ marginTop: 20 }}>Cargando…</p></div>;

  // header reflects the workout if any; otherwise a rest/recovery header
  const headCls = r ? r.intensity === "high" ? "high" : r.intensity === "low" ? "low" : r.intensity === "rest" ? "rest" : "recovery" : "rest";
  const kicker = r ? r.intensity === "rest" ? "Descanso" : r.intensity + " intensity" : "Descanso";
  const title = r ? r.title : "Día de descanso";

  return (
    <div>
      <div className={`routine-head ${headCls}`}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
          <BackPill onClick={back} />
          <img className="routine-head-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
        </div>
        <div className="kicker">{kicker}</div>
        {dayCtx && dayCtx.dateLabel && <div className="routine-date"><Icon name="calendar" style={{ width: 13, height: 13 }} /> {dayCtx.dateLabel}</div>}
        <div className="ttl" style={{ textWrap: "balance" }}>{title}</div>
      </div>

      <div className="pad" style={{ paddingTop: 20 }}>
        {r && r.warmup &&
        <div className="block">
          <div className="block-head2">
            <span className="block-kicker">Warm-up</span>
          </div>
          <div className="block-card">
            <div className="ex-row">
              <span className="ex-body"><span className="ex-name">{r.warmup}</span></span>
            </div>
          </div>
        </div>}
        {r ?
        <RoutineBlocks blocks={r.blocks} onVideo={onVideo} /> :
        !rec && <p className="lead center" style={{ marginTop: 10 }}>Hoy toca descansar. Aprovecha para dormir bien e hidratarte.</p>}
        {r && r.note && <div className="routine-foot"><Icon name="check" style={{ width: 14, height: 14 }} /> {r.note}</div>}
        {rec && <RecoverySection rec={rec} onVideo={onVideo} />}
        {dayCtx && (r || rec) && !readOnly && <FeedbackForm clientId={clientId} routine={r} dayCtx={dayCtx} />}
        <img className="day-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
      </div>
    </div>);

}

/* ---------------- Info screens (fiel al PDF) ---------------- */
function InfoShell({ title, subtitle, children, back }) {
  return (
    <div className="pad">
      <BackPill onClick={back} />
      <h1 className="info-title" style={{ marginTop: 18 }}>{title}</h1>
      {subtitle && <p className="info-sub">{subtitle}</p>}
      {children}
      <img className="day-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
    </div>);

}

/* renders an array of text lines inside a box */
const Lines = ({ lines }) => (lines || []).map((l, i) => <p className="line" key={i}>{l}</p>);

/* one content box (used by nutrition + recovery) */
function ContentBox({ s }) {
  const accent = s.accent || "light";
  return (
    <div className={`box ${accent}`}>
      {(s.icon || s.img) ?
      <div className="rec-head"><span className="ic-wrap">{s.img ? <img className="rec-ic-img" src={s.img} alt="" /> : <Icon name={s.icon} />}</span><h4>{s.h}</h4></div> :
      s.h && <div className={`bx-h ${s.hicon ? "with-icon" : ""}`}>{s.hicon && <img className={`bx-hicon${s.hiconSq ? " sq" : ""}`} src={s.hicon} alt="" />}{s.h}</div>}

      {s.type === "chips" && <div className="chiprow">{s.chips.map((c, i) => <span className="chip-soft" key={i}>{c}</span>)}</div>}

      {s.macros && <div className="macros">{s.macros.map((m, i) =>
        <div className="macro" key={i}><span className="v">{m.v}</span><span className="l">{m.l}</span></div>
        )}</div>}

      {s.lines && <Lines lines={s.lines} />}

      {s.groups && s.groups.map((g, gi) =>
      <div className="subgroup" key={gi}>
          {g.sub && <div className="sec-sub" style={{ textAlign: "left", marginBottom: 8 }}>{g.sub}</div>}
          {g.items.map((it, ii) =>
        <div className="subgroup" key={ii} style={{ marginTop: ii ? 10 : 0 }}>
              {it.when && <div className="when">{it.when}</div>}
              <Lines lines={it.lines} />
            </div>
        )}
        </div>
      )}
    </div>);

}

/* a section that may be a single box or a two-column row */
function Section({ s }) {
  if (s.type === "cols") {
    return <div className="cols2">{s.cols.map((c, i) => <ContentBox s={c} key={i} />)}</div>;
  }
  return <ContentBox s={s} />;
}

function InfoMethodology({ data, back }) {
  return (
    <InfoShell title={data.title} subtitle={data.intro} back={back}>
      {data.week &&
      <div className="sec">
          <div className="sec-h center" style={{ textAlign: "center" }}>Distribución semanal</div>
          <div className="box light">
            <div className="wk">{data.week.labels.map((l, i) => <div className="d" key={i}>{l}</div>)}</div>
            <div className="wk" style={{ marginTop: 8 }}>{data.week.values.map((v, i) => <div className={`c ${v}`} key={i}>{v}</div>)}</div>
          </div>
        </div>
      }
      <div className="sec">
        {data.intensities.map((s, i) => <ContentBox s={s} key={i} />)}
      </div>
    </InfoShell>);

}

function InfoNutrition({ data, back }) {
  const [pg, setPg] = useState(0);
  const pages = data.pages || [];
  const page = pages[pg] || { sections: [] };
  return (
    <InfoShell title={data.title} subtitle={data.intro} back={back}>
      <div className="page-label">{`Página ${pg + 1} de ${pages.length}${page.label ? " · " + page.label : ""}`}</div>
      <div className="sec fade-in" key={pg}>
        {page.sections.map((s, i) => <div className="sec" key={i} style={{ marginTop: i ? 14 : 0 }}><Section s={s} /></div>)}
      </div>
      {pages.length > 1 &&
      <div className="pager">
          <button disabled={pg === 0} onClick={() => setPg((p) => Math.max(0, p - 1))} aria-label="Anterior"><Icon name="chevronLeft" style={{ width: 18, height: 18 }} /></button>
          <div className="dots">{pages.map((_, i) => <span className={`dot ${i === pg ? "on" : ""}`} key={i} onClick={() => setPg(i)} style={{ cursor: "pointer" }}></span>)}</div>
          <button disabled={pg === pages.length - 1} onClick={() => setPg((p) => Math.min(pages.length - 1, p + 1))} aria-label="Siguiente"><Icon name="chevronRight" style={{ width: 18, height: 18 }} /></button>
        </div>
      }
    </InfoShell>);

}

function InfoRecovery({ data, back }) {
  return (
    <InfoShell title={data.title} subtitle={data.intro} back={back}>
      <div className="sec">
        {data.sections.map((s, i) => <div className="sec" key={i} style={{ marginTop: i ? 12 : 0 }}><Section s={s} /></div>)}
      </div>
    </InfoShell>);

}

/* ---------------- Competition (Próxima competencia) ---------------- */
function fmtResultDate(s) {
  if (!s) return "—";
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
  if (!m) return s;
  const dt = new Date(+m[1], +m[2] - 1, +m[3]);
  const wd = WEEKDAY_NAMES[(dt.getDay() + 6) % 7];
  return `${wd} ${+m[3]} de ${MONTH_NAMES[+m[2] - 1]}`;
}
function ResultsLog({ results, dark }) {
  const list = results || [];
  if (!list.length) return null;
  return (
    <div className={`results-log ${dark ? "dark" : ""}`}>
      <div className="results-head"><Icon name="clock" style={{ width: 14, height: 14 }} /> Registro de resultados</div>
      {list.map((r) => (
        <div className="result-row" key={r.id}>
          <span className="result-date">{fmtResultDate(r.date)}</span>
          <span className="result-text">{r.text}</span>
        </div>
      ))}
    </div>
  );
}

/* editable results log — client captures their own results (auto date) */
function todayISO() { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; }
function ClientResultsLog({ results, onChange, dark }) {
  const list = results || [];
  const [editId, setEditId] = useState(null);
  const [draft, setDraft] = useState("");

  function startAdd() {
    const r = { id: "res_" + Math.random().toString(36).slice(2, 8), date: todayISO(), text: "" };
    onChange([...list, r]); setEditId(r.id); setDraft("");
  }
  function startEdit(r) { setEditId(r.id); setDraft(r.text); }
  function save() {
    const txt = draft.trim();
    if (!txt) { onChange(list.filter((r) => r.id !== editId)); }
    else { onChange(list.map((r) => (r.id === editId ? { ...r, text: txt } : r))); }
    setEditId(null); setDraft("");
  }
  function cancel() {
    const r = list.find((x) => x.id === editId);
    if (r && !r.text) onChange(list.filter((x) => x.id !== editId));
    setEditId(null); setDraft("");
  }
  function del(id) { onChange(list.filter((r) => r.id !== id)); if (editId === id) { setEditId(null); setDraft(""); } }

  return (
    <div className={`results-log ${dark ? "dark" : ""}`}>
      <div className="results-head"><Icon name="clock" style={{ width: 14, height: 14 }} /> Registro de resultados</div>
      {list.map((r) => (
        <div className="result-row" key={r.id}>
          <span className="result-date">{fmtResultDate(r.date)}</span>
          {editId === r.id ? (
            <div className="result-edit">
              <textarea className="result-input" value={draft} onChange={(e) => setDraft(e.target.value)} placeholder="¿Cómo te fue? Tiempos, sensaciones, lo que lograste…" autoFocus></textarea>
              <div className="result-edit-actions">
                <button className="result-save" onClick={save}>Guardar</button>
                <button className="result-cancel" onClick={cancel}>Cancelar</button>
              </div>
            </div>
          ) : (
            <div className="result-show">
              <span className="result-text">{r.text || "—"}</span>
              <span className="result-row-actions">
                <button onClick={() => startEdit(r)} aria-label="Editar"><Icon name="edit" style={{ width: 15, height: 15 }} /></button>
                <button onClick={() => del(r.id)} aria-label="Eliminar"><Icon name="trash" style={{ width: 15, height: 15 }} /></button>
              </span>
            </div>
          )}
        </div>
      ))}
      <button className="result-add" onClick={startAdd}><Icon name="plus" style={{ width: 15, height: 15 }} /> Agregar resultado</button>
    </div>
  );
}

function CompMeta({ meta, onVideo, onResultsChange }) {
  if (!meta || !meta.blocks) return null;
  return (
    <div className="comp-meta-card">
      <img className="comp-meta-bolt" src="assets/icon-rayo.svg" alt="" />
      <div className="comp-meta-title">{meta.title || "Circuito Meta"}</div>
      {meta.blocks.map((b) => (
        <div key={b.id} style={{ marginTop: 10 }}>
          {b.scheme && <div className="comp-meta-scheme">{b.scheme}</div>}
          <ul className="comp-meta-list">
            {b.items.filter((it) => it.name || it.qty).map((it) => (
              <li key={it.id}>
                <span>{[it.qty, it.name].filter((x) => x !== "" && x != null).join(" ")}</span>
                {it.meta && <span className="comp-meta-note"> — {it.meta}</span>}
                {it.video && <a className="comp-meta-video" href={it.video} target="_blank" rel="noopener noreferrer" aria-label="Ver video"><Icon name="play" /></a>}
              </li>
            ))}
          </ul>
          {b.note && <div className="comp-meta-foot">{b.note}</div>}
        </div>
      ))}
      <ClientResultsLog results={meta.results} onChange={onResultsChange} dark={true} />
    </div>
  );
}

function CompetitionScreen({ clientId, competition, onUpdate, back, onVideo }) {
  const [comp, setComp] = useState(() => competition ? JSON.parse(JSON.stringify(competition)) : null);
  const circuits = (comp && comp.circuits) || [];

  function persist(next) {
    setComp(next);
    window.DB.saveClientCompetition(clientId, next);
    if (onUpdate) onUpdate(next);
  }
  function setCircuitResults(ci, results) {
    const cs = circuits.map((c) => ({ ...c }));
    cs[ci] = { ...cs[ci], results };
    persist({ ...comp, circuits: cs });
  }
  function setMetaResults(ci, results) {
    const cs = circuits.map((c) => ({ ...c, meta: { ...c.meta } }));
    cs[ci].meta = { ...cs[ci].meta, results };
    persist({ ...comp, circuits: cs });
  }

  return (
    <div className="pad">
      <BackPill onClick={back} />
      <h1 className="info-title" style={{ marginTop: 18 }}>Próxima competencia</h1>
      {comp && (comp.name || comp.date) && <p className="info-sub" style={{ fontWeight: 700, color: "var(--ink)" }}>{[comp.name, comp.date].filter(Boolean).join(" · ")}</p>}
      {comp && comp.intro && <p className="lead" style={{ marginTop: 10 }}>{comp.intro}</p>}

      {comp && (comp.category || comp.location) && (
        <div className="comp-info">
          {comp.category && <div className="comp-info-row"><Icon name="dumbbell" style={{ width: 16, height: 16, color: "var(--coral-ink)" }} /><span><b>Categoría:</b> {comp.category}</span></div>}
          {comp.location && <div className="comp-info-row"><Icon name="calendar" style={{ width: 16, height: 16, color: "var(--coral-ink)" }} /><span><b>Ubicación:</b> {comp.location}</span></div>}
        </div>
      )}

      {circuits.map((cir, ci) => (
        <div className="comp-circuit" key={cir.id}>
          {cir.title && <div className="comp-circuit-title">{cir.title}</div>}
          {cir.image
            ? <img className="comp-img" src={cir.image} alt={cir.title || "Circuito"} />
            : <div className="comp-img-empty"><Icon name="grid" style={{ width: 26, height: 26 }} /><span>Sin imagen del circuito</span></div>}
          <ClientResultsLog results={cir.results} onChange={(r) => setCircuitResults(ci, r)} />
          <CompMeta meta={cir.meta} onVideo={onVideo} onResultsChange={(r) => setMetaResults(ci, r)} />
        </div>
      ))}
      {circuits.length === 0 && <div className="box light" style={{ marginTop: 18, textAlign: "center" }}><p className="lead">Aún no hay circuitos cargados.</p></div>}
      <img className="day-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
    </div>
  );
}

/* ---------------- Profile (Mi perfil) ---------------- */
function ProfileScreen({ client, back }) {
  const p = client.profile || {};
  const evals = p.evaluation || [];
  const infoCards = [
    { ic: "icon-metodo.svg", t: "Experiencia", v: p.experience },
    { ic: "icon-objetivos.svg", t: "Edad y peso", v: [p.age && p.age + " años", p.weight && p.weight + " kg"].filter(Boolean).join("\n") },
    { ic: "icon-recuperacion.svg", t: "Estatura", v: p.height && p.height + " cm" },
    { ic: "icon-alimentacion.svg", t: "Nacionalidad", v: p.nationality },
  ].filter((c) => c.v);

  return (
    <div className="pad profile">
      <BackPill onClick={back} />

      <div className="profile-head">
        {client.photo ? <img className="profile-photo" src={client.photo} alt={client.name} /> : <span className="profile-photo empty"><Icon name="user" style={{ width: 38, height: 38 }} /></span>}
        <div className="profile-name">{client.name}</div>
        {client.email && <div className="profile-email">{client.email}</div>}
      </div>

      {evals.length > 0 &&
      <div className="profile-evals">
        {evals.map((ev) => (
          <div className="eval-card" key={ev.id}>
            <img className="eval-ic" src={"assets/" + (ev.icon || "icon-objetivos.svg")} alt="" />
            <div className="eval-title">{ev.title}</div>
            {ev.note && <div className="eval-note">{ev.note}</div>}
            <ul className="eval-list">
              {(ev.exercises || []).filter((x) => x && x.trim()).map((x, i) => <li key={i}>{x}</li>)}
            </ul>
          </div>
        ))}
      </div>
      }

      {p.level &&
      <div className="profile-level-wrap">
        <div className="profile-level">{p.level.toUpperCase()}</div>
        <div className="profile-level-cap">Calisthenics level</div>
      </div>
      }

      {infoCards.length > 0 &&
      <div className="profile-info-scroll">
        {infoCards.map((c, i) => (
          <div className="info-card" key={i}>
            <img className="info-card-ic" src={"assets/" + c.ic} alt="" />
            <div className="info-card-t">{c.t}</div>
            <div className="info-card-v">{c.v}</div>
          </div>
        ))}
      </div>
      }

      <img className="day-brand" src="assets/logo-mark.svg" alt="ONLYCLEAN" />
    </div>
  );
}

Object.assign(window, { LoginScreen, ClientApp });