/* ============================================================
   App shell: sidebar, topbar, router, command palette, assistant
   ============================================================ */

/* ---------- i18n (chrome labels) ---------- */
const I18N = {
  en: {
    search: "Search students, screens, actions…", ask: "Ask AI", role: "Role", signout: "Sign out",
    g_overview: "Overview", g_students: "Students", g_pastoral: "Pastoral", g_academic: "Academic", g_knowledge: "Knowledge", g_admin: "Administration",
    dashboard: "Dashboard", radar: "At-Risk Radar", progress: "Progress Monitoring", behaviour: "Behaviour Pipeline",
    ilp: "ILP / SEN Plans", attendance: "Attendance", coursework: "IA / EE Monitor", docs: "Document Hub",
    compliance: "Compliance Cockpit", staff: "Staff & Settings", assistant: "AI Assistant",
    director: "Executive Director", teacher: "Subject Teacher",
  },
  uz: {
    search: "O‘quvchilar, sahifalar, amallar…", ask: "AI so‘rash", role: "Rol", signout: "Chiqish",
    g_overview: "Umumiy", g_students: "O‘quvchilar", g_pastoral: "Tarbiyaviy", g_academic: "Akademik", g_knowledge: "Bilim bazasi", g_admin: "Boshqaruv",
    dashboard: "Boshqaruv paneli", radar: "Xavf Radari", progress: "O‘zlashtirish", behaviour: "Xulq jarayoni",
    ilp: "ILP / SEN rejalari", attendance: "Davomat", coursework: "IA / EE monitor", docs: "Hujjatlar bazasi",
    compliance: "Muvofiqlik paneli", staff: "Xodimlar & Sozlamalar", assistant: "AI yordamchi",
    director: "Ijrochi direktor", teacher: "Fan o‘qituvchisi",
  },
  ru: {
    search: "Ученики, разделы, действия…", ask: "Спросить ИИ", role: "Роль", signout: "Выход",
    g_overview: "Обзор", g_students: "Ученики", g_pastoral: "Воспитание", g_academic: "Академика", g_knowledge: "База знаний", g_admin: "Администрирование",
    dashboard: "Панель", radar: "Радар рисков", progress: "Успеваемость", behaviour: "Дисциплина",
    ilp: "Планы ILP / SEN", attendance: "Посещаемость", coursework: "Монитор IA / EE", docs: "База документов",
    compliance: "Кокпит соответствия", staff: "Сотрудники и настройки", assistant: "ИИ-ассистент",
    director: "Исполнительный директор", teacher: "Учитель-предметник",
  },
};
function t(v) {
  if (typeof v !== "string") return v;
  const l = (window.__lang || "en");
  const D = window.I18N_DATA;
  if (D && D[l] && D[l][v] != null) return D[l][v];   // string-as-key dictionary (i18n-data.js)
  if (I18N[l] && I18N[l][v] != null) return I18N[l][v]; // legacy chrome short-keys
  return v;                                            // passthrough: English literal / unknown
}

/* ---------- Navigation model ---------- */
const NAV = [
  { group: "g_overview", items: [{ key: "dashboard", icon: "dashboard" }] },
  { group: "g_students", items: [
    { key: "radar", icon: "radar" },
    { key: "progress", icon: "progress" },
  ] },
  { group: "g_pastoral", items: [
    { key: "behaviour", icon: "behaviour" },
    { key: "ilp", icon: "ilp", director: true },
    { key: "attendance", icon: "attendance" },
  ] },
  { group: "g_academic", items: [{ key: "coursework", icon: "coursework" }] },
  { group: "g_knowledge", items: [
    { key: "docs", icon: "docs" },
    { key: "compliance", icon: "compliance", director: true },
  ] },
  { group: "g_admin", items: [{ key: "staff", icon: "staff", director: true }] },
];

const SCREEN_TITLES = {
  dashboard: "Director Dashboard", radar: "At-Risk Radar", progress: "Progress Monitoring",
  behaviour: "Behaviour Pipeline", ilp: "ILP / SEN Plans", attendance: "Attendance",
  coursework: "IA / EE Submission Monitor", docs: "Document Hub", compliance: "Compliance Cockpit",
  staff: "Staff Directory & Settings", student: "Student Profile",
};

