// app.jsx — Panel de Agentes MDP (VDM-style layout)

const { useState, useEffect, useRef, useMemo } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#C87848",
  "density": "regular",
  "theme": "dark",
  "credits": 50,
  "sidebarStyle": "grouped"
}/*EDITMODE-END*/;

// ── Cuentas ──────────────────────────────────────────────────────────────────
// PRODUCCIÓN: el login y los datos del usuario vienen del backend (window.MDP_API).
// (Las cuentas de mentira del prototipo se eliminaron.)

// Convierte el usuario que devuelve el backend al formato que usa la app.
function mapUser(u) {
  return {
    id: u.id, email: u.email, name: u.nombre,
    admin: u.rol === "admin",
    accessLevel: u.nivel_acceso,
    plan: u.programa || (u.rol === "admin" ? "Administradora · Acceso total" : "Miembro"),
    consultas: u.consultas,
    password_temporal: !!u.password_temporal,
  };
}

const PALETTES = {
  dark: {
    bg: "#0F0E0B", bg2: "#17150F", bgCard: "#1C1A14",
    border: "#2C2820", borderSoft: "rgba(255,255,255,0.06)",
    text: "#FAF8F3", textMuted: "#9A9488", textDim: "#5E594E",
    sidebarBg: "#100F0C",
  },
  light: {
    bg: "#F7F5F0", bg2: "#EFEBE2", bgCard: "#FFFFFF",
    border: "#E3DDD1", borderSoft: "rgba(10,10,8,0.07)",
    text: "#0A0A08", textMuted: "#6E6A60", textDim: "#A8A294",
    sidebarBg: "#EFEBE2",
  },
};

// Returns initials for an agent's "icon badge" — used in sidebar list rows
function initials(name) {
  return name.split(/\s+/).filter(w => w.length > 2 && !["de","del","la","el","los","las"].includes(w.toLowerCase()))
    .slice(0,2).map(w => w[0].toUpperCase()).join("") || name.slice(0,2).toUpperCase();
}

// ── Logo (uses real PNG) ────────────────────────────────────────────────────
function MDPLogo({ theme, size = 30 }) {
  const src = theme === "dark" ? "assets/logo-mdp-white.png" : "assets/logo-mdp-black.png";
  return (
    <img src={src} alt="Marca de Poder"
         style={{ height: size, width: "auto", display: "block", opacity: 0.92 }} />
  );
}

