/* Portal O-Lab — app de la Empresa. Expone window.EmpresaApp. */
(function () {
  const { useState, useEffect } = React;
  const { C, FONT, Icon, Avatar, Bar, Pill, Btn, Card, useIsMobile } = window.PORTAL_UI;
  const B = () => window.PORTAL_BACKEND;
  const SEED = () => window.PORTAL_SEED;

  const STAGE_META = {
    nuevo: { label: "Nuevo", bg: C.sand, border: C.line2, color: C.mut3, colBg: C.sand, colBd: C.line2, colColor: C.mut3 },
    contactado: { label: "Contactado", bg: C.violetSoft, border: "#D9CDFF", color: C.violetDk, colBg: C.violetSoft, colBd: "#D9CDFF", colColor: C.violetDk },
    entrevista: { label: "Entrevistado", bg: C.orangeSoft, border: "#FFC79A", color: C.orangeDk, colBg: C.orangeSoft, colBd: "#FFC79A", colColor: C.orangeDk },
    contratado: { label: "Contratado", bg: C.greenBg, border: C.greenBd, color: C.green, colBg: C.greenBg, colBd: C.greenBd, colColor: C.green },
    descartado: { label: "Descartado", bg: "#FDECEA", border: "#F5C6C0", color: "#C0392B", colBg: "#FDECEA", colBd: "#F5C6C0", colColor: "#C0392B" },
  };

  function EmpresaApp({ profile, onLogout, onSwitchRole, isAdmin }) {
    const mob = useIsMobile();
    const company = Object.assign({}, SEED().company, profile || {});
    const [tab, setTab] = useState("candidatos");
    const [adminOpen, setAdminOpen] = useState(false);
    const AdminPanel = window.PORTAL_AdminModal;
    const [cands, setCands] = useState(() => SEED().candidates.map((c) => ({ ...c })));
    const [contacts, setContacts] = useState(() => SEED().contacts.map((c) => ({ ...c })));
    const [open, setOpen] = useState(null); // candidate id
    const [postOpen, setPostOpen] = useState(false);
    const [toast, setToast] = useState("");

    // filtros
    const [f, setF] = useState({ lab: "Todas", prof: "Todas", city: "Todas", gender: "Todos", exp: "Todas", labs: "0", mode: "Todas", seek: "Todas" });
    const [labCatalog, setLabCatalog] = useState([]);   // catálogo real de laboratorios publicados

    // Catálogo de laboratorios publicados desde Project OS (talentPortal/labs/items).
    useEffect(() => {
      if (!B().subscribeLabs) return;
      return B().subscribeLabs((items) => setLabCatalog(Array.isArray(items) ? items : []));
    }, []);

    useEffect(() => {
      B().candidateDirectory().then((r) => {
        if (r.source === "live" && r.candidates.length) {
          const avatars = ["linear-gradient(135deg,#FF6600,#FF3D7F)", "linear-gradient(135deg,#12C2E9,#6C4CF1)", "linear-gradient(135deg,#C6F24E,#0E8F5B)", "linear-gradient(135deg,#FF3D7F,#6C4CF1)"];
          setCands(r.candidates.map((c, i) => ({
            stage: "nuevo", avatarBg: avatars[i % 4], avatarColor: "#fff", matchColor: "#8B8194",
            skills: [], labList: [], ...c,
          })));
        }
      });
    }, []);

    function setStage(id, stage) {
      setCands((cs) => cs.map((c) => (c.id === id ? { ...c, stage } : c)));
      const c = cands.find((x) => x.id === id);
      if (c) B().logContact({ candidate: c, channel: "Sistema", note: "Cambio de etapa a " + STAGE_META[stage].label, stage: STAGE_META[stage].label });
    }
    function logContact(cand, channel) {
      const now = new Date();
      const stamp = String(now.getDate()).padStart(2, "0") + " ago · " + String(now.getHours()).padStart(2, "0") + ":" + String(now.getMinutes()).padStart(2, "0");
      setContacts((cx) => [{ id: "k" + now.getTime(), name: cand.name, channel, date: stamp, note: "Contacto desde el perfil · vacante Operario de bodega", stage: STAGE_META[cand.stage === "nuevo" ? "contactado" : cand.stage].label }, ...cx]);
      if (cand.stage === "nuevo") setStage(cand.id, "contactado");
      B().logContact({ candidate: cand, channel, stage: STAGE_META[cand.stage].label });
      flash(channel + " registrado con " + cand.name);
    }
    function flash(msg) { setToast(msg); setTimeout(() => setToast(""), 2600); }

    // Nombre "base" de un lab: "Auditoría de bodega · 6/6" → "Auditoría de bodega".
    const labBase = (s) => String(s || "").split("·")[0].trim();
    // Opciones del filtro: primero el catálogo real publicado; si no hay, la unión
    // de los laboratorios que traen los candidatos cargados.
    const catalogNames = labCatalog.map((l) => (l && (l.name || l.title || l.label)) || "").map(labBase).filter(Boolean);
    const candLabNames = new Set();
    cands.forEach((c) => (c.labList || []).forEach((l) => { const n = labBase(l); if (n) candLabNames.add(n); }));
    const labOptions = [...new Set([...(catalogNames.length ? catalogNames : []), ...candLabNames])].sort((a, b) => a.localeCompare(b, "es"));
    // Nombres de lab de un candidato (labList + competencias validadas por lab).
    const candLabsOf = (x) => new Set([...(x.labList || []).map(labBase), ...((x.skills || []).map((s) => labBase(s && s.name)))]);

    const filtered = cands.filter((x) => {
      if (f.lab !== "Todas" && !candLabsOf(x).has(f.lab)) return false;
      if (f.prof !== "Todas" && x.profession !== f.prof) return false;
      if (f.city !== "Todas" && x.city !== f.city) return false;
      if (f.gender !== "Todos" && x.gender !== f.gender) return false;
      if (f.exp !== "Todas" && x.expKey !== f.exp) return false;
      if ((x.labs || 0) < parseInt(f.labs, 10)) return false;
      if (f.mode !== "Todas" && x.modality !== f.mode) return false;
      if (f.seek !== "Todas" && (x.desiredRoles || []).indexOf(f.seek) < 0) return false;
      return true;
    });
    const openCand = cands.find((c) => c.id === open) || null;
    const tabs = [["feed", "Feed", "chat"], ["candidatos", "Candidatos", "user"], ["pipeline", "Pipeline", "briefcase"], ["registro", "Registro", "mail"], ["stats", "Estadísticas", "test"], ["vacantes", "Mis vacantes", "flask"]];

    return (
      <div style={{ minHeight: "100vh", background: C.cream, fontFamily: FONT }}>
        <div style={{ background: "#fff", borderBottom: `1px solid ${C.line}`, padding: mob ? "10px 12px" : "12px 20px" }}>
          <div style={{ maxWidth: 1120, margin: "0 auto", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }}>
            <img src="assets/logo-olab.png" alt="o-lab" style={{ height: 24 }} />
            <div style={{ display: "flex", alignItems: "center", gap: mob ? 6 : 10, flexWrap: "wrap", justifyContent: "flex-end" }}>
              {!mob && <Pill color={C.violetDk} bg={C.violetSoft} bd="#D9CDFF">EMPRESA · {(company.name || "").toUpperCase()}</Pill>}
              {isAdmin && AdminPanel && <button onClick={() => setAdminOpen(true)} title="Panel de superadmin" style={{ border: `1px solid ${C.line2}`, background: C.ink, color: "#fff", fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "7px 11px", borderRadius: 999, cursor: "pointer", display: "flex", alignItems: "center", gap: 6 }}><Icon name="star" size={14} color={C.lime} />{!mob && "Superadmin"}</button>}
              {onSwitchRole && <button onClick={onSwitchRole} title="Cambiar a vista de aplicante" style={{ border: `1px solid ${C.orangeSoftBd}`, background: C.orangeSoft, color: C.orangeDk, fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "7px 11px", borderRadius: 999, cursor: "pointer", display: "flex", alignItems: "center", gap: 6 }}><Icon name="user" size={14} color={C.orangeDk} />{!mob && "Aplicante"}</button>}
              <div style={{ width: 32, height: 32, borderRadius: 11, background: C.ink, display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontWeight: 800, color: C.lime }}>{(company.name || "AL").slice(0, 2).toUpperCase()}</div>
              <button onClick={onLogout} title="Salir" style={{ border: `1px solid ${C.line2}`, background: "#fff", borderRadius: 999, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", color: C.mut3 }}><Icon name="logout" size={16} /></button>
            </div>
          </div>
        </div>

        <div style={{ maxWidth: 1120, margin: "0 auto", padding: mob ? "14px 12px 36px" : "20px 20px 40px" }}>
          <div style={{ display: "flex", gap: 6, overflowX: "auto", paddingBottom: 4 }}>
            {tabs.map(([k, label, icon]) => {
              const on = tab === k;
              return (
                <button key={k} onClick={() => { setTab(k); setOpen(null); }} style={{ border: `1px solid ${on ? C.ink : C.line2}`, background: on ? C.ink : "#fff", color: on ? "#fff" : C.mut3, fontFamily: FONT, fontSize: 13, fontWeight: 800, padding: "9px 15px", borderRadius: 999, cursor: "pointer", display: "flex", alignItems: "center", gap: 7, whiteSpace: "nowrap" }}>
                  <Icon name={icon} size={16} color={on ? "#fff" : C.mut3} />{label}
                </button>
              );
            })}
          </div>

          <div style={{ marginTop: 18 }}>
            {tab === "feed" && <EmpresaFeed isAdmin={isAdmin} company={company} />}
            {tab === "candidatos" && <Candidatos list={filtered} total={cands.length} f={f} setF={setF} onOpen={setOpen} onContact={(c) => logContact(c, "WhatsApp")} />}
            {tab === "pipeline" && <Pipeline cands={cands} onOpen={setOpen} />}
            {tab === "registro" && <Registro contacts={contacts} />}
            {tab === "stats" && <EmpresaStats cands={cands} contacts={contacts} />}
            {tab === "vacantes" && <Vacantes contacts={contacts} cands={cands} onPost={() => setPostOpen(true)} onGoCand={() => setTab("candidatos")} />}
          </div>
        </div>

        {openCand && <CandidateModal cand={openCand} onClose={() => setOpen(null)} setStage={setStage} onContact={(ch) => logContact(openCand, ch)} />}
        {postOpen && <PostVacancyModal onClose={() => setPostOpen(false)} onSaved={(msg) => { setPostOpen(false); flash(msg); }} />}
        {toast && <div style={{ position: "fixed", bottom: 20, left: "50%", transform: "translateX(-50%)", background: C.ink, color: "#fff", fontWeight: 700, fontSize: 13, padding: "11px 18px", borderRadius: 999, zIndex: 80, boxShadow: "0 10px 30px rgba(0,0,0,0.3)" }}>{toast}</div>}
        {adminOpen && AdminPanel && <AdminPanel onClose={() => setAdminOpen(false)} />}
      </div>
    );
  }

  /* ----------------------------- CANDIDATOS ----------------------------- */
  function Candidatos({ list, total, f, setF, onOpen, onContact }) {
    const set = (k) => (e) => setF({ ...f, [k]: e.target.value });
    const clear = () => setF({ lab: "Todas", prof: "Todas", city: "Todas", gender: "Todos", exp: "Todas", labs: "0", mode: "Todas", seek: "Todas" });
    const sel = { fontFamily: FONT, fontSize: 13, fontWeight: 700, color: "#3D3548", background: C.sand, border: `1px solid ${C.line2}`, borderRadius: 12, padding: "10px 11px", cursor: "pointer" };
    const lab = { display: "flex", flexDirection: "column", gap: 5 };
    const cap = { fontSize: 10, fontWeight: 800, letterSpacing: "0.08em", color: C.mut4 };
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div>
          <div style={{ fontSize: 26, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Candidatos con competencias validadas</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Match calculado con tests y Labs completados en O-Lab, no con auto-reporte.</div>
        </div>

        <Card style={{ padding: 16, display: "flex", flexDirection: "column", gap: 13 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
            <Icon name="filter" color={C.orange} size={17} />
            <span style={{ fontSize: 14, fontWeight: 800, color: C.ink }}>Filtrar candidatos</span>
            <span style={{ flex: 1 }} />
            <Pill color={C.orangeDk} bg={C.orangeSoft} bd={C.orangeSoftBd}>{list.length} de {total}</Pill>
            <Btn kind="ghost" onClick={clear} style={{ padding: "7px 12px", fontSize: 12, borderRadius: 999 }}>Limpiar</Btn>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(160px,1fr))", gap: 11 }}>
            <label style={lab}><span style={cap}>LABORATORIO</span>
              <select value={f.lab} onChange={set("lab")} style={sel}><option value="Todas">Todos</option>{labOptions.map((l) => <option key={l} value={l}>{l}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>PROFESIÓN</span>
              <select value={f.prof} onChange={set("prof")} style={sel}>{["Todas", "Logística", "Industrial", "Servicio al cliente"].map((v) => <option key={v} value={v}>{v}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>CIUDAD</span>
              <select value={f.city} onChange={set("city")} style={sel}>{["Todas", "Medellín", "Bello", "Itagüí", "Envigado"].map((v) => <option key={v} value={v}>{v}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>GÉNERO</span>
              <select value={f.gender} onChange={set("gender")} style={sel}>{["Todos", "Femenino", "Masculino", "No binario"].map((v) => <option key={v} value={v}>{v}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>EXPERIENCIA</span>
              <select value={f.exp} onChange={set("exp")} style={sel}>{[["Todas", "Todas"], ["sin", "Sin experiencia"], ["<1", "Menos de 1 año"], ["1-2", "1 a 2 años"], ["2+", "Más de 2 años"]].map(([v, l]) => <option key={v} value={v}>{l}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>LABS REALIZADOS</span>
              <select value={f.labs} onChange={set("labs")} style={sel}>{[["0", "Cualquiera"], ["10", "10 o más"], ["15", "15 o más"], ["20", "20 o más"]].map(([v, l]) => <option key={v} value={v}>{l}</option>)}</select>
            </label>
            <label style={lab}><span style={cap}>ROL QUE BUSCA</span>
              <select value={f.seek} onChange={set("seek")} style={sel}><option value="Todas">Todos</option>{(SEED().rolesBuscados || []).map((r) => <option key={r} value={r}>{r}</option>)}</select>
            </label>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
            <span style={{ ...cap, marginRight: 2 }}>MODALIDAD</span>
            {["Todas", "Presencial", "Remoto"].map((m) => (
              <button key={m} onClick={() => setF({ ...f, mode: m })} style={{ border: `1px solid ${f.mode === m ? C.ink : C.line2}`, background: f.mode === m ? C.ink : "#fff", color: f.mode === m ? "#fff" : C.mut3, fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "8px 13px", borderRadius: 999, cursor: "pointer" }}>{m}</button>
            ))}
          </div>
        </Card>

        {list.length === 0 ? (
          <div style={{ background: "#fff", border: "1px dashed #D6CEC4", borderRadius: 22, padding: 32, textAlign: "center" }}>
            <div style={{ fontSize: 16, fontWeight: 800, color: C.ink }}>Ningún candidato con esos filtros</div>
            <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 6 }}>Prueba bajando los Labs mínimos o quitando el laboratorio.</div>
            <Btn onClick={clear} style={{ marginTop: 16, padding: "11px 18px" }}>Limpiar filtros</Btn>
          </div>
        ) : (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(300px,1fr))", gap: 13 }}>
            {list.map((cd) => {
              const sm = STAGE_META[cd.stage] || STAGE_META.nuevo;
              return (
                <Card key={cd.id} style={{ padding: 16, display: "flex", flexDirection: "column", gap: 13 }}>
                  <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
                    <Avatar name={cd.name} initials={cd.initials} bg={cd.avatarBg} color={cd.avatarColor} size={52} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 16, fontWeight: 800, color: C.ink, lineHeight: 1.25 }}>{cd.name}</div>
                      <div style={{ fontSize: 12, fontWeight: 600, color: C.mut2, marginTop: 3 }}>{cd.role} · {cd.city}</div>
                      <div style={{ display: "flex", gap: 6, marginTop: 8, flexWrap: "wrap" }}>
                        {cd.origin === "postulacion"
                          ? <Pill color={C.cyanDk} bg={C.cyanSoft} bd="#B4E9F6" style={{ fontSize: 10, padding: "3px 8px" }}>POSTULANTE</Pill>
                          : <React.Fragment>
                              <Pill color={C.ink} bg={C.lime} style={{ fontSize: 10, padding: "3px 8px" }}>NV. {cd.level}</Pill>
                              <Pill color={C.orangeDk} bg={C.orangeSoft} bd={C.orangeSoftBd} style={{ fontSize: 10, padding: "3px 8px" }}>STREAK {cd.streak}</Pill>
                            </React.Fragment>}
                        <Pill color={sm.color} bg={sm.bg} bd={sm.border} style={{ fontSize: 10, padding: "3px 8px" }}>{sm.label}</Pill>
                      </div>
                    </div>
                    <div style={{ flexShrink: 0, textAlign: "center" }}>
                      <div style={{ fontSize: 19, fontWeight: 800, color: cd.matchColor, lineHeight: 1 }}>{cd.match}</div>
                      <div style={{ fontSize: 8, fontWeight: 800, color: C.mut, letterSpacing: "0.08em" }}>MATCH</div>
                    </div>
                  </div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {(cd.skills || []).map((sk) => (
                      <div key={sk.name}>
                        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                          <span style={{ fontSize: 11, fontWeight: 700, color: C.mut3 }}>{sk.name}</span>
                          <span style={{ fontSize: 11, fontWeight: 800, color: sk.color }}>{sk.pct}</span>
                        </div>
                        <div style={{ marginTop: 4 }}><Bar pct={sk.pct} color={sk.color} h={6} /></div>
                      </div>
                    ))}
                  </div>
                  <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                    {[cd.profession, cd.modality, cd.exp].filter(Boolean).map((t) => <span key={t} style={{ fontSize: 10, fontWeight: 700, color: C.mut3, background: C.sand, border: `1px solid ${C.line}`, padding: "4px 9px", borderRadius: 999 }}>{t}</span>)}
                  </div>
                  {(cd.desiredRoles && cd.desiredRoles.length > 0) && (
                    <div style={{ display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
                      <span style={{ fontSize: 10, fontWeight: 800, color: C.mut4, letterSpacing: "0.06em" }}>BUSCA</span>
                      {cd.desiredRoles.slice(0, 3).map((r) => <span key={r} style={{ fontSize: 10, fontWeight: 700, color: C.violetDk, background: C.violetSoft, border: `1px solid ${C.violetSoftBd}`, padding: "4px 9px", borderRadius: 999 }}>{r}</span>)}
                    </div>
                  )}
                  <div style={{ display: "flex", gap: 10 }}>
                    <span style={{ fontSize: 11, fontWeight: 700, color: C.mut2 }}>{cd.labs} Labs</span>
                    <span style={{ fontSize: 11, fontWeight: 700, color: C.mut2 }}>{cd.tests} tests</span>
                    <span style={{ fontSize: 11, fontWeight: 700, color: C.mut2 }}>{cd.badges} insignias</span>
                  </div>
                  <div style={{ display: "flex", gap: 9, marginTop: "auto" }}>
                    <Btn kind="dark" onClick={() => onOpen(cd.id)} style={{ flex: 1, padding: 11 }}>Ver perfil</Btn>
                    <Btn kind="soft" onClick={() => onContact(cd)} style={{ padding: "11px 14px" }}>Contactar</Btn>
                  </div>
                </Card>
              );
            })}
          </div>
        )}
      </div>
    );
  }

  /* ----------------------------- PIPELINE ----------------------------- */
  function Pipeline({ cands, onOpen }) {
    const cols = ["nuevo", "contactado", "entrevista", "contratado", "descartado"];
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div>
          <div style={{ fontSize: 26, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Proceso de selección</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Vacante: Operario de bodega · 3 cupos. Cambia la etapa desde el perfil del candidato.</div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 13, alignItems: "start" }}>
          {cols.map((k) => {
            const sm = STAGE_META[k];
            const items = cands.filter((c) => c.stage === k);
            return (
              <div key={k} style={{ background: sm.colBg, border: `1px solid ${sm.colBd}`, borderRadius: 20, padding: 14, display: "flex", flexDirection: "column", gap: 10 }}>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                  <span style={{ fontSize: 12, fontWeight: 800, color: sm.colColor, letterSpacing: "0.04em" }}>{sm.label.toUpperCase()}</span>
                  <span style={{ fontSize: 12, fontWeight: 800, color: sm.colColor }}>{items.length}</span>
                </div>
                {items.map((c) => (
                  <button key={c.id} onClick={() => onOpen(c.id)} style={{ border: `1px solid ${sm.colBd}`, background: "#fff", borderRadius: 14, padding: 11, cursor: "pointer", fontFamily: FONT, display: "flex", alignItems: "center", gap: 10, textAlign: "left", width: "100%" }}>
                    <Avatar name={c.name} initials={c.initials} bg={c.avatarBg} color={c.avatarColor} size={32} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 800, color: C.ink }}>{c.name}</div>
                      <div style={{ fontSize: 11, fontWeight: 700, color: C.mut }}>Nv. {c.level} · {c.match}</div>
                    </div>
                  </button>
                ))}
                {items.length === 0 && <div style={{ fontSize: 11, color: C.mut4, fontWeight: 600, padding: "6px 2px" }}>Sin candidatos</div>}
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  /* ----------------------------- REGISTRO ----------------------------- */
  function Registro({ contacts }) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div>
          <div style={{ fontSize: 26, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Registro de contactos</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Cada contacto queda registrado con canal, fecha y etapa del proceso.</div>
        </div>
        <Card style={{ overflow: "hidden" }}>
          {contacts.map((ct) => (
            <div key={ct.id} style={{ padding: "15px 16px", borderBottom: "1px solid #F3EDE6", display: "flex", gap: 13, alignItems: "center", flexWrap: "wrap" }}>
              <div style={{ width: 38, height: 38, borderRadius: 11, background: C.sand, border: `1px solid ${C.line}`, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}><Icon name="mail" color={C.mut} size={17} /></div>
              <div style={{ flex: 1, minWidth: 190 }}>
                <div style={{ fontSize: 14, fontWeight: 800, color: C.ink }}>{ct.name}</div>
                <div style={{ fontSize: 12, fontWeight: 600, color: C.mut2, marginTop: 2 }}>{ct.note}</div>
              </div>
              <Pill color={C.violetDk} bg={C.violetSoft} bd="#D9CDFF">{ct.channel}</Pill>
              <Pill color={C.orangeDk} bg={C.orangeSoft} bd={C.orangeSoftBd}>{ct.stage}</Pill>
              <span style={{ fontSize: 12, fontWeight: 700, color: C.mut, minWidth: 96, textAlign: "right" }}>{ct.date}</span>
            </div>
          ))}
        </Card>
      </div>
    );
  }

  /* ----------------------------- MIS VACANTES ----------------------------- */
  function Vacantes({ contacts, cands, onPost, onGoCand }) {
    const contratados = cands.filter((c) => c.stage === "contratado").length;
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
          <div>
            <div style={{ fontSize: 26, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Mis vacantes</div>
            <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Publicadas a través de O-Lab.</div>
          </div>
          <Btn onClick={onPost} style={{ padding: "12px 18px" }}>Publicar vacante</Btn>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(280px,1fr))", gap: 13 }}>
          <Card style={{ padding: 16 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 }}>
              <Pill color={C.green} bg={C.greenBg} bd={C.greenBd} style={{ fontSize: 10, padding: "4px 9px" }}>ACTIVA</Pill>
              <span style={{ fontSize: 11, fontWeight: 700, color: C.mut }}>Cierra 30 ago</span>
            </div>
            <div style={{ fontSize: 17, fontWeight: 800, color: C.ink, lineHeight: 1.25, marginTop: 11 }}>Operario de bodega</div>
            <div style={{ fontSize: 12, fontWeight: 600, color: C.mut2, marginTop: 4 }}>3 cupos · Medellín · $1.6M – $1.9M</div>
            <div style={{ display: "flex", gap: 14, marginTop: 13 }}>
              {[["MATCH >80%", 18, C.orange], ["CONTACTOS", contacts.length, C.violet], ["CONTRATADOS", contratados, C.green]].map(([l, v, col]) => (
                <div key={l}><div style={{ fontSize: 18, fontWeight: 800, color: col }}>{v}</div><div style={{ fontSize: 9, fontWeight: 800, color: C.mut, letterSpacing: "0.06em" }}>{l}</div></div>
              ))}
            </div>
            <Btn kind="ghost" onClick={onGoCand} style={{ width: "100%", padding: 11, marginTop: 14, borderRadius: 13 }}>Ver candidatos</Btn>
          </Card>
          <Card style={{ padding: 16 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 }}>
              <Pill color={C.orangeDk} bg={C.orangeSoft} bd={C.orangeSoftBd} style={{ fontSize: 10, padding: "4px 9px" }}>BORRADOR</Pill>
              <span style={{ fontSize: 11, fontWeight: 700, color: C.mut }}>Sin publicar</span>
            </div>
            <div style={{ fontSize: 17, fontWeight: 800, color: C.ink, lineHeight: 1.25, marginTop: 11 }}>Auxiliar de inventarios</div>
            <div style={{ fontSize: 12, fontWeight: 600, color: C.mut2, marginTop: 4 }}>2 cupos · Bello · turno diurno</div>
            <div style={{ fontSize: 12, fontWeight: 600, color: C.mut, lineHeight: 1.5, marginTop: 11 }}>Define las competencias requeridas para calcular el match de los candidatos.</div>
            <Btn kind="dark" onClick={onPost} style={{ width: "100%", padding: 11, marginTop: 14, borderRadius: 13 }}>Continuar borrador</Btn>
          </Card>
        </div>
      </div>
    );
  }

  /* ----------------------------- ESTADÍSTICAS EMPRESA ----------------------------- */
  function EmpresaStats({ cands, contacts }) {
    const total = cands.length;
    const stageCount = (k) => cands.filter((c) => c.stage === k).length;
    const funnel = [
      { k: "nuevo", label: "Nuevos", n: stageCount("nuevo"), color: C.mut3 },
      { k: "contactado", label: "Contactados", n: stageCount("contactado"), color: C.violet },
      { k: "entrevista", label: "Entrevistados", n: stageCount("entrevista"), color: C.orange },
      { k: "contratado", label: "Contratados", n: stageCount("contratado"), color: C.green },
      { k: "descartado", label: "Descartados", n: stageCount("descartado"), color: "#C0392B" },
    ];
    const contratados = stageCount("contratado");
    const conv = total ? Math.round((contratados / total) * 100) : 0;
    const matches = cands.map((c) => parseInt(c.match, 10)).filter((n) => !isNaN(n));
    const avgMatch = matches.length ? Math.round(matches.reduce((a, b) => a + b, 0) / matches.length) : 0;
    const chan = {};
    contacts.forEach((c) => { const k = c.channel || "Otro"; chan[k] = (chan[k] || 0) + 1; });
    const channels = Object.keys(chan).map((k) => ({ label: k, count: chan[k] })).sort((a, b) => b.count - a.count);
    const maxF = Math.max(1, ...funnel.map((f) => f.n));
    const maxC = Math.max(1, ...channels.map((c) => c.count));
    const tile = (label, value, color) => (
      <Card style={{ padding: "14px 12px", textAlign: "center", borderRadius: 16 }}>
        <div style={{ fontSize: 22, fontWeight: 800, color }}>{value}</div>
        <div style={{ fontSize: 9, fontWeight: 800, color: C.mut, letterSpacing: "0.04em", marginTop: 3 }}>{label}</div>
      </Card>
    );
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div>
          <div style={{ fontSize: 26, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Estadísticas del proceso</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Cómo va tu reclutamiento con los candidatos que has estado gestionando.</div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(120px,1fr))", gap: 8 }}>
          {tile("EN PROCESO", total, C.ink)}
          {tile("CONTACTADOS", stageCount("contactado") + stageCount("entrevista") + contratados, C.violet)}
          {tile("ENTREVISTAS", stageCount("entrevista"), C.orange)}
          {tile("CONTRATADOS", contratados, C.green)}
          {tile("CONVERSIÓN", conv + "%", C.pink)}
          {tile("MATCH PROM.", avgMatch + "%", C.cyan)}
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(260px,1fr))", gap: 12 }}>
          <Card style={{ padding: 16 }}>
            <div style={{ fontSize: 14, fontWeight: 800, color: C.ink, marginBottom: 12 }}>Embudo de selección</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
              {funnel.map((f) => (
                <div key={f.k}>
                  <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}><span style={{ fontSize: 12, fontWeight: 700, color: C.mut3 }}>{f.label}</span><span style={{ fontSize: 12, fontWeight: 800, color: f.color }}>{f.n}</span></div>
                  <Bar pct={Math.round((f.n / maxF) * 100) + "%"} color={f.color} h={8} />
                </div>
              ))}
            </div>
          </Card>
          <Card style={{ padding: 16 }}>
            <div style={{ fontSize: 14, fontWeight: 800, color: C.ink, marginBottom: 12 }}>Contactos por canal</div>
            {channels.length === 0 ? <div style={{ fontSize: 12, fontWeight: 600, color: C.mut }}>Aún no has registrado contactos.</div> : (
              <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
                {channels.map((c, i) => (
                  <div key={i}>
                    <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}><span style={{ fontSize: 12, fontWeight: 700, color: C.mut3 }}>{c.label}</span><span style={{ fontSize: 12, fontWeight: 800, color: C.violet }}>{c.count}</span></div>
                    <Bar pct={Math.round((c.count / maxC) * 100) + "%"} color={C.violet} h={8} />
                  </div>
                ))}
              </div>
            )}
            <div style={{ marginTop: 14, background: C.sand, borderRadius: 12, padding: "11px 13px", display: "flex", alignItems: "center", gap: 8 }}>
              <Icon name="mail" color={C.mut} size={16} /><span style={{ fontSize: 12, fontWeight: 700, color: C.mut2 }}>{contacts.length} contactos registrados en total</span>
            </div>
          </Card>
        </div>
      </div>
    );
  }

  /* ----------------------------- MODAL CANDIDATO ----------------------------- */
  function CandidateModal({ cand, onClose, setStage, onContact }) {
    const [cvOpen, setCvOpen] = useState(false);
    const [evidences, setEvidences] = useState([]);
    const sm = STAGE_META[cand.stage] || STAGE_META.nuevo;
    const email = cand.email || (cand.name.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/ /g, ".") + "@correo.com");
    const phone = cand.phone || ("+57 300 000 00" + (cand.id || "0").replace(/\D/g, ""));
    const waDigits = phone.replace(/\D/g, "");
    const waLink = "https://wa.me/" + waDigits + "?text=" + encodeURIComponent("Hola " + cand.name + ", vimos tu perfil en O-Lab y nos interesa para una vacante. ¿Podemos conversar?");
    const mailLink = "mailto:" + email + "?subject=" + encodeURIComponent("Oportunidad laboral · O-Lab") + "&body=" + encodeURIComponent("Hola " + cand.name + ",\n\nVimos tu perfil en O-Lab y nos gustaría contactarte para una vacante.");
    const testsDone = Object.values(cand.testResults || {});
    function downloadHV() { if (cand.cvUrl) window.open(cand.cvUrl, "_blank"); else setCvOpen(true); onContact && onContact("Descargó HV"); }
    function addEvidence(e) {
      const files = Array.from(e.target.files || []).map((file) => ({ name: file.name, size: (file.size / 1024 / 1024).toFixed(1) + " MB", kind: /\.pdf$/i.test(file.name) ? "PDF" : "IMG" }));
      e.target.value = ""; setEvidences((ev) => ev.concat(files));
    }
    return (
      <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 60, background: "rgba(23,19,31,0.62)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: 24, overflowY: "auto" }}>
        <div onClick={(e) => e.stopPropagation()} style={{ width: "100%", maxWidth: 760, background: C.cream, borderRadius: 26, overflow: "hidden", animation: "olabRise .25s ease both", marginBottom: 40 }}>
          <div style={{ padding: 22, background: C.heroGrad, display: "flex", gap: 16, alignItems: "center", flexWrap: "wrap" }}>
            <div style={{ width: 74, height: 74, borderRadius: 999, background: "conic-gradient(#FF6600 0turn 0.7turn, rgba(255,255,255,0.16) 0.7turn 1turn)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
              {cand.photoUrl
                ? <img src={cand.photoUrl} alt="foto" style={{ width: 62, height: 62, borderRadius: 999, objectFit: "cover" }} />
                : <Avatar name={cand.name} initials={cand.initials} bg={cand.avatarBg} color={cand.avatarColor} size={62} />}
            </div>
            <div style={{ flex: 1, minWidth: 200 }}>
              <div style={{ fontSize: 22, fontWeight: 800, color: "#fff", letterSpacing: "-0.02em" }}>{cand.name}</div>
              <div style={{ fontSize: 13, fontWeight: 600, color: "rgba(255,255,255,0.62)", marginTop: 3 }}>{cand.role} · {cand.city}</div>
              <div style={{ display: "flex", gap: 6, marginTop: 10, flexWrap: "wrap" }}>
                <Pill color={C.ink} bg={C.lime} style={{ fontSize: 10 }}>NV. {cand.level} · {cand.xp}</Pill>
                <Pill color="#fff" bg="rgba(255,255,255,0.14)" style={{ fontSize: 10 }}>STREAK {cand.streak}</Pill>
                <Pill color="#fff" bg="rgba(255,255,255,0.14)" style={{ fontSize: 10 }}>MATCH {cand.match}</Pill>
              </div>
            </div>
            <button onClick={onClose} style={{ border: "1px solid rgba(255,255,255,0.24)", background: "rgba(255,255,255,0.08)", color: "#fff", fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "9px 13px", borderRadius: 999, cursor: "pointer" }}>Cerrar</button>
          </div>

          <div style={{ padding: 18, display: "flex", flexDirection: "column", gap: 13 }}>
            <Card style={{ padding: 16 }}>
              <div style={{ fontSize: 11, fontWeight: 800, letterSpacing: "0.1em", color: C.mut4 }}>ETAPA DEL PROCESO</div>
              <div style={{ display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }}>
                {[["contactado", "Contactado"], ["entrevista", "Entrevistado"], ["contratado", "Contratado"], ["descartado", "Descartado"]].map(([k, label]) => {
                  const on = cand.stage === k; const m = STAGE_META[k];
                  return <button key={k} onClick={() => setStage(cand.id, k)} style={{ border: `1px solid ${on ? m.border : C.line2}`, background: on ? m.bg : "#fff", color: on ? m.color : C.mut3, fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "10px 14px", borderRadius: 999, cursor: "pointer" }}>{label}</button>;
                })}
              </div>
              <div style={{ fontSize: 12, fontWeight: 700, color: C.mut2, marginTop: 11 }}>Etapa actual: <span style={{ color: sm.color }}>{sm.label}</span> · el cambio queda en el registro</div>
            </Card>

            <Card style={{ padding: 16 }}>
              <div style={{ fontSize: 11, fontWeight: 800, letterSpacing: "0.1em", color: C.mut4 }}>CONTACTO DIRECTO</div>
              <div style={{ display: "flex", gap: 16, flexWrap: "wrap", marginTop: 8 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 7 }}><Icon name="mail" color={C.mut} size={16} /><span style={{ fontSize: 13, fontWeight: 700, color: C.ink }}>{email}</span></div>
                <div style={{ display: "flex", alignItems: "center", gap: 7 }}><Icon name="phone" color={C.mut} size={16} /><span style={{ fontSize: 13, fontWeight: 700, color: C.ink }}>{phone}</span></div>
              </div>
              <div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
                <a href={waLink} target="_blank" rel="noopener noreferrer" onClick={() => onContact && onContact("WhatsApp")} style={{ display: "flex", alignItems: "center", gap: 7, textDecoration: "none", background: "#25D366", color: "#fff", fontFamily: FONT, fontSize: 13, fontWeight: 800, padding: "11px 15px", borderRadius: 14 }}><Icon name="whatsapp" color="#fff" size={17} />Escribir por WhatsApp</a>
                <a href={mailLink} onClick={() => onContact && onContact("Correo")} style={{ display: "flex", alignItems: "center", gap: 7, textDecoration: "none", background: C.violetSoft, color: C.violetDk, border: `1px solid ${C.violetSoftBd}`, fontFamily: FONT, fontSize: 13, fontWeight: 800, padding: "11px 15px", borderRadius: 14 }}><Icon name="mail" color={C.violetDk} size={17} />Enviar correo</a>
                <button onClick={downloadHV} style={{ display: "flex", alignItems: "center", gap: 7, border: 0, background: C.ink, color: "#fff", fontFamily: FONT, fontSize: 13, fontWeight: 800, padding: "11px 15px", borderRadius: 14, cursor: "pointer" }}><Icon name="external" color={C.lime} size={16} />Descargar HV</button>
              </div>
            </Card>

            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 13 }}>
              <Card style={{ padding: 16 }}>
                <div style={{ fontSize: 15, fontWeight: 800, color: C.ink }}>Competencias validadas</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 11, marginTop: 13 }}>
                  {(cand.skills || []).map((ks) => (
                    <div key={ks.name}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                        <span style={{ fontSize: 12, fontWeight: 700, color: "#3D3548" }}>{ks.name}</span>
                        <span style={{ fontSize: 12, fontWeight: 800, color: ks.color }}>{ks.pct}</span>
                      </div>
                      <div style={{ marginTop: 5 }}><Bar pct={ks.pct} color={ks.color} h={7} /></div>
                    </div>
                  ))}
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 8, marginTop: 15 }}>
                  {[["LABS", cand.labs, C.orange], ["TESTS", cand.tests, C.violet], ["INSIGNIAS", cand.badges, C.green]].map(([l, v, col]) => (
                    <div key={l} style={{ background: C.sand, borderRadius: 13, padding: 10, textAlign: "center" }}><div style={{ fontSize: 16, fontWeight: 800, color: col }}>{v}</div><div style={{ fontSize: 8, fontWeight: 800, color: C.mut, letterSpacing: "0.06em", marginTop: 2 }}>{l}</div></div>
                  ))}
                </div>
              </Card>

              <Card style={{ padding: 16 }}>
                <div style={{ fontSize: 15, fontWeight: 800, color: C.ink }}>Labs completados</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 12 }}>
                  {(cand.labList || []).map((l, i) => (
                    <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12, fontWeight: 600, color: C.mut2 }}><Icon name="check" color={C.green} size={16} />{l}</div>
                  ))}
                </div>
                {testsDone.length > 0 && (
                  <div style={{ marginTop: 12 }}>
                    <div style={{ fontSize: 12, fontWeight: 800, color: C.ink, marginBottom: 6 }}>Tests realizados</div>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                      {testsDone.map((t, i) => <Pill key={i} color={C.green} bg={C.greenBg}>{t.label}{t.pct != null ? " · " + t.pct + "/100" : ""}</Pill>)}
                    </div>
                  </div>
                )}
                <div style={{ height: 1, background: C.line, margin: "14px 0" }} />
                <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                  <Btn kind="dark" onClick={() => setCvOpen(true)} style={{ flex: 1, padding: 11 }}>Ver CV</Btn>
                  <Btn kind="soft" onClick={() => onContact("WhatsApp")} style={{ padding: "11px 13px" }}>Contactar</Btn>
                </div>
                <label style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 8, marginTop: 10, border: `1px dashed ${C.line2}`, borderRadius: 13, padding: "11px", cursor: "pointer", fontSize: 12, fontWeight: 800, color: C.mut3 }}>
                  <Icon name="plus" size={16} color={C.mut3} />Subir evidencia
                  <input type="file" multiple onChange={addEvidence} style={{ display: "none" }} />
                </label>
                {evidences.length > 0 && (
                  <div style={{ display: "flex", flexDirection: "column", gap: 6, marginTop: 8 }}>
                    {evidences.map((f, i) => (
                      <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 11, fontWeight: 700, color: C.mut2, background: C.sand, borderRadius: 10, padding: "7px 10px" }}>
                        <Pill color={f.kind === "PDF" ? C.orangeDk : C.cyanDk} bg={f.kind === "PDF" ? C.orangeSoft : C.cyanSoft} style={{ fontSize: 9, padding: "2px 6px" }}>{f.kind}</Pill>
                        <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{f.name}</span>
                        <span>{f.size}</span>
                      </div>
                    ))}
                  </div>
                )}
              </Card>
            </div>
          </div>

          {cvOpen && (
            <div onClick={() => setCvOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 70, background: "rgba(23,19,31,0.7)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: 24, overflowY: "auto" }}>
              <div onClick={(e) => e.stopPropagation()} style={{ width: "100%", maxWidth: 640, background: "#fff", borderRadius: 24, padding: "36px 40px", marginBottom: 40 }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
                  <div>
                    <div style={{ fontSize: 24, fontWeight: 800, color: C.ink }}>{cand.name}</div>
                    <div style={{ fontSize: 13, color: C.mut2, marginTop: 4 }}>{cand.role} · {cand.city}</div>
                    <div style={{ fontSize: 12, color: C.mut, marginTop: 2 }}>{email} · +57 300 000 00{cand.id.replace("c", "")}</div>
                  </div>
                  <button onClick={() => setCvOpen(false)} style={{ border: `1px solid ${C.line2}`, background: "#fff", borderRadius: 999, width: 32, height: 32, cursor: "pointer", color: C.mut3 }}><Icon name="close" size={16} /></button>
                </div>
                <div style={{ height: 1, background: C.line, margin: "18px 0" }} />
                <div style={{ fontSize: 12, fontWeight: 800, letterSpacing: "0.08em", color: C.mut4 }}>COMPETENCIAS VALIDADAS EN O-LAB</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 12 }}>
                  {(cand.skills || []).map((ks) => (
                    <div key={ks.name}><div style={{ display: "flex", justifyContent: "space-between" }}><span style={{ fontSize: 12, fontWeight: 700, color: "#3D3548" }}>{ks.name}</span><span style={{ fontSize: 12, fontWeight: 800, color: ks.color }}>{ks.pct}</span></div><div style={{ marginTop: 5 }}><Bar pct={ks.pct} color={ks.color} h={7} /></div></div>
                  ))}
                </div>
                <div style={{ fontSize: 12, fontWeight: 800, letterSpacing: "0.08em", color: C.mut4, marginTop: 18 }}>LABS Y EXPERIENCIA</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 7, marginTop: 10 }}>
                  {(cand.labList || []).map((l, i) => <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12, fontWeight: 600, color: C.mut2 }}><Icon name="check" color={C.green} size={15} />{l}</div>)}
                </div>
                <div style={{ display: "flex", gap: 8, marginTop: 22 }}>
                  <Btn kind="ghost" onClick={() => window.print()} style={{ flex: 1, padding: 12 }}>Descargar / imprimir</Btn>
                  <Btn onClick={() => { onContact("Correo"); setCvOpen(false); }} style={{ flex: 1, padding: 12 }}>Contactar candidato</Btn>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    );
  }

  /* ----------------------------- MODAL PUBLICAR VACANTE ----------------------------- */
  function PostVacancyModal({ onClose, onSaved }) {
    const today = new Date().toISOString().slice(0, 10);
    const [v, setV] = useState({ cargo: "", cupos: "1", fechaPublicacion: today, fechaCierre: "", salario: "", ubicacion: "", ciudad: "", modalidad: "Presencial", tipoContrato: "Indefinido", descripcion: "", requisitos: "", link: "", recibirCV: true });
    const set = (k) => (e) => setV({ ...v, [k]: e.target.value });
    const inp = { fontFamily: FONT, fontSize: 13, fontWeight: 600, color: C.ink, background: C.sand, border: `1px solid ${C.line2}`, borderRadius: 12, padding: "11px 12px", width: "100%", boxSizing: "border-box" };
    const cap = { fontSize: 10, fontWeight: 800, letterSpacing: "0.08em", color: C.mut4, marginBottom: 5, display: "block" };
    async function save() {
      if (!v.cargo) return;
      const codigo = "EMP-" + v.cargo.slice(0, 3).toUpperCase().replace(/\s/g, "") + "-" + String(Date.now()).slice(-4);
      const r = await B().postVacancy({ ...v, codigo_vacante: codigo });
      onSaved(r.demo ? "Vacante lista (modo demo, inicia sesión para publicar)" : "Vacante publicada · aparecerá en la red O-Lab");
    }
    return (
      <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 65, background: "rgba(23,19,31,0.62)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: 24, overflowY: "auto" }}>
        <div onClick={(e) => e.stopPropagation()} style={{ width: "100%", maxWidth: 580, background: "#fff", borderRadius: 24, padding: 24, marginBottom: 40, animation: "olabRise .25s ease both" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <div style={{ fontSize: 20, fontWeight: 800, color: C.ink }}>Publicar vacante</div>
            <button onClick={onClose} style={{ border: `1px solid ${C.line2}`, background: "#fff", borderRadius: 999, width: 32, height: 32, cursor: "pointer", color: C.mut3 }}><Icon name="close" size={16} /></button>
          </div>
          <div style={{ fontSize: 12, fontWeight: 600, color: C.mut, marginTop: 4 }}>Se publica en la red O-Lab y alimenta el tablero de Vacantes de Projects.</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 18 }}>
            <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 12 }}>
              <div><label style={cap}>NOMBRE DEL CARGO</label><input value={v.cargo} onChange={set("cargo")} placeholder="Operario de bodega" style={inp} /></div>
              <div><label style={cap}>N° DE VACANTES</label><input value={v.cupos} onChange={set("cupos")} type="number" min="1" style={inp} /></div>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              <div><label style={cap}>FECHA DE PUBLICACIÓN</label><input value={v.fechaPublicacion} onChange={set("fechaPublicacion")} type="date" style={inp} /></div>
              <div><label style={cap}>FECHA DE CIERRE</label><input value={v.fechaCierre} onChange={set("fechaCierre")} type="date" style={inp} /></div>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              <div><label style={cap}>SALARIO</label><input value={v.salario} onChange={set("salario")} placeholder="$1.6M – $1.9M" style={inp} /></div>
              <div><label style={cap}>CIUDAD</label><input value={v.ciudad} onChange={set("ciudad")} placeholder="Medellín" style={inp} /></div>
            </div>
            <div><label style={cap}>UBICACIÓN (dirección / zona)</label><input value={v.ubicacion} onChange={set("ubicacion")} placeholder="Bodega Zona Franca, Itagüí" style={inp} /></div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              <div><label style={cap}>MODALIDAD</label><select value={v.modalidad} onChange={set("modalidad")} style={{ ...inp, cursor: "pointer" }}>{["Presencial", "Remoto", "Híbrido"].map((m) => <option key={m}>{m}</option>)}</select></div>
              <div><label style={cap}>TIPO DE CONTRATO</label><select value={v.tipoContrato} onChange={set("tipoContrato")} style={{ ...inp, cursor: "pointer" }}>{["Fijo", "Indefinido", "OPS", "Aprendizaje", "Prácticas"].map((m) => <option key={m}>{m}</option>)}</select></div>
            </div>
            <div><label style={cap}>DESCRIPCIÓN DEL CARGO</label><textarea value={v.descripcion} onChange={set("descripcion")} rows={3} placeholder="Funciones, responsabilidades, horario…" style={{ ...inp, resize: "vertical" }} /></div>
            <div><label style={cap}>REQUISITOS DEL CANDIDATO</label><textarea value={v.requisitos} onChange={set("requisitos")} rows={3} placeholder="Inventarios, seguridad industrial, test de montacargas…" style={{ ...inp, resize: "vertical" }} /></div>
            <div><label style={cap}>LINK DE LA VACANTE (opcional)</label><input value={v.link} onChange={set("link")} placeholder="https://…" style={inp} /></div>
            <label style={{ display: "flex", alignItems: "center", gap: 9, cursor: "pointer", background: C.sand, borderRadius: 12, padding: "11px 12px" }}>
              <input type="checkbox" checked={v.recibirCV} onChange={(e) => setV({ ...v, recibirCV: e.target.checked })} style={{ width: 18, height: 18, cursor: "pointer" }} />
              <span style={{ fontSize: 13, fontWeight: 700, color: C.ink }}>Recibir la hoja de vida de los candidatos directamente</span>
            </label>
          </div>
          <div style={{ display: "flex", gap: 8, marginTop: 20 }}>
            <Btn kind="ghost" onClick={onClose} style={{ flex: 1, padding: 13 }}>Cancelar</Btn>
            <Btn onClick={save} style={{ flex: 1.4, padding: 13 }}>Publicar vacante</Btn>
          </div>
        </div>
      </div>
    );
  }

  /* ----------------------------- FEED EMPRESAS ----------------------------- */
  function EmpFeedReactions({ postId }) {
    const [rx, setRx] = useState({ count: 0, mine: false });
    useEffect(() => B().subscribeReactions(postId, setRx), [postId]);
    return (
      <button onClick={() => B().reactPost(postId, !rx.mine)} style={{ border: 0, background: "transparent", padding: 0, display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontFamily: FONT }}>
        <Icon name="heart" size={19} color={rx.mine ? C.pink : C.mut3} fill={rx.mine ? C.pink : "none"} />
        <span style={{ fontSize: 12, fontWeight: 700, color: C.mut3 }}>{rx.count}{rx.mine ? " · Te gusta" : ""}</span>
      </button>
    );
  }
  function EmpresaFeed({ isAdmin, company }) {
    const [posts, setPosts] = useState(null);
    const [text, setText] = useState("");
    const [image, setImage] = useState("");
    const [busy, setBusy] = useState(false);
    const [imgBusy, setImgBusy] = useState(false);
    useEffect(() => B().subscribeFeed((l) => setPosts(l)), []);
    const list = (Array.isArray(posts) ? posts : []).filter((p) => !p.audience || p.audience === "todos" || p.audience === "empresas");
    async function onImg(e) { const f = e.target.files && e.target.files[0]; e.target.value = ""; if (!f) return; setImgBusy(true); try { const url = await B().uploadFeedImage(f); setImage(url); } catch (err) { console.warn(err); } finally { setImgBusy(false); } }
    async function publish() { if (!text.trim() && !image) return; setBusy(true); try { await B().publishPost({ text, image, audience: "empresas" }); setText(""); setImage(""); } catch (e) { console.warn(e); } finally { setBusy(false); } }
    function fmtLink(t) {
      const parts = String(t || "").split(/(https?:\/\/[^\s]+)/g);
      return parts.map((p, i) => /^https?:\/\//.test(p) ? <a key={i} href={p} target="_blank" rel="noopener noreferrer" style={{ color: C.orange, fontWeight: 700, wordBreak: "break-all" }}>{p}</a> : p);
    }
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 14, maxWidth: 640, margin: "0 auto" }}>
        <div>
          <div style={{ fontSize: 22, fontWeight: 800, color: C.ink, letterSpacing: "-0.02em" }}>Feed de empresas</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: C.mut, marginTop: 4 }}>Novedades, oportunidades y anuncios de O-Lab para las empresas aliadas.</div>
        </div>
        {isAdmin ? (
          <div style={{ background: "#fff", border: `1px solid ${C.line}`, borderRadius: 18, padding: 14 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}><Pill color={C.violetDk} bg={C.violetSoft}>ADMIN</Pill><span style={{ fontSize: 13, fontWeight: 800, color: C.ink }}>Publicar para empresas</span></div>
            <textarea value={text} onChange={(e) => setText(e.target.value)} rows={2} placeholder="Comparte un anuncio u oportunidad con las empresas…" style={{ width: "100%", boxSizing: "border-box", fontFamily: FONT, fontSize: 13, fontWeight: 500, color: C.ink, background: C.sand, border: `1px solid ${C.line2}`, borderRadius: 14, padding: "10px 12px", resize: "vertical" }} />
            {image && <div style={{ position: "relative", marginTop: 10 }}><img src={image} alt="" style={{ width: "100%", height: "auto", display: "block", borderRadius: 12, background: C.sand }} /><button onClick={() => setImage("")} style={{ position: "absolute", top: 8, right: 8, border: 0, background: "rgba(23,19,31,0.7)", color: "#fff", borderRadius: 999, width: 26, height: 26, cursor: "pointer" }}>✕</button></div>}
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 10 }}>
              <label style={{ display: "flex", alignItems: "center", gap: 7, border: `1px solid ${C.line2}`, background: "#fff", color: C.mut3, fontFamily: FONT, fontSize: 12, fontWeight: 800, padding: "8px 12px", borderRadius: 999, cursor: "pointer" }}><Icon name="plus" size={14} color={C.mut3} />{imgBusy ? "Subiendo…" : image ? "Cambiar imagen" : "Imagen"}<input type="file" accept="image/*" onChange={onImg} style={{ display: "none" }} /></label>
              <Btn onClick={publish} style={{ padding: "9px 16px", fontSize: 13, opacity: busy ? 0.6 : 1 }}>{busy ? "Publicando…" : "Publicar"}</Btn>
            </div>
          </div>
        ) : (
          <div style={{ background: C.sand, border: `1px solid ${C.line}`, borderRadius: 16, padding: "12px 14px", display: "flex", alignItems: "center", gap: 10 }}>
            <Icon name="chat" color={C.mut} size={18} /><span style={{ fontSize: 12, fontWeight: 700, color: C.mut2 }}>Solo O-Lab publica aquí. Puedes reaccionar a las publicaciones. 💬</span>
          </div>
        )}
        {posts === null && <div style={{ padding: 24, textAlign: "center", color: C.mut, fontWeight: 700 }}>Cargando…</div>}
        {posts !== null && list.length === 0 && <div style={{ background: "#fff", border: "1px dashed #D6CEC4", borderRadius: 18, padding: 28, textAlign: "center", fontSize: 13, fontWeight: 600, color: C.mut }}>Aún no hay publicaciones para empresas.</div>}
        {list.map((p) => (
          <div key={p.id} style={{ background: "#fff", border: `1px solid ${C.line}`, borderRadius: 18, overflow: "hidden" }}>
            <div style={{ padding: 14, display: "flex", gap: 10, alignItems: "center" }}>
              {p.authorPhoto ? <img src={p.authorPhoto} alt="" style={{ width: 38, height: 38, borderRadius: 999, objectFit: "cover" }} /> : <div style={{ width: 38, height: 38, borderRadius: 999, background: "linear-gradient(135deg,#6C4CF1,#12C2E9)", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff", fontWeight: 800, fontSize: 13 }}>{(p.authorName || "O").slice(0, 1).toUpperCase()}</div>}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 800, color: C.ink }}>{p.authorName || "O-Lab"} <Pill color={C.violetDk} bg={C.violetSoft} style={{ fontSize: 9, padding: "2px 6px" }}>O-LAB</Pill></div>
                <div style={{ fontSize: 11, color: C.mut, fontWeight: 600 }}>Para empresas</div>
              </div>
              {isAdmin && <button onClick={() => B().deletePost(p.id)} title="Eliminar" style={{ border: 0, background: "transparent", cursor: "pointer", color: C.mut4 }}><Icon name="close" size={16} /></button>}
            </div>
            {p.text && <div style={{ padding: "0 14px 12px", fontSize: 14, fontWeight: 500, color: "#3D3548", lineHeight: 1.55, whiteSpace: "pre-wrap" }}>{fmtLink(p.text)}</div>}
            {p.image && <a href={p.link || p.image} target="_blank" rel="noopener noreferrer" style={{ display: "block", margin: "0 14px 12px" }}><img src={p.image} alt="" style={{ width: "100%", height: "auto", display: "block", borderRadius: 14, background: C.sand }} /></a>}
            <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "10px 14px 14px", borderTop: `1px solid ${C.line}` }}>
              <EmpFeedReactions postId={p.id} />
            </div>
          </div>
        ))}
      </div>
    );
  }

  window.EmpresaApp = EmpresaApp;
})();