/* ---------- routing ---------- */
function parseHash() {
  const h = (location.hash || "#/dashboard").replace(/^#\//, "");
  const [key, arg] = h.split("/");
  return { key: key || "dashboard", arg };
}
function navigate(to) { location.hash = "#/" + to; }
window.navigate = navigate;

function useHash() {
  const [route, setRoute] = React.useState(parseHash());
  React.useEffect(() => {
    const fn = () => { setRoute(parseHash()); document.querySelector(".main")?.scrollTo(0, 0); };
    window.addEventListener("hashchange", fn);
    return () => window.removeEventListener("hashchange", fn);
  }, []);
  return route;
}

/* ---------- toasts ---------- */
const toastListeners = [];
window.toast = (msg, type) => toastListeners.forEach((fn) => fn(msg, type));
function ToastHost() {
  const [items, setItems] = React.useState([]);
  React.useEffect(() => {
    const fn = (msg, type) => {
      const id = Date.now() + Math.random();
      setItems((s) => [...s, { id, msg, type }]);
      setTimeout(() => setItems((s) => s.filter((t) => t.id !== id)), 3200);
    };
    toastListeners.push(fn);
    return () => { const i = toastListeners.indexOf(fn); if (i >= 0) toastListeners.splice(i, 1); };
  }, []);
  return (
    <div className="toast-host">
      {items.map((tt) => (
        <div key={tt.id} className={"toast " + (tt.type || "")}>
          <Icon name={tt.type === "warn" ? "alert" : "check"} size={15} />
          <span>{tt.msg}</span>
        </div>
      ))}
    </div>
  );
}

/* ---------- notifications ---------- */
const NOTIFS = [
  { icon: "flag", color: "var(--critical)", text: <React.Fragment><b>Dilnoza R.</b> {t("escalated to Red Report — week-2 review due Friday")}</React.Fragment>, time: "2h ago", to: "behaviour" },
  { icon: "coursework", color: "var(--watch)", text: <React.Fragment><b>Chemistry IA</b> {t("marked late · −15% penalty applied automatically")}</React.Fragment>, time: "3h ago", to: "coursework" },
  { icon: "compliance", color: "var(--critical)", text: <React.Fragment>{t("Safeguarding Policy review is now")} <b>{t("overdue")}</b></React.Fragment>, time: "1d ago", to: "compliance" },
  { icon: "coursework", color: "var(--watch)", text: <React.Fragment><b>Madina T.</b> {t("EE first draft is 6 days overdue")}</React.Fragment>, time: "1d ago", to: "coursework" },
  { icon: "ilp", color: "var(--info)", text: <React.Fragment><b>Sevara N.</b> {t("ILP review is due next week")}</React.Fragment>, time: "2d ago", to: "ilp" },
  { icon: "staff", color: "oklch(0.5 0.14 300)", text: <React.Fragment>{t("A new staff invite is")} <b>{t("pending")}</b></React.Fragment>, time: "2d ago", to: "staff" },
];

/* ---------- Sidebar ---------- */
function Sidebar({ active, role, lang, open, onNav }) {
  return (
    <aside className={"sidebar" + (open ? " open" : "")}>
      <div className="sb-brand">
        <div className="sb-crest"></div>
        <div className="sb-word">
          <div className="n serif">Al-Beruni</div>
          <div className="s mono">{t("ACADEMIC PORTAL")}</div>
        </div>
      </div>

      <nav className="sb-nav scroll-y">
        {NAV.map((grp) => {
          const items = grp.items.filter((it) => role === "director" || !it.director);
          if (!items.length) return null;
          return (
            <div className="sb-group" key={grp.group}>
              <div className="sb-glabel">{t(grp.group)}</div>
              {items.map((it) => (
                <button key={it.key} className={"sb-item" + (active === it.key ? " on" : "")} onClick={() => { navigate(it.key); onNav && onNav(); }}>
                  <Icon name={it.icon} size={17} />
                  <span>{t(it.key)}</span>
                  {it.key === "radar" ? <span className="sb-count mono">{window.DB.stats.critical + window.DB.stats.watch}</span> : null}
                  {it.key === "behaviour" ? <span className="sb-count mono">{window.DB.stats.openCases}</span> : null}
                </button>
              ))}
            </div>
          );
        })}
      </nav>

      <div className="sb-foot">
        <div className="sb-term">
          <span className="eyebrow">{t("Term")} 3 · 2025–26</span>
          <span className="mono faint" style={{ fontSize: 10 }}>{t("Week")} 8 {t("of")} 11</span>
        </div>
      </div>
    </aside>
  );
}

/* ---------- Topbar ---------- */
function Topbar({ route, role, setRole, lang, setLang, onCommand, onAssistant, onMenu }) {
  const title = route.key === "student" ? (window.DB.student(route.arg)?.name || t("Student")) : (SCREEN_TITLES[route.key] ? t(SCREEN_TITLES[route.key]) : "");
  const [langOpen, setLangOpen] = React.useState(false);
  const [roleOpen, setRoleOpen] = React.useState(false);
  const [notifOpen, setNotifOpen] = React.useState(false);
  const [readAll, setReadAll] = React.useState(false);
  const me = role === "director" ? window.DB.teacher("T-01") : window.DB.teacher("T-04");
  return (
    <header className="topbar">
      <button className="icon-btn tb-burger" onClick={onMenu} aria-label={t("Menu")}><Icon name="menu" size={20} /></button>
      <div className="tb-left">
        <div className="tb-title">
          <span className="eyebrow">{route.key === "student" ? t("Student 360°") : SCREEN_TITLES[route.key] && t(route.key)}</span>
          <h1>{title}</h1>
        </div>
      </div>

      <button className="tb-search" onClick={onCommand}>
        <Icon name="search" size={16} />
        <span>{t("search")}</span>
        <kbd className="mono">⌘K</kbd>
      </button>

      <div className="tb-right">
        <button className="btn btn-primary btn-sm" onClick={() => onAssistant()}>
          <Icon name="spark" size={14} />{t("ask")}
        </button>

        {/* role switch */}
        <div className="tb-menu">
          <button className="tb-chip" onClick={() => { setRoleOpen(!roleOpen); setLangOpen(false); }}>
            <Avatar name={me.name} color={me.avatar} size={24} />
            <span className="tb-role">{role === "director" ? t("director") : t("teacher")}</span>
            <Icon name="chevronD" size={13} />
          </button>
          {roleOpen ? (
            <div className="tb-pop" onMouseLeave={() => setRoleOpen(false)}>
              <div className="tb-pop-h">{t("View portal as")}</div>
              {[["director", t("director"), t("Full access · sign-off")], ["teacher", t("teacher"), t("Own subjects & homeroom only")]].map(([r, label, sub]) => (
                <button key={r} className={"tb-pop-item" + (role === r ? " on" : "")} onClick={() => { setRole(r); setRoleOpen(false); if (route.key === "ilp" || route.key === "compliance" || route.key === "staff") navigate("dashboard"); }}>
                  <div><div style={{ fontWeight: 500 }}>{label}</div><div className="muted" style={{ fontSize: 11 }}>{sub}</div></div>
                  {role === r ? <Icon name="check" size={15} /> : null}
                </button>
              ))}
            </div>
          ) : null}
        </div>

        <div className="vr" style={{ height: 22 }}></div>

        {/* language */}
        <div className="tb-menu">
          <button className="icon-btn" title={t("Language")} onClick={() => { setLangOpen(!langOpen); setRoleOpen(false); }}>
            <Icon name="globe" size={17} />
          </button>
          {langOpen ? (
            <div className="tb-pop sm" onMouseLeave={() => setLangOpen(false)}>
              {[["en", "English"], ["uz", "O‘zbek"], ["ru", "Русский"]].map(([code, label]) => (
                <button key={code} className={"tb-pop-item" + (lang === code ? " on" : "")} onClick={() => { setLang(code); setLangOpen(false); }}>
                  <span className="mono" style={{ width: 22, fontSize: 11, fontWeight: 600 }}>{code.toUpperCase()}</span>{label}
                  {lang === code ? <Icon name="check" size={15} style={{ marginLeft: "auto" }} /> : null}
                </button>
              ))}
            </div>
          ) : null}
        </div>

        <div className="tb-menu">
          <button className="icon-btn" title={t("Notifications")} style={{ position: "relative" }} onClick={() => { setNotifOpen(!notifOpen); setRoleOpen(false); setLangOpen(false); }}>
            <Icon name="bell" size={17} />
            {!readAll ? <span className="tb-bell-dot"></span> : null}
          </button>
          {notifOpen ? (
            <div className="tb-pop notif" onMouseLeave={() => setNotifOpen(false)}>
              <div className="notif-h between">
                <span style={{ fontWeight: 600, fontSize: 13 }}>{t("Notifications")} {!readAll ? <span className="badge crit" style={{ marginLeft: 4 }}>{NOTIFS.length}</span> : null}</span>
                <button className="btn btn-sm btn-ghost" onClick={() => setReadAll(true)}>{t("Mark all read")}</button>
              </div>
              <div className="notif-list scroll-y">
                {NOTIFS.map((n, i) => (
                  <button key={i} className="notif-item" onClick={() => { navigate(n.to); setNotifOpen(false); }}>
                    <span className="notif-ic" style={{ color: n.color, background: "color-mix(in oklab, " + n.color + " 13%, transparent)" }}><Icon name={n.icon} size={14} /></span>
                    <div style={{ flex: 1, minWidth: 0, textAlign: "left" }}>
                      <div style={{ fontSize: 12.5, lineHeight: 1.4 }}>{n.text}</div>
                      <div className="muted mono" style={{ fontSize: 10, marginTop: 3 }}>{n.time}</div>
                    </div>
                    {!readAll ? <span className="notif-dot"></span> : null}
                  </button>
                ))}
              </div>
            </div>
          ) : null}
        </div>
      </div>
    </header>
  );
}

/* ---------- Placeholder for unbuilt screens ---------- */
function Placeholder({ route }) {
  return (
    <div className="screen" style={{ display: "grid", placeItems: "center", minHeight: "60vh" }}>
      <div style={{ textAlign: "center", maxWidth: 360 }}>
        <div style={{ width: 52, height: 52, margin: "0 auto 16px", borderRadius: "var(--r-lg)", border: "1px solid var(--line-2)", display: "grid", placeItems: "center", color: "var(--muted)" }}>
          <Icon name="dots" size={22} />
        </div>
        <h2 style={{ fontSize: 18 }}>{SCREEN_TITLES[route.key] ? t(SCREEN_TITLES[route.key]) : t("Screen")}</h2>
        <p className="muted" style={{ marginTop: 8, fontSize: 13 }}>{t("This screen is part of the build and is coming next. Navigation, data and the shell are already live.")}</p>
      </div>
    </div>
  );
}

/* ============================================================
   App root
   ============================================================ */
function App() {
  const route = useHash();
  const [role, setRole] = React.useState(localStorage.getItem("ab_role") === "teacher" ? "teacher" : "director");
  const [lang, setLangState] = React.useState(localStorage.getItem("ab_lang") || "en");
  const [cmdOpen, setCmdOpen] = React.useState(false);
  const [assistant, setAssistant] = React.useState({ open: false, seed: null });
  const [navOpen, setNavOpen] = React.useState(false); // mobile drawer

  // close the mobile drawer whenever the route changes
  React.useEffect(() => { setNavOpen(false); }, [route.key, route.arg]);

  window.__lang = lang;
  const setLang = (l) => { window.__lang = l; setLangState(l); localStorage.setItem("ab_lang", l); };
  const setRoleP = (r) => { setRole(r); localStorage.setItem("ab_role", r); };

  // tweak bridge (palette/theme/density/role from Tweaks panel)
  React.useEffect(() => {
    window.__applyTweaks = (tw) => {
      const root = document.documentElement;
      if (tw.palette) root.setAttribute("data-palette", tw.palette);
      if (tw.theme) root.setAttribute("data-theme", tw.theme);
      if (tw.density) root.setAttribute("data-density", tw.density);
      if (tw.role && tw.role !== role) setRoleP(tw.role);
    };
  }, [role]);

  // keyboard: Cmd/Ctrl+K
  React.useEffect(() => {
    const fn = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setCmdOpen((o) => !o); }
      if (e.key === "Escape") { setCmdOpen(false); }
    };
    window.addEventListener("keydown", fn);
    return () => window.removeEventListener("keydown", fn);
  }, []);

  const ScreenComp = (window.SCREENS && window.SCREENS[route.key]) || Placeholder;

  return (
    <div className="app">
      <div className={"sb-scrim" + (navOpen ? " on" : "")} onClick={() => setNavOpen(false)}></div>
      <Sidebar active={route.key} role={role} lang={lang} open={navOpen} onNav={() => setNavOpen(false)} />
      <div className="app-main">
        <Topbar route={route} role={role} setRole={setRoleP} lang={lang} setLang={setLang}
          onCommand={() => setCmdOpen(true)} onAssistant={(seed) => setAssistant({ open: true, seed })}
          onMenu={() => setNavOpen((o) => !o)} />
        <main className="main scroll-y">
          <ScreenComp route={route} role={role} navigate={navigate}
            openAssistant={(seed) => setAssistant({ open: true, seed })} />
        </main>
      </div>

      {cmdOpen ? <CommandPalette role={role} onClose={() => setCmdOpen(false)}
        onAssistant={(seed) => { setCmdOpen(false); setAssistant({ open: true, seed }); }} /> : null}
      <AssistantPanel state={assistant} role={role} onClose={() => setAssistant({ open: false, seed: null })} />
      <ToastHost />
    </div>
  );
}

window.SCREENS = window.SCREENS || {};
Object.assign(window, { NAV, SCREEN_TITLES, t, parseHash, useHash, navigate });

window.__mountApp = function () {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
};