// ── Login screen ─────────────────────────────────────────────────────
// ── Modal: cambiar mi propia clave ───────────────────────────────────────
function ChangePasswordModal({ t, p, forced, onClose, onDone }) {
  const [actual, setActual] = useState("");
  const [nueva, setNueva] = useState("");
  const [conf, setConf] = useState("");
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);
  const [ok, setOk] = useState(false);

  const inputStyle = {
    width: "100%", boxSizing: "border-box",
    background: p.bg2, border: `1px solid ${p.border}`, borderRadius: 10,
    color: p.text, fontFamily: "'Geist', sans-serif", fontSize: 15,
    padding: "12px 14px", outline: "none",
  };
  const labelStyle = {
    fontFamily: "'Geist', sans-serif", fontSize: 10.5, color: p.textMuted,
    letterSpacing: "0.16em", textTransform: "uppercase", fontWeight: 500,
    marginBottom: 7, display: "block",
  };

  const submit = async (e) => {
    e && e.preventDefault();
    if (busy) return;
    setErr("");
    if (nueva.length < 6) return setErr("La nueva clave debe tener al menos 6 caracteres.");
    if (nueva !== conf) return setErr("Las claves nuevas no coinciden.");
    setBusy(true);
    try {
      await MDP_API.cambiarPassword(forced ? "" : actual, nueva);
      setOk(true);
      setTimeout(() => onDone(), 1100);
    } catch (err) {
      setErr(err.message || "No se pudo cambiar la clave.");
      setBusy(false);
    }
  };

  return (
    <div onClick={forced ? undefined : onClose} style={{
      position: "fixed", inset: 0, zIndex: 300,
      background: "rgba(0,0,0,0.65)",
      display: "flex", alignItems: "center", justifyContent: "center", padding: 20,
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: "100%", maxWidth: 420,
        background: p.bgCard, border: `1px solid ${p.border}`, borderRadius: 16,
        padding: 28, boxShadow: "0 30px 80px rgba(0,0,0,0.5)",
      }}>
        <div style={{
          fontFamily: "'Montserrat', sans-serif", fontWeight: 700,
          fontSize: 19, color: p.text, marginBottom: 6,
        }}>{forced ? "Creá tu clave personal" : "Cambiar mi clave"}</div>
        <div style={{
          fontFamily: "'Geist', sans-serif", fontSize: 13.5, lineHeight: 1.5,
          color: p.textMuted, marginBottom: 22,
        }}>
          {forced
            ? "Tu clave actual es temporal. Por tu seguridad, elegí una clave nueva que solo vos conozcas."
            : "Elegí una clave nueva. Nadie más puede verla, ni siquiera la administración."}
        </div>

        {ok ? (
          <div style={{
            padding: "14px 16px", borderRadius: 10,
            background: "rgba(46,125,107,0.12)", border: "1px solid rgba(46,125,107,0.4)",
            color: "#7FCBB5", fontFamily: "'Geist', sans-serif", fontSize: 14,
            textAlign: "center",
          }}>✓ Clave actualizada</div>
        ) : (
          <form onSubmit={submit}>
            {!forced && (
              <div style={{ marginBottom: 14 }}>
                <label style={labelStyle}>Clave actual</label>
                <input style={inputStyle} type="password" value={actual} autoFocus
                       onChange={e => { setActual(e.target.value); setErr(""); }}
                       placeholder="Tu clave de ahora" />
              </div>
            )}
            <div style={{ marginBottom: 14 }}>
              <label style={labelStyle}>Clave nueva</label>
              <input style={inputStyle} type="password" value={nueva} autoFocus={forced}
                     onChange={e => { setNueva(e.target.value); setErr(""); }}
                     placeholder="Mínimo 6 caracteres" />
            </div>
            <div style={{ marginBottom: 18 }}>
              <label style={labelStyle}>Repetir clave nueva</label>
              <input style={inputStyle} type="password" value={conf}
                     onChange={e => { setConf(e.target.value); setErr(""); }}
                     placeholder="Repetí la clave nueva" />
            </div>

            {err && (
              <div style={{
                marginBottom: 16, padding: "10px 13px", borderRadius: 9,
                background: "rgba(168,85,85,0.12)", border: "1px solid rgba(168,85,85,0.4)",
                color: "#D98A8A", fontFamily: "'Geist', sans-serif", fontSize: 13,
              }}>{err}</div>
            )}

            <div style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}>
              {!forced && (
                <button type="button" onClick={onClose} style={{
                  padding: "10px 18px", background: "transparent",
                  border: `1px solid ${p.border}`, borderRadius: 9,
                  color: p.text, fontFamily: "'Geist', sans-serif", fontSize: 13.5, cursor: "default",
                }}>Cancelar</button>
              )}
              <button type="submit" disabled={busy} style={{
                padding: "10px 20px", background: t.accent, border: 0, borderRadius: 9,
                color: "#0A0A0A", fontWeight: 600,
                fontFamily: "'Geist', sans-serif", fontSize: 13.5, cursor: "default",
                opacity: busy ? 0.7 : 1,
              }}>{busy ? "Guardando…" : "Guardar clave"}</button>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}

function LoginScreen({ t, p, onLogin }) {
  const [email, setEmail] = useState("");
  const [pass, setPass] = useState("");
  const [err, setErr] = useState("");
  const [show, setShow] = useState(false);

  const [busy, setBusy] = useState(false);
  const submit = async (e) => {
    e && e.preventDefault();
    if (busy) return;
    setErr(""); setBusy(true);
    try {
      const usuario = await MDP_API.login(email.trim().toLowerCase(), pass);
      onLogin(usuario);
    } catch (err) {
      setErr(err.message || "No pudimos iniciar sesión.");
    } finally {
      setBusy(false);
    }
  };

  const inputStyle = {
    width: "100%", boxSizing: "border-box",
    background: p.bg2, border: `1px solid ${p.border}`, borderRadius: 10,
    color: p.text, fontFamily: "'Geist', sans-serif", fontSize: 15,
    padding: "13px 14px", outline: "none",
  };
  const labelStyle = {
    fontFamily: "'Geist', sans-serif", fontSize: 10.5, color: p.textMuted,
    letterSpacing: "0.16em", textTransform: "uppercase", fontWeight: 500,
    marginBottom: 8, display: "block",
  };

  return (
    <div style={{
      minHeight: "100vh", width: "100%",
      display: "flex", alignItems: "center", justifyContent: "center",
      background: p.bg, padding: 24, boxSizing: "border-box",
      position: "relative", overflow: "hidden",
    }}>
      {/* glow */}
      <div style={{
        position: "absolute", top: "-30%", left: "50%", transform: "translateX(-50%)",
        width: 720, height: 720, borderRadius: "50%",
        background: `radial-gradient(circle, ${t.accent}22, transparent 62%)`,
        pointerEvents: "none",
      }}/>
      <div style={{
        position: "relative", width: 400, maxWidth: "100%",
        display: "flex", flexDirection: "column", alignItems: "center",
      }}>
        <MDPLogo theme={t.theme} size={46} />
        <h1 style={{
          fontFamily: "'Montserrat', sans-serif", fontWeight: 800,
          fontSize: 27, color: p.text, letterSpacing: "-0.02em",
          margin: "26px 0 6px", textAlign: "center",
        }}>Acceso al sistema</h1>
        <p style={{
          fontFamily: "'Geist', sans-serif", fontSize: 14, color: p.textMuted,
          margin: "0 0 28px", textAlign: "center",
        }}>Entra con tu correo de miembro de Marca de Poder.</p>

        <form onSubmit={submit} style={{ width: "100%" }}>
          <div style={{ marginBottom: 16 }}>
            <label style={labelStyle}>Correo</label>
            <input style={inputStyle} type="email" value={email} autoFocus
                   onChange={(e) => { setEmail(e.target.value); setErr(""); }}
                   placeholder="tucorreo@ejemplo.com" />
          </div>
          <div style={{ marginBottom: 18 }}>
            <label style={labelStyle}>Clave</label>
            <div style={{ position: "relative" }}>
              <input style={{ ...inputStyle, paddingRight: 64 }}
                     type={show ? "text" : "password"} value={pass}
                     onChange={(e) => { setPass(e.target.value); setErr(""); }}
                     placeholder="••••••••" />
              <button type="button" onClick={() => setShow(s => !s)} style={{
                position: "absolute", right: 10, top: "50%", transform: "translateY(-50%)",
                background: "transparent", border: 0, color: p.textMuted,
                fontFamily: "'Geist', sans-serif", fontSize: 12, cursor: "default",
              }}>{show ? "Ocultar" : "Ver"}</button>
            </div>
          </div>

          {err && (
            <div style={{
              marginBottom: 16, padding: "10px 13px", borderRadius: 9,
              background: "rgba(168,85,85,0.12)", border: "1px solid rgba(168,85,85,0.4)",
              color: "#D98A8A", fontFamily: "'Geist', sans-serif", fontSize: 13,
            }}>{err}</div>
          )}

          <button type="submit" style={{
            width: "100%", padding: "14px", border: 0, borderRadius: 10,
            background: t.accent, color: "#0A0A0A",
            fontFamily: "'Geist', sans-serif", fontSize: 15, fontWeight: 600,
            cursor: "default", display: "flex", alignItems: "center",
            justifyContent: "center", gap: 8,
          }}>
            Entrar
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M5 12h14"/><path d="m13 6 6 6-6 6"/>
            </svg>
          </button>
        </form>

        <a href="https://portal.marcadepoder.com/feed" target="_blank" rel="noopener noreferrer"
           style={{
             marginTop: 22, fontFamily: "'Geist', sans-serif", fontSize: 13,
             color: p.textMuted, textDecoration: "none",
           }}>¿Problemas para entrar? Ir al portal de estudios →</a>
      </div>
    </div>
  );
}

// ── Header (top bar) ────────────────────────────────────────────────────────
function TopBar({ t, p, activeAgent, onHome, onAdmin, view, query, setQuery, user, onLogout, onChangePassword, isMobile, showMenu, onMenu }) {
  return (
    <header style={{
      height: 60, flexShrink: 0,
      borderBottom: `1px solid ${p.border}`,
      padding: isMobile ? "0 12px" : "0 28px",
      display: "flex", alignItems: "center", gap: isMobile ? 10 : 18,
      background: p.bg,
    }}>
      {isMobile && showMenu && (
        <button onClick={onMenu} aria-label="Menú" style={{
          width: 38, height: 38, borderRadius: 9, flexShrink: 0,
          background: "transparent", border: `1px solid ${p.border}`,
          color: p.text, cursor: "default",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
            <path d="M3 6h18M3 12h18M3 18h18"/>
          </svg>
        </button>
      )}

      <button onClick={onHome} style={{
        background: "transparent", border: 0, padding: 0,
        cursor: "default", display: "flex", alignItems: "center", gap: 12,
      }}>
        <MDPLogo theme={t.theme} size={isMobile ? 26 : 30} />
      </button>

      {!isMobile && (activeAgent || view === "admin") && (
        <>
          <div style={{
            height: 16, width: 1, background: p.border, margin: "0 4px",
          }}/>

          <div style={{
            display: "flex", alignItems: "center", gap: 10,
            fontFamily: "'Geist', sans-serif", fontSize: 13,
            color: p.text,
          }}>
            {activeAgent && <span style={{ color: p.text }}>{activeAgent.name}</span>}
            {view === "admin" && <span style={{ color: p.text }}>Administración</span>}
          </div>
        </>
      )}

      {/* Search bar (solo desktop; en móvil se busca dentro del drawer/home) */}
      {!isMobile && (
      <div style={{
        marginLeft: 24,
        display: "flex", alignItems: "center", gap: 8,
        padding: "7px 12px",
        width: 280,
        background: p.bg2, border: `1px solid ${query ? t.accent + "55" : p.border}`,
        borderRadius: 8,
        transition: "border-color .15s",
      }}>
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none"
             stroke={query ? t.accent : p.textMuted}
             strokeWidth="1.7" strokeLinecap="round">
          <circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/>
        </svg>
        <input
          value={query} onChange={(e) => setQuery(e.target.value)}
          placeholder="Buscar agente…"
          style={{
            flex: 1, minWidth: 0,
            background: "transparent", border: 0, outline: "none",
            color: p.text, fontSize: 13,
            fontFamily: "'Geist', sans-serif",
          }}
        />
        {query ? (
          <button onClick={() => setQuery("")} style={{
            background: "transparent", border: 0, padding: 0,
            color: p.textMuted, cursor: "default",
            display: "flex", alignItems: "center",
          }}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
              <path d="m6 6 12 12"/><path d="m18 6-12 12"/>
            </svg>
          </button>
        ) : (
          <kbd style={{
            background: p.bg, border: `1px solid ${p.border}`,
            borderRadius: 4, padding: "1px 6px",
            fontSize: 10, fontFamily: "ui-monospace, monospace",
            color: p.textDim, letterSpacing: "0.04em",
          }}>⌘K</kbd>
        )}
      </div>
      )}

      <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: isMobile ? 8 : 14 }}>
        {/* Portal de estudios (solo desktop) */}
        {!isMobile && (
        <a href="https://portal.marcadepoder.com/feed" target="_blank" rel="noopener noreferrer"
           style={{
             display: "flex", alignItems: "center", gap: 7,
             padding: "7px 14px",
             border: `1px solid ${p.border}`, borderRadius: 8,
             color: p.text, textDecoration: "none",
             fontFamily: "'Geist', sans-serif", fontSize: 12.5,
             cursor: "default", transition: "border-color .15s, background .15s",
           }}
           onMouseEnter={(e) => {
             e.currentTarget.style.borderColor = t.accent + "70";
             e.currentTarget.style.background = t.accent + "10";
           }}
           onMouseLeave={(e) => {
             e.currentTarget.style.borderColor = p.border;
             e.currentTarget.style.background = "transparent";
           }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <path d="M3 7v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7"/>
            <path d="m3 7 9-4 9 4"/>
            <path d="M8 12h8"/>
          </svg>
          Portal de estudios
          <svg width="10" height="10" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
               style={{ opacity: 0.6 }}>
            <path d="M7 17 17 7"/><path d="M8 7h9v9"/>
          </svg>
        </a>
        )}

        {/* Credits */}
        <div style={{
          display: "flex", alignItems: "center", gap: 7,
          padding: isMobile ? "6px 10px" : "6px 12px",
          border: `1px solid ${p.border}`, borderRadius: 999,
          fontSize: 12, color: p.textMuted,
          fontFamily: "'Geist', sans-serif", flexShrink: 0,
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: 999, background: "#2E7D6B",
            boxShadow: "0 0 6px rgba(46,125,107,0.6)",
          }}/>
          <span style={{ fontVariantNumeric: "tabular-nums", color: p.text }}>{user.consultas}</span>
          {!isMobile && <span>consultas</span>}
        </div>

        {/* User */}
        <button
          onClick={user.admin ? onAdmin : undefined}
          style={{
            display: "flex", alignItems: "center", gap: 10,
            padding: isMobile ? 3 : "5px 5px 5px 14px",
            background: view === "admin" ? p.bg2 : "transparent",
            border: `1px solid ${view === "admin" ? t.accent + "55" : p.border}`, borderRadius: 999,
            cursor: "default", transition: "border-color .15s, background .15s",
            flexShrink: 0,
          }}>
          <div style={{
            width: isMobile ? 30 : 26, height: isMobile ? 30 : 26, borderRadius: 999,
            background: `linear-gradient(135deg, ${t.accent}, ${t.accent}99)`,
            display: "flex", alignItems: "center", justifyContent: "center",
            color: "#0A0A0A", fontWeight: 600, fontSize: 11,
            fontFamily: "'Geist', sans-serif",
          }}>{initials(user.name)}</div>
          {!isMobile && (
            <span style={{
              fontFamily: "'Geist', sans-serif", fontSize: 13,
              color: p.text, marginRight: user.admin ? 4 : 8,
            }}>{user.name}</span>
          )}
          {!isMobile && user.admin && (
            <span style={{
              display: "inline-flex", alignItems: "center", gap: 5,
              padding: "2px 8px", borderRadius: 999,
              background: t.accent + "1c", border: `1px solid ${t.accent}40`,
              fontFamily: "'Geist', sans-serif", fontSize: 10.5,
              color: t.accent, letterSpacing: "0.03em",
            }}>
              <span style={{ width: 4, height: 4, borderRadius: 999, background: t.accent }}/>
              Admin
            </span>
          )}
        </button>

        <button onClick={onChangePassword} aria-label="Cambiar mi clave" title="Cambiar mi clave" style={{
          padding: 0, width: 38, height: 38, flexShrink: 0,
          background: "transparent",
          border: `1px solid ${p.border}`, borderRadius: isMobile ? 9 : 8,
          color: p.textMuted, cursor: "default",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="7.5" cy="15.5" r="4.5"/><path d="m10.5 12.5 8-8"/><path d="m16 7 3 3"/><path d="m19 4 2 2"/>
          </svg>
        </button>

        <button onClick={onLogout} aria-label="Salir" style={{
          padding: isMobile ? 0 : "7px 14px",
          width: isMobile ? 38 : "auto", height: isMobile ? 38 : "auto",
          background: "transparent",
          border: `1px solid ${p.border}`, borderRadius: isMobile ? 9 : 8,
          color: p.textMuted,
          fontFamily: "'Geist', sans-serif", fontSize: 12.5,
          cursor: "default", flexShrink: 0,
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          {isMobile ? (
            <svg width="17" height="17" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
              <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/>
            </svg>
          ) : "Salir"}
        </button>
      </div>
    </header>
  );
}

// ── Sidebar agent row ──────────────────────────────────────────────────────
function SidebarRow({ agent, locked, pinned, active, onOpen, onPin, t, p }) {
  const [hover, setHover] = useState(false);
  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onClick={() => !locked && onOpen(agent)}
      style={{
        display: "flex", alignItems: "center", gap: 11,
        padding: "10px 12px",
        borderRadius: 9,
        background: active
          ? `${t.accent}14`
          : hover && !locked ? p.bg2 : "transparent",
        border: `1px solid ${active ? t.accent + "55" : "transparent"}`,
        cursor: "default",
        opacity: locked ? 0.5 : 1,
        position: "relative",
        transition: "background .15s, border-color .15s",
      }}>
      {/* Icon ring (línea visual MDP) */}
      <div style={{
        width: 32, height: 32, borderRadius: 999,
        background: active ? t.accent + "1f" : "transparent",
        border: `1.5px solid ${active ? t.accent : t.accent + "55"}`,
        display: "flex", alignItems: "center", justifyContent: "center",
        color: t.accent, flexShrink: 0,
      }}>
        {locked ? (
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <rect x="5" y="11" width="14" height="10" rx="2"/>
            <path d="M8 11V8a4 4 0 0 1 8 0v3"/>
          </svg>
        ) : (agent.icon ? <agent.icon size={15} /> : initials(agent.name))}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontFamily: "'Geist', sans-serif", fontSize: 13.5, fontWeight: 500,
          color: p.text, lineHeight: 1.25,
          whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
        }}>{agent.name}</div>
        <div style={{
          fontFamily: "'Geist', sans-serif", fontSize: 11.5,
          color: p.textMuted, lineHeight: 1.25, marginTop: 1,
          whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
        }}>{agent.shortDesc || agent.desc}</div>
      </div>
      {/* Right-side indicator: active dot or pin star */}
      {active && (
        <span style={{
          width: 7, height: 7, borderRadius: 999, background: t.accent,
          boxShadow: `0 0 8px ${t.accent}aa`, flexShrink: 0,
        }}/>
      )}
      {!active && pinned && !locked && (
        <svg width="11" height="11" viewBox="0 0 24 24"
             fill={t.accent} stroke={t.accent} strokeWidth="1.4"
             strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
          <path d="m12 3 2.7 6 6.3.6-4.8 4.4 1.5 6.5L12 17l-5.7 3.5 1.5-6.5L3 9.6 9.3 9 12 3Z"/>
        </svg>
      )}
      {!active && !pinned && !locked && hover && (
        <button onClick={(e) => { e.stopPropagation(); onPin(agent.id); }}
                aria-label="Favorito"
                style={{
                  background: "transparent", border: 0, padding: 2,
                  color: p.textDim, cursor: "default", flexShrink: 0,
                }}>
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
            <path d="m12 3 2.7 6 6.3.6-4.8 4.4 1.5 6.5L12 17l-5.7 3.5 1.5-6.5L3 9.6 9.3 9 12 3Z"/>
          </svg>
        </button>
      )}
    </div>
  );
}

// ── Sidebar ─────────────────────────────────────────────────────────────────
function Sidebar({ t, p, activeAgent, pinned, isLocked, onOpen, onPin, onHome, query, setQuery, user, isMobile }) {
  const matchesQuery = (a) => {
    if (!query) return true;
    const q = query.toLowerCase();
    return a.name.toLowerCase().includes(q) || a.desc.toLowerCase().includes(q);
  };

  const totalUnlocked = ALL_AGENTS.filter(a => !isLocked(a.level)).length;

  return (
    <aside style={{
      width: isMobile ? "100%" : 300, flexShrink: 0,
      background: p.sidebarBg,
      borderRight: isMobile ? "none" : `1px solid ${p.border}`,
      display: "flex", flexDirection: "column",
      height: "100%",
    }}>
      {/* Home button + counter */}
      <div style={{ padding: "16px 14px 10px" }}>
        <button onClick={onHome} style={{
          width: "100%", padding: "9px 12px",
          background: !activeAgent ? p.bg2 : "transparent",
          border: `1px solid ${!activeAgent ? p.border : p.borderSoft}`,
          borderRadius: 8,
          color: p.text, fontFamily: "'Geist', sans-serif", fontSize: 13,
          cursor: "default",
          display: "flex", alignItems: "center", gap: 9,
        }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <path d="M3 11 12 4l9 7"/>
            <path d="M5 10v9h14v-9"/>
          </svg>
          Inicio
        </button>
      </div>

      {/* Search */}
      <div style={{ padding: "0 14px 12px" }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 9,
          padding: "8px 12px",
          background: p.bg2, border: `1px solid ${p.border}`,
          borderRadius: 8,
        }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke={p.textMuted}
               strokeWidth="1.6" strokeLinecap="round">
            <circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/>
          </svg>
          <input
            value={query} onChange={(e) => setQuery(e.target.value)}
            placeholder="Buscar agente…"
            style={{
              background: "transparent", border: 0, outline: "none",
              color: p.text, fontSize: 12.5, flex: 1, minWidth: 0,
              fontFamily: "'Geist', sans-serif",
            }}
          />
        </div>
      </div>

      {/* Section header */}
      <div style={{
        padding: "6px 18px 10px",
        display: "flex", alignItems: "baseline", justifyContent: "space-between",
      }}>
        <span style={{
          fontFamily: "'Geist', sans-serif", fontSize: 10.5,
          color: p.textMuted, letterSpacing: "0.22em",
          textTransform: "uppercase", fontWeight: 500,
        }}>Agentes</span>
      </div>

      {/* Agent list (scrollable) */}
      <div style={{
        flex: 1, overflowY: "auto",
        padding: "0 10px 14px",
      }}>
        {/* Pinned section */}
        {(() => {
          const pinnedVisible = ALL_AGENTS.filter(a =>
            pinned.includes(a.id) && !isLocked(a.level) && matchesQuery(a));
          if (pinnedVisible.length === 0 || query) return null;
          return (
            <>
              <div style={{
                padding: "8px 6px 6px",
                display: "flex", alignItems: "center", gap: 6,
                fontFamily: "'Geist', sans-serif", fontSize: 10,
                color: t.accent, letterSpacing: "0.22em",
                textTransform: "uppercase", fontWeight: 500,
              }}>
                <svg width="9" height="9" viewBox="0 0 24 24"
                     fill={t.accent} stroke={t.accent} strokeWidth="1.4"
                     strokeLinecap="round" strokeLinejoin="round">
                  <path d="m12 3 2.7 6 6.3.6-4.8 4.4 1.5 6.5L12 17l-5.7 3.5 1.5-6.5L3 9.6 9.3 9 12 3Z"/>
                </svg>
                Favoritos
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 2, marginBottom: 12 }}>
                {pinnedVisible.map(a => (
                  <SidebarRow key={"pin-" + a.id} agent={a} locked={false}
                              pinned={true}
                              active={activeAgent?.id === a.id}
                              onOpen={onOpen} onPin={onPin}
                              t={t} p={p}/>
                ))}
              </div>
            </>
          );
        })()}

        {/* Levels */}
        {LEVELS.map(level => {
          const locked = isLocked(level.n);
          const visible = level.agents.filter(matchesQuery);
          if (visible.length === 0) return null;
          return (
            <div key={level.n} style={{ marginBottom: 12 }}>
              <div style={{
                padding: "8px 6px 6px",
                display: "flex", alignItems: "center", justifyContent: "space-between",
                fontFamily: "'Geist', sans-serif", fontSize: 10,
                letterSpacing: "0.22em", textTransform: "uppercase",
                fontWeight: 500,
              }}>
                <span style={{ color: p.textMuted }}>
                  Nivel {level.n} · <span style={{ color: p.text }}>{level.name}</span>
                </span>
                {locked && (
                  <svg width="10" height="10" viewBox="0 0 24 24" fill="none"
                       stroke={p.textMuted} strokeWidth="1.8"
                       strokeLinecap="round" strokeLinejoin="round">
                    <rect x="5" y="11" width="14" height="10" rx="2"/>
                    <path d="M8 11V8a4 4 0 0 1 8 0v3"/>
                  </svg>
                )}
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
                {visible.map(a => (
                  <SidebarRow key={a.id}
                              agent={{ ...a, level: level.n, levelName: level.name }}
                              locked={locked}
                              pinned={pinned.includes(a.id)}
                              active={activeAgent?.id === a.id}
                              onOpen={onOpen} onPin={onPin}
                              t={t} p={p}/>
                ))}
              </div>
            </div>
          );
        })}
      </div>

      {/* Footer: plan info */}
      <div style={{
        padding: "12px 14px 16px",
        borderTop: `1px solid ${p.border}`,
      }}>
        <div style={{
          fontFamily: "'Geist', sans-serif", fontSize: 10.5,
          color: p.textMuted, letterSpacing: "0.22em",
          textTransform: "uppercase", marginBottom: 8, fontWeight: 500,
        }}>Tu plan</div>
        <div style={{
          padding: "11px 13px",
          background: p.bg2, border: `1px solid ${p.border}`,
          borderRadius: 9,
        }}>
          <div style={{
            fontFamily: "'Geist', sans-serif", fontSize: 13, fontWeight: 500,
            color: p.text, marginBottom: 2,
          }}>{user.plan}</div>
          <div style={{
            fontFamily: "'Geist', sans-serif", fontSize: 11.5,
            color: p.textMuted,
          }}>{user.consultas} consultas disponibles</div>
        </div>
      </div>
    </aside>
  );
}

// ── App ─────────────────────────────────────────────────────────────────────
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [query, setQuery] = useState("");
  const [activeAgent, setActiveAgent] = useState(null);
  const [view, setView] = useState("home"); // home | admin
  const [adminTab, setAdminTab] = useState("miembros"); // miembros | agentes
  const [pinned, setPinned] = useState(["perfil-magnetico", "director-estrategico"]);
  const [user, setUser] = useState(null);
  const isMobile = window.useIsMobile();
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [showPwd, setShowPwd] = useState(false);

  const p = PALETTES[t.theme] || PALETTES.dark;

  // Si ya hay sesión guardada (token), recuperamos al usuario al cargar.
  useEffect(() => {
    MDP_API.me().then(u => { if (u) { setUser(mapUser(u)); if (u.password_temporal) setShowPwd(true); } });
  }, []);

  const login = (usuario) => { setUser(mapUser(usuario)); if (usuario.password_temporal) setShowPwd(true); };
  const logout = () => {
    MDP_API.clearToken();
    setActiveAgent(null); setView("home"); setUser(null);
  };

  // Acceso acumulativo: nivel N incluye 1..N. Nivel 5 = todo.
  const isLocked = (n) => n > (user?.accessLevel ?? 5);

  const openAgent = (agent) => {
    // En producción las consultas se descuentan en el backend, por mensaje.
    setActiveAgent(agent);
    setView("home");
  };
  const setConsultas = (n) => setUser(u => u ? { ...u, consultas: n } : u);
  const goHome = () => { setActiveAgent(null); setView("home"); };
  const goAdmin = () => { setActiveAgent(null); setView("admin"); };
  const togglePin = (id) =>
    setPinned(prev => prev.includes(id) ? prev.filter(x => x !== id) : [id, ...prev]);

  // Apply theme to body
  useEffect(() => {
    document.body.style.background = p.bg;
    document.body.style.color = p.text;
  }, [p]);

  // Cerrar el drawer al cambiar de pantalla
  useEffect(() => { setDrawerOpen(false); }, [activeAgent, view]);

  // Gate de acceso (prototipo): sin sesión, mostramos el login.
  if (!user) return <LoginScreen t={t} p={p} onLogin={login} />;

  return (
    <div style={{
      display: "flex", flexDirection: "column",
      height: "100vh", overflow: "hidden",
      background: p.bg, color: p.text,
      fontFamily: "'Geist', sans-serif",
    }}>
      <TopBar t={t} p={p} activeAgent={activeAgent} onHome={goHome}
              onAdmin={goAdmin} view={view}
              query={query} setQuery={setQuery}
              user={user} onLogout={logout}
              onChangePassword={() => setShowPwd(true)}
              isMobile={isMobile} showMenu={isMobile && view !== "admin"}
              onMenu={() => setDrawerOpen(o => !o)} />

      <div style={{ display: "flex", flex: 1, minHeight: 0, position: "relative" }}>
        {/* Desktop: sidebar en línea cuando hay un agente activo */}
        {!isMobile && activeAgent && view !== "admin" && (
          <Sidebar t={t} p={p}
                   activeAgent={activeAgent}
                   pinned={pinned}
                   isLocked={isLocked}
                   onOpen={openAgent} onPin={togglePin}
                   onHome={goHome}
                   query={query} setQuery={setQuery}
                   user={user} />
        )}

        {/* Móvil: sidebar como drawer deslizable */}
        {isMobile && view !== "admin" && drawerOpen && (
          <>
            <div onClick={() => setDrawerOpen(false)} style={{
              position: "fixed", inset: 0, zIndex: 80,
              background: "rgba(0,0,0,0.55)",
            }}/>
            <div style={{
              position: "fixed", top: 0, left: 0, height: "100%",
              width: "86vw", maxWidth: 340, zIndex: 81,
              boxShadow: "24px 0 70px rgba(0,0,0,0.5)",
              animation: "mdpDrawerL .22s cubic-bezier(.2,.8,.2,1)",
            }}>
              <Sidebar t={t} p={p}
                       activeAgent={activeAgent}
                       pinned={pinned}
                       isLocked={isLocked}
                       onOpen={(a) => { openAgent(a); setDrawerOpen(false); }}
                       onPin={togglePin}
                       onHome={() => { goHome(); setDrawerOpen(false); }}
                       query={query} setQuery={setQuery}
                       user={user} isMobile />
            </div>
          </>
        )}

        <main style={{ flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }}>
          {view === "admin" ? (
            <>
              {/* Admin sub-tabs */}
              <div style={{
                flexShrink: 0,
                borderBottom: `1px solid ${p.border}`,
                padding: isMobile ? "0 12px" : "0 36px",
                display: "flex", alignItems: "center", gap: 4,
                background: p.bg,
                overflowX: "auto",
              }}>
                {[
                  { id: "miembros", label: "Miembros", icon: "M16 7a4 4 0 1 0-8 0 4 4 0 0 0 8 0ZM3 21v-2a6 6 0 0 1 6-6h6a6 6 0 0 1 6 6v2" },
                  { id: "agentes",  label: "Configuración de agentes", icon: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" },
                ].map(tab => {
                  const on = adminTab === tab.id;
                  return (
                    <button key={tab.id} onClick={() => setAdminTab(tab.id)} style={{
                      padding: "16px 16px 14px",
                      background: "transparent", border: 0,
                      borderBottom: `2px solid ${on ? t.accent : "transparent"}`,
                      color: on ? p.text : p.textMuted,
                      fontFamily: "'Geist', sans-serif", fontSize: 13.5,
                      fontWeight: on ? 600 : 400,
                      cursor: "default",
                      display: "flex", alignItems: "center", gap: 8,
                      marginBottom: -1, flexShrink: 0, whiteSpace: "nowrap",
                    }}>
                      <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
                           stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                        <path d={tab.icon}/>
                      </svg>
                      {tab.label}
                    </button>
                  );
                })}
              </div>
              {adminTab === "miembros"
                ? <AdminView t={t} p={p} />
                : <AgentConfigView t={t} p={p} />}
            </>
          ) : activeAgent ? (
            <ChatView key={activeAgent.id} agent={activeAgent}
                      t={t} p={p}
                      consultas={user.consultas}
                      onCredits={setConsultas}
                      onNewSession={() => {}}
                      onBack={goHome}/>
          ) : (
            <HomeView t={t} p={p} query={query}
                      pinned={pinned} isLocked={isLocked}
                      onOpenAgent={openAgent} togglePin={togglePin}/>
          )}
        </main>
      </div>

      {/* Tweaks */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Marca" />
        <TweakColor label="Color de acento" value={t.accent}
                    options={["#C87848","#A6724A","#2E7D6B","#D4AF7F","#8B6FB8"]}
                    onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="Tema" value={t.theme}
                    options={["dark","light"]}
                    onChange={(v) => setTweak("theme", v)} />

        <TweakSection label="Cuenta" />
        <TweakNumber label="Consultas disponibles" value={t.credits} min={0} max={9999} step={1}
                     onChange={(v) => setTweak("credits", v)} />
      </TweaksPanel>

      {showPwd && user && (
        <ChangePasswordModal t={t} p={p}
          forced={!!user.password_temporal}
          onClose={() => setShowPwd(false)}
          onDone={() => {
            setShowPwd(false);
            setUser(u => u ? { ...u, password_temporal: false } : u);
          }} />
      )}

      <style>{`
        @keyframes mdpSpin { to { transform: rotate(360deg); } }
        @keyframes mdpDrawerL { from { transform: translateX(-100%); } to { transform: translateX(0); } }
        @keyframes mdpBlink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }
        @keyframes mdpPulse {
          0% { box-shadow: 0 0 0 0 rgba(46,125,107,0.6); }
          70% { box-shadow: 0 0 0 6px rgba(46,125,107,0); }
          100% { box-shadow: 0 0 0 0 rgba(46,125,107,0); }
        }
        ::selection { background: ${t.accent}55; color: ${p.text}; }
        input::placeholder, textarea::placeholder { color: ${p.textDim}; }
      `}</style>
    </div>
  );
}

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