/* ============================================================
   ONLYCLEAN — Admin: shell + clients + calendar editor
   (app/admin.jsx)
   ============================================================ */

function AdminApp({ coachId, onLogout }) {
  const [tab, setTab] = useState("dashboard");
  const [unread, setUnread] = useState(0);
  const [recUnread, setRecUnread] = useState(0);
  const refreshUnread = () => {
    window.DB.listFeedback(coachId).then((fb) => setUnread(fb.filter((f) => !f.read).length));
    window.DB.listCompRecords(coachId).then((rs) => setRecUnread(rs.filter((r) => !r.read && !r.hidden).length));
  };
  useEffect(() => { refreshUnread(); }, [tab]);
  const nav = [
    { id: "dashboard", label: "Dashboard", ic: "grid" },
    { id: "clients", label: "Clientes", ic: "clients" },
    { id: "routines", label: "Rutinas", ic: "routine" },
    { id: "feedback", label: "Feedback", ic: "chat" },
    { id: "records", label: "Registros", ic: "clock" },
  ];
  return (
    <div className="admin">
      <div className="admin-bar">
        <div className="brand" style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <img src="assets/logo-mark.svg" alt="" style={{ height: 20, width: "auto" }} />
          <span>ONLYCLEAN<small>Panel del coach</small></span>
        </div>
        <button className="back-pill" onClick={onLogout}><Icon name="logout" style={{ width: 15, height: 15 }} /> Salir</button>
      </div>
      <div className="admin-wrap">
        <nav className="admin-nav">
          {nav.map((n) => (
            <button key={n.id} className={tab === n.id ? "on" : ""} onClick={() => setTab(n.id)}>
              <Icon name={n.ic} /> {n.label}
              {n.id === "feedback" && unread > 0 && <span className="nav-badge">{unread}</span>}
              {n.id === "records" && recUnread > 0 && <span className="nav-badge">{recUnread}</span>}
            </button>
          ))}
        </nav>
        <main className="admin-main">
          {tab === "dashboard" && <DashboardPanel goTo={setTab} coachId={coachId} />}
          {tab === "clients" && <ClientsPanel coachId={coachId} />}
          {tab === "routines" && <RoutinesPanel />}
          {tab === "feedback" && <FeedbackPanel onChange={refreshUnread} coachId={coachId} />}
          {tab === "records" && <RecordsPanel onChange={refreshUnread} coachId={coachId} canDelete={false} />}
        </main>
      </div>
    </div>
  );
}

