/* ============================================================
   SYMPHO — root: routing, shell, theming, tweaks
   ============================================================ */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "navModel": "rail",
  "theme": "dark",
  "density": "regular",
  "brand": "#8b7bf0"
}/*EDITMODE-END*/;

// brand swatch -> oklch hue override for --sympho
const BRANDS = {
  "#8b7bf0": { name: "Indigo", sympho: "oklch(0.72 0.135 274)", dim: "oklch(0.72 0.135 274 / 0.16)" },
  "#5fb8c9": { name: "Cian",   sympho: "oklch(0.74 0.115 215)", dim: "oklch(0.74 0.115 215 / 0.16)" },
  "#c98fd6": { name: "Violeta",sympho: "oklch(0.74 0.135 320)", dim: "oklch(0.74 0.135 320 / 0.16)" },
  "#6fc89b": { name: "Esmeralda", sympho: "oklch(0.74 0.115 162)", dim: "oklch(0.74 0.115 162 / 0.16)" },
};

function appAccent(appId) {
  const a = window.APPS.find(x => x.id === appId);
  if (!a) return null;
  // dim variants map per app
  const dims = { ek: "var(--ek-dim)", muluk: "var(--muluk-dim)", manik: "var(--manik-dim)", pakal: "var(--pakal-dim)", zamna: "var(--zamna-dim)", eb: "var(--eb-dim)", kin: "var(--kin-dim)" };
  return { accent: a.hue, dim: dims[appId] || "var(--sympho-dim)" };
}

// apps that present several role personas (role -> nav + role meta)
function roleConfig(appId) {
  if (appId === "eb") return { nav: window.EB_NAV, roles: window.EB_ROLES, def: "master" };
  if (appId === "zamna") return { nav: window.ZAMNA_NAV, roles: window.ZAMNA_ROLES, def: "admin" };
  if (appId === "kin") return { nav: window.KIN_NAV, roles: window.KIN_ROLES, def: "fm" };
  if (appId === "pakal") return { nav: window.PAKAL_NAV, roles: window.PAKAL_ROLES, def: "am" };
  return null;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [loc, setLoc] = useState({ view: "login", appId: null, sub: null });
  const [cmd, setCmd] = useState(false);
  const [roles, setRoles] = useState({ eb: "master", zamna: "admin", kin: "fm", pakal: "am" });
  const [ebLang, setEbLang] = useState("es");
  const [i18nBump, setI18nBump] = useState(0);
  const [ebProfile, setEbProfileState] = useState("superadmin");
  const [ebChatOpen, setEbChatOpen] = useState(false);

  const go = (next) => {
    setLoc(prev => ({ view: next.view ?? prev.view, appId: next.appId ?? null, sub: next.sub ?? null }));
    const sc = document.querySelector(".canvas, .login");
    if (sc) sc.scrollTop = 0;
  };
  const openApp = (appId, sub = null) => {
    const rc = roleConfig(appId);
    if (rc) {
      const items = rc.nav[roles[appId]] || rc.nav[rc.def];
      go({ view: "app", appId, sub: sub || items[0].id });
      return;
    }
    const a = window.APPS.find(x => x.id === appId);
    go({ view: "app", appId, sub: sub || (a && a.nav[0] ? a.nav[0].id : null) });
  };
  const changeRole = (appId, role) => {
    const rc = roleConfig(appId);
    if (!rc) return;
    setRoles(prev => ({ ...prev, [appId]: role }));
    let items = rc.nav[role] || rc.nav[rc.def];
    if (appId === "eb" && window.ebFilterNav) items = window.ebFilterNav(items, ebProfile);
    go({ view: "app", appId, sub: items[0].id });
  };
  const setEbProfile = (profile) => {
    setEbProfileState(profile);
    if (loc.view === "app" && loc.appId === "eb") {
      const items = window.ebFilterNav(window.EB_NAV[roles.eb] || window.EB_NAV.master, profile);
      if (!items.some(n => n.id === loc.sub)) go({ view: "app", appId: "eb", sub: items[0].id });
    }
  };

  // ⌘K
  useEffect(() => {
    const h = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); if (loc.view !== "login") setCmd(v => !v); }
      if (e.key === "Escape") setCmd(false);
    };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [loc.view]);

  const nav = { loc, go, openApp, roles, role: (id) => roles[id], setRole: changeRole,
    ebRole: roles.eb, setEbRole: (r) => changeRole("eb", r),
    ebLang, setEbLang, i18nBump, bumpI18n: () => setI18nBump(v => v + 1),
    ebProfile, setEbProfile,
    ebChatOpen, setEbChatOpen };

  // ---- accent / brand theming ----
  const brand = BRANDS[t.brand] || BRANDS["#8b7bf0"];
  const acc = loc.view === "app" ? appAccent(loc.appId) : null;
  const rootStyle = {
    "--sympho": brand.sympho,
    "--sympho-dim": brand.dim,
    "--accent": acc ? acc.accent : brand.sympho,
    "--accent-dim": acc ? acc.dim : brand.dim,
  };

  useEffect(() => {
    document.documentElement.setAttribute("data-theme", t.theme === "light" ? "light" : "dark");
    document.documentElement.setAttribute("data-density", t.density);
  }, [t.theme, t.density]);

  return (
    <NavCtx.Provider value={nav}>
      <div style={rootStyle}>
        {loc.view === "login"
          ? <LoginView />
          : <Shell navModel={t.navModel} loc={loc} onCommand={() => setCmd(true)} />}
        {window.EbChatSidebar && <window.EbChatSidebar open={loc.view === "app" && loc.appId === "eb" && ebChatOpen} onClose={() => setEbChatOpen(false)} />}
        <CommandPalette open={cmd} onClose={() => setCmd(false)} />
        <TweaksUI t={t} setTweak={setTweak} />
      </div>
    </NavCtx.Provider>
  );
}

// ---------------- the workspace shell ----------------
function Shell({ navModel, loc, onCommand }) {
  const railOn = navModel === "rail";
  const inApp = loc.view === "app";
  const sideOn = inApp;
  const mini = navModel === "command";

  return (
    <div className="shell" data-rail={railOn ? "on" : "off"}>
      {railOn && <AppRail />}
      <div className="shell-main">
        <TopBar onCommand={onCommand} />
        <div className="shell-body" data-side={sideOn ? "on" : "off"} style={sideOn && mini ? { gridTemplateColumns: "var(--rail-w) 1fr" } : undefined}>
          {sideOn && <AppSidebar appId={loc.appId} sub={loc.sub} showBack={!railOn} mini={mini} />}
          <main className="canvas">
            <Router loc={loc} />
          </main>
        </div>
      </div>
    </div>
  );
}

// ---------------- contextual app sidebar ----------------
function AppSidebar({ appId, sub, showBack, mini }) {
  const nav = useNav();
  const a = window.APPS.find(x => x.id === appId);
  if (!a) return null;
  const rc = roleConfig(appId);
  const role = rc ? nav.role(appId) : null;
  let items = rc ? (rc.nav[role] || rc.nav[rc.def]) : a.nav;
  if (appId === "eb" && window.ebFilterNav) items = window.ebFilterNav(items, nav.ebProfile);
  if (mini) {
    return (
      <nav className="rail" style={{ background: "var(--bg-2)" }}>
        <button className="rail-item" onClick={() => nav.go({ view: "hub" })} title="Inicio" style={{ "--ind": "var(--sympho)" }}><Icon name="home" size={20} /><span className="rail-tip">Inicio</span></button>
        <div className="rail-sep" />
        {items.map(n => {
          const label = (appId === "eb" && window.ebNavLabel) ? window.ebNavLabel(n.id, nav.ebLang, n.label) : n.label;
          return (
            <button key={n.id} className="rail-item" data-on={sub === n.id} onClick={() => nav.openApp(a.id, n.id)} title={label} style={{ "--ind": a.hue }}>
              <span className="rail-ind" /><Icon name={n.icon} size={20} /><span className="rail-tip">{label}</span>
            </button>
          );
        })}
      </nav>
    );
  }
  return (
    <aside className="side">
      <div className="side-head">
        <Glyph app={a} size={34} radius={9} />
        <div style={{ minWidth: 0 }}>
          <b className="disp" style={{ fontSize: 15, display: "block", letterSpacing: "-0.01em" }}>{a.name}</b>
          <span className="mono" style={{ fontSize: 10.5, color: "var(--text-4)" }}>{rc ? rc.roles[role].label : a.url}</span>
        </div>
      </div>
      {rc && (
        <div style={{ padding: "0 12px 10px" }}>
          {appId === "eb" && window.EbRoleProfileSwitch
            ? <window.EbRoleProfileSwitch rc={rc} role={role} nav={nav} />
            : <RoleSwitch rc={rc} role={role} appId={appId} nav={nav} />}
        </div>
      )}
      {showBack && (
        <div style={{ padding: "0 10px 8px" }}>
          <button className="side-link" style={{ height: 36, color: "var(--text-3)" }} onClick={() => nav.go({ view: "hub" })}>
            <Icon name="chevright" size={15} style={{ transform: "rotate(180deg)" }} /> Volver a Inicio
          </button>
        </div>
      )}
      <nav className="side-nav">
        {items.map(n => {
          const label = (appId === "eb" && window.ebNavLabel) ? window.ebNavLabel(n.id, nav.ebLang, n.label) : n.label;
          return (
            <button key={n.id} className="side-link" data-on={sub === n.id} onClick={() => nav.openApp(a.id, n.id)}>
              <Icon name={n.icon} size={18} /> {label}
            </button>
          );
        })}
      </nav>
      <div className="side-foot">
        <button className="side-link" style={{ height: 36 }} onClick={() => nav.go({ view: "modules" })}><Icon name="layers" size={17} /> Módulos de {a.name}</button>
      </div>
    </aside>
  );
}