/* ---------------- Feedback ---------------- */
function FeedbackPanel({ onChange, coachId }) {
  const superMode = !coachId;
  const [items, setItems] = useState(null);
  const [clients, setClients] = useState([]);
  const [coaches, setCoaches] = useState([]);
  const [coachFilter, setCoachFilter] = useState("all");
  const [filter, setFilter] = useState("all");
  const [confirm, setConfirm] = useState(null);
  const toast = useToast();

  const load = () => Promise.all([window.DB.listFeedback(coachId), window.DB.listClients(coachId), superMode ? window.DB.listCoaches() : Promise.resolve([])])
    .then(([fb, cl, cs]) => { setItems(fb); setClients(cl); setCoaches(cs); onChange && onChange(); });
  useEffect(() => { load(); }, []);
  if (!items) return <div className="panel">Cargando…</div>;

  const clientOf = (id) => clients.find((c) => c.id === id) || {};
  const nameOf = (id) => clientOf(id).name || "Cliente";
  const coachNameOf = (clientId) => (coaches.find((co) => co.id === clientOf(clientId).coachId) || {}).name || "—";

  const clientsForFilter = superMode && coachFilter !== "all" ? clients.filter((c) => c.coachId === coachFilter) : clients;
  let shown = items;
  if (superMode && coachFilter !== "all") { const ids = clients.filter((c) => c.coachId === coachFilter).map((c) => c.id); shown = shown.filter((f) => ids.includes(f.clientId)); }
  if (filter !== "all") shown = shown.filter((f) => f.clientId === filter);
  const unread = items.filter((f) => !f.read).length;
  const fmtDate = (ts) => new Date(ts).toLocaleDateString("es-MX", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });

  async function toggleRead(f) { await window.DB.setFeedbackRead(f.id, !f.read); load(); }

  return (
    <div>
      <div className="panel">
        <div className="row-between" style={{ flexWrap: "wrap", gap: 12 }}>
          <div><h3>Feedback de clientes</h3><div className="sub" style={{ margin: 0 }}>{items.length} mensaje(s) · {unread} sin leer</div></div>
          <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
            {superMode && coaches.length > 0 && (
              <select className="input" style={{ width: "auto", minWidth: 150 }} value={coachFilter} onChange={(e) => { setCoachFilter(e.target.value); setFilter("all"); }}>
                <option value="all">Todos los coaches</option>
                {coaches.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            )}
            <select className="input" style={{ width: "auto", minWidth: 160 }} value={filter} onChange={(e) => setFilter(e.target.value)}>
              <option value="all">Todos los clientes</option>
              {clientsForFilter.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </div>
        </div>
      </div>

      <div className="fb-list">
        {shown.map((f) => (
          <div className={`fb-card ${f.read ? "" : "unread"}`} key={f.id}>
            <div className="fb-card-top">
              <div className="fb-meta">
                <span className="fb-client">{!f.read && <span className="fb-dot"></span>}{nameOf(f.clientId)}</span>
                <span className="fb-tags">
                  {superMode && <span className="fb-tag"><Icon name="user" style={{ width: 12, height: 12 }} /> {coachNameOf(f.clientId)}</span>}
                  <span className="fb-tag coral"><Icon name="dumbbell" style={{ width: 12, height: 12 }} /> {f.routineTitle}</span>
                  <span className="fb-tag"><Icon name="calendar" style={{ width: 12, height: 12 }} /> Día {f.date} · {f.calTitle}</span>
                </span>
              </div>
              <span className="fb-date">{fmtDate(f.createdAt)}</span>
            </div>
            <p className="fb-text">{f.text}</p>
            <div className="fb-actions">
              <button className="fb-btn" onClick={() => toggleRead(f)}><Icon name={f.read ? "mail" : "check"} style={{ width: 14, height: 14 }} /> {f.read ? "Marcar no leído" : "Marcar leído"}</button>
              <button className="fb-btn danger" onClick={() => setConfirm(f)}><Icon name="trash" style={{ width: 14, height: 14 }} /> Eliminar</button>
            </div>
          </div>
        ))}
        {shown.length === 0 && <div className="panel"><p className="sub" style={{ margin: 0 }}>Sin feedback para mostrar.</p></div>}
      </div>

      <Confirm open={!!confirm} text="¿Eliminar este feedback?" onNo={() => setConfirm(null)}
        onYes={async () => { await window.DB.deleteFeedback(confirm.id); setConfirm(null); toast("Feedback eliminado"); load(); }} />
    </div>
  );
}

/* ---------------- Dashboard ---------------- */
function DashboardPanel({ goTo, coachId }) {
  const [data, setData] = useState(null);
  const [coach, setCoach] = useState(null);
  useEffect(() => {
    if (coachId) window.DB.getCoach(coachId).then(setCoach);
    Promise.all([window.DB.listClients(coachId), window.DB.listRoutines(), window.DB.listFeedback(coachId), window.DB.listCompRecords(coachId)]).then(([clients, routines, feedback, records]) => {
      const blocked = clients.filter((c) => c.blocked).length;
      const calendars = clients.reduce((n, c) => n + (c.calendars || []).length, 0);
      const recVisible = records.filter((r) => !r.hidden);
      setData({
        clients: clients.length,
        active: clients.length - blocked,
        blocked,
        workouts: routines.filter((r) => r.intensity !== "recovery").length,
        recoveries: routines.filter((r) => r.intensity === "recovery").length,
        calendars,
        feedback: feedback.length,
        feedbackUnread: feedback.filter((f) => !f.read).length,
        records: recVisible.length,
        recordsUnread: recVisible.filter((r) => !r.read).length,
      });
    });
  }, []);
  if (!data) return <div className="panel">Cargando…</div>;

  const Metric = ({ icon, value, label, accent, sub, onClick }) => (
    <div className={`metric ${onClick ? "clickable" : ""}`} onClick={onClick}>
      <span className="metric-ic"><MetricIcon name={icon} /></span>
      <div className="metric-v">{value}</div>
      <div className="metric-l">{label}</div>
      {sub && <div className="metric-sub">{sub}</div>}
    </div>
  );

  return (
    <div>
      {coachId
        ? <div className="panel coach-hero">
            <span className="coach-hero-avatar">{coach && coach.photo ? <img src={coach.photo} alt={coach.name} /> : <Icon name="user" style={{ width: 30, height: 30, color: "#b3b3b3" }} />}</span>
            <div className="coach-hero-info">
              <div className="coach-hero-hi">Hola,</div>
              <div className="coach-hero-name">{coach ? coach.name : "Coach"}</div>
              <div className="coach-hero-sub">Este es tu panel · {data.clients} cliente(s) a tu cargo</div>
            </div>
          </div>
        : <div className="panel">
            <h3>Dashboard</h3>
            <div className="sub" style={{ margin: 0 }}>Resumen general de ONLYCLEAN</div>
          </div>}

      <div className="metrics-grid">
        <Metric icon="user" value={data.clients} label="Clientes" accent="var(--coral)" onClick={() => goTo("clients")}
          sub={<span><span className="dot-active"></span>{data.active} activos · <span className="dot-blocked"></span>{data.blocked} bloqueados</span>} />
        <Metric icon="chat" value={data.feedback} label="Feedback recibido" accent="#2fa66a" onClick={() => goTo("feedback")}
          sub={data.feedbackUnread > 0 ? <span><span className="dot-blocked"></span>{data.feedbackUnread} sin leer</span> : <span>Todo al día</span>} />
        <Metric icon="clock" value={data.records} label="Registros de competencia" accent="#5b6b7a" onClick={() => goTo("records")}
          sub={data.recordsUnread > 0 ? <span><span className="dot-blocked"></span>{data.recordsUnread} sin leer</span> : <span>Todo al día</span>} />
        <Metric icon="calendar" value={data.calendars} label="Planificaciones asignadas" accent="#5b6b7a" onClick={() => goTo("clients")} />
        <Metric icon="dumbbell" value={data.workouts} label="Rutinas de entrenamiento" accent="#2b2b2b" onClick={() => goTo("routines")} />
        <Metric icon="snowflake" value={data.recoveries} label="Tipos de recuperación" accent="#8b97a4" onClick={() => goTo("routines")} />
      </div>

      <div className="panel">
        <h3 style={{ fontSize: 16 }}>Accesos directos</h3>
        <div className="sub">Crea rápido sin salir del resumen.</div>
        <div className="quick-actions">
          <button className="quick-btn" onClick={() => goTo("clients")}><span className="metric-ic"><Icon name="plus" style={{ width: 18, height: 18 }} /></span>Nuevo cliente</button>
          <button className="quick-btn" onClick={() => goTo("routines")}><span className="metric-ic"><Icon name="plus" style={{ width: 18, height: 18 }} /></span>Nueva rutina</button>
        </div>
      </div>
    </div>
  );
}

/* ---------------- Competition results board (dashboard) ---------------- */
const _CRB_WD = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"];
const _CRB_MO = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
function crbDate(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]);
  return `${_CRB_WD[(dt.getDay() + 6) % 7]} ${+m[3]} de ${_CRB_MO[+m[2] - 1]}`;
}
function RegList() { return null; }
function CompetitionResultsBoard({ coachId, goTo }) {
  const [stats, setStats] = useState(null);
  useEffect(() => {
    window.DB.listCompRecords(coachId).then((recs) => {
      const visible = recs.filter((r) => !r.hidden);
      const clients = new Set(visible.map((r) => r.clientId));
      setStats({ total: visible.length, unread: visible.filter((r) => !r.read).length, clients: clients.size });
    });
  }, [coachId]);
  if (!stats) return null;
  return (
    <div className="panel">
      <div className="row-between" style={{ flexWrap: "wrap", gap: 10 }}>
        <div>
          <h3 style={{ fontSize: 16 }}>Registros de competencia</h3>
          <div className="sub" style={{ margin: 0 }}>
            {stats.total} registro(s) de {stats.clients} cliente(s){stats.unread > 0 ? ` · ${stats.unread} sin leer` : " · todo al día"}
          </div>
        </div>
        <Pill variant="ghost" onClick={() => goTo && goTo("records")}>Ver registros{stats.unread > 0 ? ` (${stats.unread})` : ""}</Pill>
      </div>
    </div>
  );
}