// ---------------- role switcher (explicit literals → unique edit ids) ----------------
function RoleSwitch({ rc, role, appId, nav }) {
  const k = Object.keys(rc.roles);
  const body = (rk) => <><Icon name={rc.roles[rk].icon} size={14} />{rc.roles[rk].label.split(" ")[0]}</>;
  const cls = (rk) => "role-btn" + (role === rk ? " on" : "");
  // 4+ personas → lista vertical legible (p. ej. K'in: 5 roles)
  if (k.length > 3) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 3, padding: 3, background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 10 }}>
        {k.map(rk => {
          const on = role === rk;
          return (
            <button key={rk} onClick={() => nav.setRole(appId, rk)}
              style={{ display: "flex", alignItems: "center", gap: 9, padding: "8px 10px", borderRadius: 7, border: "none", cursor: "pointer",
                background: on ? "var(--accent)" : "transparent", color: on ? "oklch(0.16 0.02 264)" : "var(--text-3)",
                fontFamily: "var(--ui)", fontSize: 12.5, fontWeight: on ? 600 : 500, textAlign: "left", width: "100%", transition: "background 0.14s, color 0.14s" }}>
              <Icon name={rc.roles[rk].icon} size={14} /> {rc.roles[rk].label}
            </button>
          );
        })}
      </div>
    );
  }
  return (
    <div className="role-switch" style={{ gridTemplateColumns: `repeat(${k.length}, 1fr)` }}>
      {k[0] && <button className={cls(k[0])} onClick={() => nav.setRole(appId, k[0])}>{role === k[0] && <span className="role-fill" />}<span className="role-in">{body(k[0])}</span></button>}
      {k[1] && <button className={cls(k[1])} onClick={() => nav.setRole(appId, k[1])}>{role === k[1] && <span className="role-fill" />}<span className="role-in">{body(k[1])}</span></button>}
      {k[2] && <button className={cls(k[2])} onClick={() => nav.setRole(appId, k[2])}>{role === k[2] && <span className="role-fill" />}<span className="role-in">{body(k[2])}</span></button>}
      {k[3] && <button className={cls(k[3])} onClick={() => nav.setRole(appId, k[3])}>{role === k[3] && <span className="role-fill" />}<span className="role-in">{body(k[3])}</span></button>}
    </div>
  );
}

// ---------------- view router ----------------
function Router({ loc }) {
  const nav = useNav();
  if (loc.view === "hub") return <HubView />;
  if (loc.view === "modules") return <ModulesView />;
  if (loc.view === "admin") return <AdminView />;
  if (loc.view === "app") {
    switch (loc.appId) {
      case "ek": return <EkApp sub={loc.sub} />;
      case "muluk": return <MulukApp sub={loc.sub} />;
      case "manik": return <ManikApp sub={loc.sub} />;
      case "pakal": return <PakalApp sub={loc.sub} role={nav.role("pakal")} />;
      case "zamna": return <ZamnaApp sub={loc.sub} role={nav.role("zamna")} />;
      case "eb": return <EbApp role={nav.ebRole} sub={loc.sub} />;
      case "kin": return <KinApp role={nav.role("kin")} sub={loc.sub} />;
      default: return <HubView />;
    }
  }
  return <HubView />;
}

// ---------------- tweaks panel ----------------
function TweaksUI({ t, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection label="Modelo de navegación" />
      <TweakRadio label="Enfoque del flujo" value={t.navModel}
        options={[{ value: "rail", label: "Riel" }, { value: "launcher", label: "Launcher" }, { value: "command", label: "Comando" }]}
        onChange={v => setTweak("navModel", v)} />
      <div style={{ fontSize: 11, color: "var(--text-3)", padding: "2px 2px 6px", lineHeight: 1.5, fontFamily: "var(--ui)" }}>
        {t.navModel === "rail" && "Riel de apps persistente, estilo Teams. Salto directo entre módulos."}
        {t.navModel === "launcher" && "Sin riel. Todo parte de Inicio + launcher 3×3, estilo Google Workspace."}
        {t.navModel === "command" && "Chrome mínimo, sidebar de íconos. ⌘K conduce todo."}
      </div>
      <TweakSection label="Apariencia" />
      <TweakToggle label="Tema claro" value={t.theme === "light"} onChange={v => setTweak("theme", v ? "light" : "dark")} />
      <TweakRadio label="Densidad" value={t.density} options={["compact", "regular", "comfy"]} onChange={v => setTweak("density", v)} />
      <TweakColor label="Color de marca" value={t.brand}
        options={Object.keys(BRANDS)} onChange={v => setTweak("brand", v)} />
    </TweaksPanel>
  );
}

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