/* ---------------- Records panel (detail, grouped by client, collapsible) ---------------- */
function RecordsPanel({ onChange, coachId, canDelete }) {
  const superMode = !coachId;
  const [recs, setRecs] = useState(null);
  const [coaches, setCoaches] = useState([]);
  const [coachFilter, setCoachFilter] = useState("all");
  const [open, setOpen] = useState({});
  const [showHidden, setShowHidden] = useState(false);
  const [confirm, setConfirm] = useState(null);
  const toast = useToast();

  const load = () => Promise.all([window.DB.listCompRecords(coachId), superMode ? window.DB.listCoaches() : Promise.resolve([])])
    .then(([rs, cs]) => { setRecs(rs); setCoaches(cs); onChange && onChange(); });
  useEffect(() => { load(); }, []);
  if (!recs) return <div className="panel">Cargando…</div>;

  let filtered = showHidden ? recs.filter((r) => r.hidden) : recs.filter((r) => !r.hidden);
  if (superMode && coachFilter !== "all") filtered = filtered.filter((r) => r.coachId === coachFilter);

  // group by client
  const byClient = {};
  filtered.forEach((r) => { (byClient[r.clientId] = byClient[r.clientId] || { name: r.clientName, comp: r.compName, items: [] }).items.push(r); });
  const groups = Object.entries(byClient);
  const unreadTotal = recs.filter((r) => !r.read && !r.hidden).length;

  async function toggleRead(r) { await window.DB.setCompRecordRead(r.clientId, r.id, !r.read); load(); }
  async function toggleHidden(r) { await window.DB.setCompRecordHidden(r.clientId, r.id, !r.hidden); toast(r.hidden ? "Mostrado de nuevo" : "Registro oculto"); load(); }

  return (
    <div>
      <div className="panel">
        <div className="row-between" style={{ flexWrap: "wrap", gap: 12 }}>
          <div><h3>Registros de competencia</h3><div className="sub" style={{ margin: 0 }}>{unreadTotal} sin leer · capturados por los clientes en sus circuitos</div></div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            {superMode && (
              <select className="input" style={{ width: "auto", minWidth: 150 }} value={coachFilter} onChange={(e) => setCoachFilter(e.target.value)}>
                <option value="all">Todos los coaches</option>
                {coaches.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            )}
            <button className={`fb-btn ${showHidden ? "" : ""}`} onClick={() => setShowHidden((v) => !v)}><Icon name={showHidden ? "chat" : "x"} style={{ width: 14, height: 14 }} /> {showHidden ? "Ver activos" : "Ver ocultos"}</button>
          </div>
        </div>
      </div>

      {groups.length === 0 && <div className="panel"><p className="sub" style={{ margin: 0 }}>{showHidden ? "No hay registros ocultos." : "Aún no hay registros."}</p></div>}

      {groups.map(([cid, g]) => {
        const isOpen = open[cid] !== false; // default open
        const groupUnread = g.items.filter((r) => !r.read).length;
        return (
          <div className="panel rec-group" key={cid}>
            <button className="rec-group-head" onClick={() => setOpen((o) => ({ ...o, [cid]: !isOpen }))}>
              <span className="rec-group-name"><Icon name="user" style={{ width: 16, height: 16 }} /> {g.name}{g.comp && <span className="crb-comp"> · {g.comp}</span>}</span>
              <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
                {groupUnread > 0 && <span className="nav-badge" style={{ position: "static" }}>{groupUnread}</span>}
                <span className="rec-count">{g.items.length}</span>
                <Icon name="chevronDown" style={{ width: 16, height: 16, transform: isOpen ? "rotate(180deg)" : "none", color: "var(--muted)" }} />
              </span>
            </button>
            {isOpen && (
              <div className="rec-items">
                {g.items.map((r) => (
                  <div className={`rec-item ${r.read ? "" : "unread"}`} key={r.id}>
                    <div className="rec-item-top">
                      <span className={`fb-tag ${r.kind === "meta" ? "coral" : ""}`}>{r.kind === "meta" ? "Circuito Meta" : "Circuito"} · {r.circuitTitle}</span>
                      <span className="crb-date">{crbDate(r.date)}</span>
                    </div>
                    <p className="rec-text">{r.text}</p>
                    <div className="fb-actions">
                      <button className="fb-btn" onClick={() => toggleRead(r)}><Icon name={r.read ? "mail" : "check"} style={{ width: 14, height: 14 }} /> {r.read ? "No leído" : "Leído"}</button>
                      <button className="fb-btn" onClick={() => toggleHidden(r)}><Icon name="x" style={{ width: 14, height: 14 }} /> {r.hidden ? "Mostrar" : "Ocultar"}</button>
                      {canDelete && <button className="fb-btn danger" onClick={() => setConfirm(r)}><Icon name="trash" style={{ width: 14, height: 14 }} /> Eliminar</button>}
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        );
      })}

      <Confirm open={!!confirm} text="¿Eliminar este registro? Se borrará del historial del cliente." onNo={() => setConfirm(null)}
        onYes={async () => { await window.DB.deleteCompRecord(confirm.clientId, confirm.id); setConfirm(null); toast("Registro eliminado"); load(); }} />
    </div>
  );
}

/* ---------------- Clients list ---------------- */
function ClientsPanel({ coachId }) {
  const superMode = !coachId;
  const [clients, setClients] = useState(null);
  const [coaches, setCoaches] = useState([]);
  const [filter, setFilter] = useState("all");
  const [editing, setEditing] = useState(null); // client object or "new"
  const [confirm, setConfirm] = useState(null);
  const toast = useToast();

  const load = () => Promise.all([window.DB.listClients(coachId), superMode ? window.DB.listCoaches() : Promise.resolve([])])
    .then(([cl, cs]) => { setClients(cl); setCoaches(cs); });
  useEffect(() => { load(); }, []);

  if (editing) return <ClientEditor client={editing === "new" ? null : editing} coachId={coachId} coaches={coaches} superMode={superMode} onClose={() => { setEditing(null); load(); }} />;
  if (!clients) return <div className="panel">Cargando…</div>;

  const coachName = (id) => (coaches.find((c) => c.id === id) || {}).name || "Sin coach";
  const shown = filter === "all" ? clients : clients.filter((c) => c.coachId === filter);

  return (
    <div className="panel">
      <div className="row-between" style={{ marginBottom: 16, flexWrap: "wrap", gap: 12 }}>
        <div><h3>Clientes</h3><div className="sub" style={{ margin: 0 }}>{clients.length} cliente(s){superMode ? " · todos los coaches" : ""}</div></div>
        <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          {superMode && coaches.length > 0 && (
            <select className="input" style={{ width: "auto", minWidth: 150 }} value={filter} onChange={(e) => setFilter(e.target.value)}>
              <option value="all">Todos los coaches</option>
              {coaches.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          )}
          <Pill onClick={() => setEditing("new")}><Icon name="plus" style={{ width: 16, height: 16 }} /> Nuevo cliente</Pill>
        </div>
      </div>
      <div className="adm-list">
        {shown.map((c) => (
          <div className="adm-list-item" key={c.id}>
            <span className="av">{c.photo ? <img src={c.photo} alt="" /> : <Icon name="user" style={{ width: 18, height: 18 }} />}</span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="nm">{c.name} {c.blocked && <span className="status-chip">Bloqueado</span>}</div>
              <div className="em">{c.email} · {(c.calendars || []).length} planificación(es){superMode ? ` · ${coachName(c.coachId)}` : ""}</div>
            </div>
            <button className="icon-btn" title="Editar" onClick={() => setEditing(c)}><Icon name="edit" style={{ width: 16, height: 16 }} /></button>
            <button className="icon-btn danger" title="Eliminar" onClick={() => setConfirm(c)}><Icon name="trash" style={{ width: 16, height: 16 }} /></button>
          </div>
        ))}
        {shown.length === 0 && <p className="sub">Aún no hay clientes. Crea el primero.</p>}
      </div>
      <Confirm open={!!confirm} text={`¿Eliminar a ${confirm?.name}? Se borrarán sus calendarios.`}
        onNo={() => setConfirm(null)}
        onYes={async () => { await window.DB.deleteClient(confirm.id); setConfirm(null); toast("Cliente eliminado"); load(); }} />
    </div>
  );
}

/* ---------------- Client editor ---------------- */
function ClientEditor({ client, coachId, coaches, superMode, onClose }) {
  const [c, setC] = useState(() => client ? JSON.parse(JSON.stringify(client)) : { name: "", email: "", password: "", photo: "", welcome: "", objectives: [""], blocked: false, coachId: coachId || null, calendars: [] });
  const [routines, setRoutines] = useState([]);
  const [editingCal, setEditingCal] = useState(null);
  const [editingContent, setEditingContent] = useState(null); // null o clave de sección
  const [editingComp, setEditingComp] = useState(false);
  const toast = useToast();
  useEffect(() => { window.DB.listRoutines().then(setRoutines); }, []);
  // prefill per-client content from the global base template (and default visibility)
  useEffect(() => {
    if (!c.content || !c.contentShow || !c.competition || !c.profile) {
      window.DB.getContent().then((tmpl) => setC((p) => ({
        ...p,
        content: p.content || tmpl,
        contentShow: p.contentShow || { methodology: true, nutrition: true, recovery: true, competition: true },
        competition: p.competition || window.DB.newCompetition(),
        profile: p.profile || window.DB.newProfile(),
      })));
    }
  }, []);

  const set = (k, v) => setC((p) => ({ ...p, [k]: v }));
  const setP = (k, v) => setC((p) => ({ ...p, profile: { ...(p.profile || {}), [k]: v } }));
  const setPYN = (k, patch) => setC((p) => ({ ...p, profile: { ...(p.profile || {}), [k]: { ...((p.profile || {})[k] || {}), ...patch } } }));
  const setObj = (i, v) => setC((p) => { const o = [...p.objectives]; o[i] = v; return { ...p, objectives: o }; });
  const addObj = () => setC((p) => ({ ...p, objectives: [...p.objectives, ""] }));
  const delObj = (i) => setC((p) => ({ ...p, objectives: p.objectives.filter((_, j) => j !== i) }));

  async function save() {
    if (!c.name.trim() || !c.email.trim()) { toast("Nombre y correo son obligatorios"); return; }
    if (superMode && !c.coachId) { toast("Asigna un coach al cliente"); return; }
    const payload = { ...c, coachId: c.coachId || coachId || null, objectives: c.objectives.filter((o) => o.trim()) };
    await window.DB.saveClient(payload);
    toast("Cliente guardado");
    onClose();
  }

  if (editingContent) {
    const labels = { methodology: "Metodología", nutrition: "Alimentación", recovery: "Recuperación" };
    return (
      <div>
        <div className="panel">
          <div className="row-between" style={{ marginBottom: 4 }}>
            <BackPill onClick={() => setEditingContent(null)} label={`Volver a ${c.name || "cliente"}`} />
            <Pill onClick={() => { setEditingContent(null); toast("Listo — recuerda Guardar el cliente"); }}><Icon name="check" style={{ width: 16, height: 16 }} /> Aplicar</Pill>
          </div>
          <h3>{labels[editingContent]} de {c.name || "el cliente"}</h3>
          <div className="sub" style={{ margin: 0 }}>Los cambios se guardan al pulsar “Guardar” en el cliente.</div>
        </div>
        <ClientContentEditor
          only={editingContent}
          content={c.content}
          show={c.contentShow || { methodology: true, nutrition: true, recovery: true }}
          onContent={(nc) => set("content", nc)}
          onShow={(ns) => set("contentShow", ns)}
        />
      </div>
    );
  }

  if (editingComp) {
    const comp = c.competition || window.DB.newCompetition();
    return (
      <div>
        <div className="panel">
          <div className="row-between" style={{ marginBottom: 4 }}>
            <BackPill onClick={() => setEditingComp(false)} label={`Volver a ${c.name || "cliente"}`} />
            <Pill onClick={() => { setEditingComp(false); toast("Listo — recuerda Guardar el cliente"); }}><Icon name="check" style={{ width: 16, height: 16 }} /> Aplicar</Pill>
          </div>
          <h3>Próxima competencia de {c.name || "el cliente"}</h3>
          <div className="sub" style={{ margin: 0 }}>Datos de la competencia, circuitos (imagen) y su Circuito Meta. Se guarda al pulsar “Guardar” en el cliente.</div>
        </div>
        <CompetitionEditor competition={comp} onChange={(nc) => set("competition", nc)} />
      </div>
    );
  }

  if (editingCal !== null) {
    return <CalendarEditor
      clientId={c.id}
      clientName={c.name}
      calendar={editingCal === "new" ? window.DB.newCalendar() : editingCal}
      routines={routines}
      onClose={async () => { const fresh = await window.DB.getClient(c.id); if (fresh) setC(fresh); setEditingCal(null); }}
    />;
  }

  return (
    <div>
      <div className="panel">
        <div className="row-between" style={{ marginBottom: 16 }}>
          <BackPill onClick={onClose} label="Volver a clientes" />
          <Pill onClick={save}><Icon name="check" style={{ width: 16, height: 16 }} /> Guardar</Pill>
        </div>
        <h3>{client ? "Editar cliente" : "Nuevo cliente"}</h3>
        <div className="sub">Datos de acceso y objetivos personales.</div>

        <div className="grid2">
          <div className="field"><label>Nombre</label><input className="input" value={c.name} onChange={(e) => set("name", e.target.value)} /></div>
          <div className="field"><label>Correo (usuario)</label><input className="input" type="email" value={c.email} onChange={(e) => set("email", e.target.value)} /></div>
          <div className="field"><label>Contraseña</label><input className="input" value={c.password} onChange={(e) => set("password", e.target.value)} /></div>
        </div>
        <PhotoUpload value={c.photo} onChange={(v) => set("photo", v)} label="Foto del cliente" />
        <div className="field"><label>Mensaje de bienvenida</label><textarea className="input" value={c.welcome} onChange={(e) => set("welcome", e.target.value)} /></div>

        {superMode && (
          <div className="field"><label>Coach asignado</label>
            <select className="input" value={c.coachId || ""} onChange={(e) => set("coachId", e.target.value || null)}>
              <option value="">— Selecciona un coach —</option>
              {(coaches || []).map((co) => <option key={co.id} value={co.id}>{co.name}</option>)}
            </select>
          </div>
        )}

        <div className={`access-toggle ${c.blocked ? "off" : ""}`}>
          <div className="at-text">
            <div className="at-title">{c.blocked ? "Acceso bloqueado" : "Acceso activo"}</div>
            <div className="at-sub">{c.blocked ? "El cliente verá un aviso para contactar a su entrenador." : "El cliente puede entrar y ver su planificación."}</div>
          </div>
          <button type="button" className={`switch ${c.blocked ? "" : "on"}`} role="switch" aria-checked={!c.blocked} onClick={() => set("blocked", !c.blocked)}>
            <span className="knob"></span>
          </button>
        </div>

        <label className="mini" style={{ fontWeight: 700, color: "var(--ink-soft)" }}>OBJETIVOS PERSONALES</label>
        <div style={{ display: "flex", flexDirection: "column", gap: 8, margin: "8px 0 4px" }}>
          {c.objectives.map((o, i) => (
            <div key={i} style={{ display: "flex", gap: 8 }}>
              <input className="input" value={o} onChange={(e) => setObj(i, e.target.value)} placeholder={`Objetivo ${i + 1}`} />
              <button className="icon-btn danger" onClick={() => delObj(i)}><Icon name="trash" style={{ width: 15, height: 15 }} /></button>
            </div>
          ))}
        </div>
        <button className="add-row" onClick={addObj}><Icon name="plus" style={{ width: 14, height: 14 }} /> Añadir objetivo</button>
      </div>

      {c.profile && <ProfileEditor profile={c.profile} setP={setP} setPYN={setPYN}
        onEval={(ev) => set("profile", { ...c.profile, evaluation: ev })} />}

      {/* calendars */}
      <div className="panel">
        <div className="row-between" style={{ marginBottom: 14 }}>
          <div><h3>Planificaciones</h3><div className="sub" style={{ margin: 0 }}>Un cliente puede tener varias planificaciones/meses.</div></div>
          {c.id ? <Pill variant="ghost" onClick={() => setEditingCal("new")}><Icon name="plus" style={{ width: 16, height: 16 }} /> Nueva planificación</Pill>
                : <span className="mini">Guarda el cliente primero para añadir planificaciones.</span>}
        </div>
        <div className="adm-list">
          {(c.calendars || []).map((cal) => (
            <div className="adm-list-item" key={cal.id}>
              <span className="av"><Icon name="calendar" style={{ width: 18, height: 18 }} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="nm">{cal.title} {cal.active && <span className="status-chip" style={{ color: "#2fa66a", background: "#e7f5ed", borderColor: "#bfe6cf" }}>Actual</span>}</div>
                <div className="em">{cal.monthLabel} · {cal.weeks.length} semana(s)</div>
              </div>
              <button className="icon-btn" onClick={() => setEditingCal(cal)}><Icon name="edit" style={{ width: 16, height: 16 }} /></button>
              <button className="icon-btn danger" onClick={async () => { await window.DB.deleteCalendar(c.id, cal.id); const fresh = await window.DB.getClient(c.id); setC(fresh); toast("Calendario eliminado"); }}><Icon name="trash" style={{ width: 16, height: 16 }} /></button>
            </div>
          ))}
          {(c.calendars || []).length === 0 && c.id && <p className="sub">Sin calendarios todavía.</p>}
        </div>
      </div>

      {/* content */}
      {c.content && [{ key: "methodology", label: "Metodología", ic: "dumbbell" }, { key: "nutrition", label: "Alimentación", ic: "apple" }, { key: "recovery", label: "Recuperación", ic: "heart" }].map((a) => {
        const visible = !c.contentShow || c.contentShow[a.key] !== false;
        return (
          <div className="panel" key={a.key}>
            <div className="row-between" style={{ gap: 12, flexWrap: "wrap" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <span className="av"><Icon name={a.ic} style={{ width: 18, height: 18 }} /></span>
                <h3 style={{ fontSize: 16 }}>{a.label}</h3>
              </div>
              <Pill variant="ghost" className="sm" onClick={() => setEditingContent(a.key)}><Icon name="edit" style={{ width: 14, height: 14 }} /> Editar</Pill>
            </div>
            <div className={`access-toggle ${visible ? "" : "off"}`} style={{ marginTop: 14, marginBottom: 0 }}>
              <div className="at-text">
                <div className="at-title">{visible ? "Sección activa" : "Sección oculta"}</div>
                <div className="at-sub">{visible ? "El cliente ve este botón en su inicio." : "No aparece en el inicio del cliente."}</div>
              </div>
              <button type="button" className={`switch ${visible ? "on" : ""}`} role="switch" aria-checked={visible} onClick={() => set("contentShow", { ...(c.contentShow || {}), [a.key]: !visible })}>
                <span className="knob"></span>
              </button>
            </div>
          </div>
        );
      })}
      {!c.content && <div className="panel"><span className="mini">Cargando plantilla…</span></div>}

      {/* competition */}
      <div className="panel">
        <div className="row-between" style={{ gap: 12, flexWrap: "wrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span className="av"><Icon name="dumbbell" style={{ width: 18, height: 18 }} /></span>
            <h3 style={{ fontSize: 16 }}>Próxima competencia</h3>
          </div>
          {c.id
            ? <Pill variant="ghost" className="sm" onClick={() => setEditingComp(true)}><Icon name="edit" style={{ width: 14, height: 14 }} /> Editar</Pill>
            : <span className="mini">Guarda el cliente primero.</span>}
        </div>
        {(() => {
          const visible = !c.contentShow || c.contentShow.competition !== false;
          return (
            <div className={`access-toggle ${visible ? "" : "off"}`} style={{ marginTop: 14, marginBottom: 0 }}>
              <div className="at-text">
                <div className="at-title">{visible ? "Sección activa" : "Sección oculta"}</div>
                <div className="at-sub">{visible ? "El cliente ve este botón en su inicio." : "No aparece en el inicio del cliente."}</div>
              </div>
              <button type="button" className={`switch ${visible ? "on" : ""}`} role="switch" aria-checked={visible} onClick={() => set("contentShow", { ...(c.contentShow || {}), competition: !visible })}>
                <span className="knob"></span>
              </button>
            </div>
          );
        })()}
      </div>
    </div>
  );
}

/* ---------------- Calendar editor ---------------- */
const TYPE_OPTS = [
  { v: "high", l: "High", c: "var(--coral)" },
  { v: "low", l: "Low", c: "var(--low)" },
  { v: "rest", l: "Rest", c: "#434343" },
  { v: "empty", l: "—", c: "#e2e2e2" },
];
function CalendarEditor({ clientId, clientName, calendar, routines, onClose }) {
  const [cal, setCal] = useState(() => JSON.parse(JSON.stringify(calendar)));
  const toast = useToast();
  const dow = ["L", "M", "M", "J", "V", "S", "D"];
  const workouts = routines.filter((r) => r.intensity !== "recovery");
  const recoveries = routines.filter((r) => r.intensity === "recovery");

  const setField = (k, v) => setCal((p) => ({ ...p, [k]: v }));
  const setDay = (wi, di, patch) => setCal((p) => {
    const weeks = p.weeks.map((w) => w.map((d) => ({ ...d })));
    weeks[wi][di] = { ...weeks[wi][di], ...patch };
    return { ...p, weeks };
  });
  const addWeek = () => setCal((p) => ({ ...p, weeks: [...p.weeks, Array.from({ length: 7 }, (_, i) => ({ date: i + 1, type: "empty", routineId: null, recoveryId: null, otherMonth: false }))] }));
  const delWeek = (wi) => setCal((p) => ({ ...p, weeks: p.weeks.filter((_, i) => i !== wi) }));

  async function save() {
    await window.DB.saveCalendar(clientId, cal);
    toast("Calendario guardado");
    onClose();
  }

  return (
    <div className="panel">
      <div className="row-between" style={{ marginBottom: 16 }}>
        <BackPill onClick={onClose} label={`Volver a ${clientName}`} />
        <Pill onClick={save}><Icon name="check" style={{ width: 16, height: 16 }} /> Guardar planificación</Pill>
      </div>
      <h3>{calendar.id ? "Editar planificación" : "Nueva planificación"}</h3>
      <div className="sub">Marca el tipo de cada día (High / Low / Rest), enlaza su rutina y, si aplica, una recuperación recomendada.</div>

      <div className="grid2">
        <div className="field"><label>Título (planificación)</label><input className="input" value={cal.title} onChange={(e) => setField("title", e.target.value)} placeholder="Planificación 1" /></div>
        <div className="field"><label>Mes / etiqueta</label><input className="input" value={cal.monthLabel} onChange={(e) => setField("monthLabel", e.target.value)} placeholder="Junio – Julio 2026" /></div>
      </div>

      <div className={`access-toggle ${cal.active ? "" : "off"}`} style={{ marginBottom: 16 }}>
        <div className="at-text">
          <div className="at-title">{cal.active ? "Planificación activa (actual)" : "Planificación en histórico"}</div>
          <div className="at-sub">{cal.active ? "Es el que el cliente ve como actual." : "El cliente solo lo verá en su histórico (solo lectura)."}</div>
        </div>
        <button type="button" className={`switch ${cal.active ? "on" : ""}`} role="switch" aria-checked={!!cal.active} onClick={() => setField("active", !cal.active)}>
          <span className="knob"></span>
        </button>
      </div>

      <div className="cal-edit" style={{ marginBottom: 8 }}>
        {dow.map((d, i) => <div key={i} style={{ textAlign: "center", fontWeight: 700, fontSize: 12, color: "var(--muted)" }}>{d}</div>)}
      </div>

      {cal.weeks.map((week, wi) => (
        <div key={wi} style={{ marginBottom: 12 }}>
          <div className="row-between" style={{ marginBottom: 5 }}>
            <span className="mini" style={{ fontWeight: 700 }}>Semana {wi + 1}</span>
            <button className="icon-btn danger" style={{ width: 26, height: 26 }} onClick={() => delWeek(wi)}><Icon name="trash" style={{ width: 13, height: 13 }} /></button>
          </div>
          <div className="cal-edit">
            {week.map((day, di) => {
              const tc = TYPE_OPTS.find((t) => t.v === day.type) || TYPE_OPTS[3];
              return (
                <div className="cal-edit-cell" key={di} style={{ borderColor: day.type === "empty" ? "var(--line)" : tc.c, borderWidth: 1.5 }}>
                  <input value={day.date} onChange={(e) => setDay(wi, di, { date: e.target.value })} />
                  <select value={day.type} onChange={(e) => setDay(wi, di, { type: e.target.value })} style={{ color: "#fff", background: tc.c, fontWeight: 700 }}>
                    {TYPE_OPTS.map((t) => <option key={t.v} value={t.v} style={{ background: "#fff", color: "#000" }}>{t.l}</option>)}
                  </select>
                  <select value={day.routineId || ""} onChange={(e) => setDay(wi, di, { routineId: e.target.value || null })} title="Rutina del día">
                    <option value="">Sin rutina</option>
                    {workouts.map((r) => <option key={r.id} value={r.id}>{r.title}</option>)}
                  </select>
                  <select value={day.recoveryId || ""} onChange={(e) => setDay(wi, di, { recoveryId: e.target.value || null })} title="Recuperación recomendada (opcional)" style={{ color: day.recoveryId ? "#fff" : undefined, background: day.recoveryId ? "#8b97a4" : undefined, fontWeight: day.recoveryId ? 700 : undefined }}>
                    <option value="" style={{ background: "#fff", color: "#000" }}>Sin recuperación</option>
                    {recoveries.map((r) => <option key={r.id} value={r.id} style={{ background: "#fff", color: "#000" }}>+ {r.title}</option>)}
                  </select>
                </div>
              );
            })}
          </div>
        </div>
      ))}
      <button className="add-row" onClick={addWeek}><Icon name="plus" style={{ width: 14, height: 14 }} /> Añadir semana</button>
    </div>
  );
}

/* ---------------- Profile editor (ficha del cliente) ---------------- */
const EVAL_ICON_OPTS = [
  { v: "icon-objetivos.svg", l: "Objetivos" }, { v: "icon-rayo.svg", l: "Rayo" },
  { v: "icon-metodo.svg", l: "Método" }, { v: "icon-pila.svg", l: "Pila" },
  { v: "icon-escudo-1.svg", l: "Escudo" }, { v: "icon-recuperacion.svg", l: "Recuperación" },
];
const LEVEL_OPTS = ["Principiante", "Intermedio", "Avanzado", "Élite"];

function YesNoField({ label, data, onChange }) {
  const d = data || { value: false, detail: "" };
  return (
    <div className="field">
      <label>{label}</label>
      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
        <button type="button" className={`switch ${d.value ? "on" : ""}`} role="switch" aria-checked={!!d.value} onClick={() => onChange({ ...d, value: !d.value })} style={{ flex: "0 0 auto" }}>
          <span className="knob"></span>
        </button>
        <span className="mini" style={{ flex: "0 0 28px", fontWeight: 700 }}>{d.value ? "Sí" : "No"}</span>
        <input className="input" style={{ flex: 1 }} value={d.detail || ""} onChange={(e) => onChange({ ...d, detail: e.target.value })} placeholder="Detalle (opcional)" />
      </div>
    </div>
  );
}

function ProfileEditor({ profile, setP, setPYN, onEval }) {
  const p = profile;
  const evals = p.evaluation || [];
  const setEvalCard = (i, patch) => onEval(evals.map((e, j) => j === i ? { ...e, ...patch } : e));
  const setEx = (ci, ei, v) => onEval(evals.map((e, j) => j === ci ? { ...e, exercises: e.exercises.map((x, k) => k === ei ? v : x) } : e));

  return (
    <div>
      <div className="panel">
        <h3 style={{ fontSize: 16 }}>Datos generales</h3>
        <div className="sub">Edad, medidas y nacionalidad (se muestran en su perfil).</div>
        <div className="grid2">
          <div className="field"><label>Edad</label><input className="input" value={p.age} onChange={(e) => setP("age", e.target.value)} placeholder="28" /></div>
          <div className="field"><label>Estatura (cm)</label><input className="input" value={p.height} onChange={(e) => setP("height", e.target.value)} placeholder="178" /></div>
          <div className="field"><label>Peso (kg)</label><input className="input" value={p.weight} onChange={(e) => setP("weight", e.target.value)} placeholder="78" /></div>
          <div className="field"><label>Nacionalidad</label><input className="input" value={p.nationality} onChange={(e) => setP("nationality", e.target.value)} placeholder="México" /></div>
        </div>
        <div className="field"><label>Nivel (calisthenics level)</label>
          <select className="input" value={p.level} onChange={(e) => setP("level", e.target.value)}>
            {LEVEL_OPTS.map((l) => <option key={l} value={l}>{l}</option>)}
          </select>
        </div>
      </div>

      <div className="panel">
        <h3 style={{ fontSize: 16 }}>Antecedentes</h3>
        <div className="field"><label>Tiempo que lleva entrenando</label><input className="input" value={p.experience} onChange={(e) => setP("experience", e.target.value)} placeholder="10 años en calistenia" /></div>
        <div className="field"><label>Lesiones y/o padecimientos</label><textarea className="input" value={p.injuries} onChange={(e) => setP("injuries", e.target.value)} /></div>
        <YesNoField label="¿Lleva alguna dieta especial?" data={p.diet} onChange={(v) => setPYN("diet", v)} />
        <YesNoField label="¿Consume lácteos?" data={p.dairy} onChange={(v) => setPYN("dairy", v)} />
        <YesNoField label="¿Adicción al azúcar?" data={p.sugar} onChange={(v) => setPYN("sugar", v)} />
        <YesNoField label="¿Va a fisioterapia con regularidad?" data={p.physio} onChange={(v) => setPYN("physio", v)} />
      </div>

      <div className="panel">
        <h3 style={{ fontSize: 16 }}>Horas de sueño</h3>
        <div className="field"><label>Horas de sueño al día</label><input className="input" value={p.sleepHours} onChange={(e) => setP("sleepHours", e.target.value)} placeholder="7-8" /></div>
        <YesNoField label="¿Dificultades para dormir?" data={p.sleepTrouble} onChange={(v) => setPYN("sleepTrouble", v)} />
      </div>

      <div className="panel">
        <h3 style={{ fontSize: 16 }}>Tiempo y espacio de entrenamiento</h3>
        <div className="field"><label>Días disponibles para entrenar</label><input className="input" value={p.trainDays} onChange={(e) => setP("trainDays", e.target.value)} placeholder="Lunes a sábado" /></div>
        <div className="field"><label>Tiempo al día disponible</label><input className="input" value={p.trainTime} onChange={(e) => setP("trainTime", e.target.value)} placeholder="90 min al día" /></div>
        <div className="field"><label>Lugar de entrenamiento</label><input className="input" value={p.trainPlace} onChange={(e) => setP("trainPlace", e.target.value)} placeholder="Parque y gimnasio" /></div>
        <YesNoField label="¿Tiene todo el equipo necesario?" data={p.equipment} onChange={(v) => setPYN("equipment", v)} />
      </div>

      <div className="panel">
        <div className="row-between" style={{ marginBottom: 4 }}>
          <h3 style={{ fontSize: 16 }}>Evaluación</h3>
          <Pill variant="ghost" className="sm" onClick={() => onEval([...evals, window.DB.newEvalCard()])}><Icon name="plus" style={{ width: 14, height: 14 }} /> Bloque</Pill>
        </div>
        <div className="sub">Máximos, máximo peso, etc. Cada bloque tiene icono, título, nota y ejercicios.</div>
        {evals.map((ev, ci) => (
          <div className="block-edit" key={ev.id}>
            <div className="row-between" style={{ marginBottom: 8 }}>
              <span className="mini" style={{ fontWeight: 700 }}>Bloque {ci + 1}</span>
              <button className="icon-btn danger" onClick={() => onEval(evals.filter((_, j) => j !== ci))}><Icon name="trash" style={{ width: 14, height: 14 }} /></button>
            </div>
            <div className="grid2">
              <div className="field"><label>Título</label><input className="input" value={ev.title} onChange={(e) => setEvalCard(ci, { title: e.target.value })} placeholder="Máximos" /></div>
              <div className="field"><label>Icono</label>
                <select className="input" value={ev.icon} onChange={(e) => setEvalCard(ci, { icon: e.target.value })}>
                  {EVAL_ICON_OPTS.map((o) => <option key={o.v} value={o.v}>{o.l}</option>)}
                </select>
              </div>
            </div>
            <div className="field"><label>Nota</label><input className="input" value={ev.note} onChange={(e) => setEvalCard(ci, { note: e.target.value })} placeholder="Repeticiones UB / 1RM" /></div>
            <label className="mini" style={{ fontWeight: 700, color: "var(--ink-soft)" }}>EJERCICIOS</label>
            <div style={{ display: "flex", flexDirection: "column", gap: 8, margin: "8px 0 4px" }}>
              {(ev.exercises || []).map((x, ei) => (
                <div key={ei} style={{ display: "flex", gap: 8 }}>
                  <input className="input" value={x} onChange={(e) => setEx(ci, ei, e.target.value)} placeholder="11 Muscle-up" />
                  <button className="icon-btn danger" onClick={() => setEvalCard(ci, { exercises: ev.exercises.filter((_, k) => k !== ei) })}><Icon name="trash" style={{ width: 14, height: 14 }} /></button>
                </div>
              ))}
            </div>
            <button className="add-row" onClick={() => setEvalCard(ci, { exercises: [...(ev.exercises || []), ""] })}><Icon name="plus" style={{ width: 14, height: 14 }} /> Añadir ejercicio</button>
          </div>
        ))}
        {evals.length === 0 && <p className="sub" style={{ margin: 0 }}>Sin bloques de evaluación.</p>}
      </div>
    </div>
  );
}

Object.assign(window, { AdminApp, CompetitionResultsBoard, RecordsPanel });
