/* ==================================================================
   App root — orchestrates screens + tweaks
   ------------------------------------------------------------------
   The cockpit is a single column: the pill top bar (brand + section
   pills + sub-nav) sits above a full-width content area. Section →
   screen mapping lives in shell.jsx's NAV_SECTIONS, which the top bar
   and this router both read, so adding a screen is one edit there plus
   a case below.
   ================================================================== */

const KTopbar = window.KXUI.CockpitTopbar;
const KRadialNav = window.KXUI.CockpitRadialNav;
const KIcon = window.KXUI.Icon;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#3b7bf6",
  "density": "comfortable",
  "language": "bn"
}/*EDITMODE-END*/;

// Landing screen. `?screen=` is how the installed app's home-screen shortcuts
// (manifest.webmanifest) open straight into Hostel / Staff Attendance / Finance
// instead of always dropping the user on the dashboard. Unknown values fall
// through to the dashboard rather than rendering an empty router default.
const KNOWN_SCREENS = new Set([
  "dashboard", "academics", "hostel", "hostel-report", "staff-attendance",
  "parents-overview", "kinetix-overview", "finance", "library", "kinetix",
  "evaluate", "report", "answer-key", "doubts", "ai-review", "notifications",
  "teachers", "students", "parents", "announcements", "personnel", "taxonomy",
  "chapters", "topics", "kinetix-access", "kinetix-activity", "admissions",
  "forms", "bus-tracking", "college-students",
]);
const initialScreen = () => {
  try {
    const want = new URLSearchParams(window.location.search).get("screen");
    if (want && KNOWN_SCREENS.has(want)) return want;
  } catch { /* no URL access — fall through */ }
  return "dashboard";
};

const App = () => {
  const [screen, setRawScreen] = useState(initialScreen);
  const [pickerOpen, setPickerOpen] = useState(false);
  const [evalTest, setEvalTest] = useState(null);
  const [authoringMeta, setAuthoringMeta] = useState(null);
  const [authoringInitial, setAuthoringInitial] = useState(null);
  const [pendingSaveHandler, setPendingSaveHandler] = useState(null);
  const [tweaks, setTweak] = (typeof useTweaks === "function") ? useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];

  // Intercept screen change: opening "evaluate" without a chosen test pops the picker first.
  // If the library/upload-sheets flow set window.KX.EVAL_CONTEXT first, honour it directly.
  const setScreen = (next) => {
    if (next === "evaluate") {
      const ctx = window.KX.EVAL_CONTEXT;
      if (ctx?.test) {
        setEvalTest(ctx.test);
        setRawScreen("evaluate");
        return;
      }
      if (!evalTest) { setPickerOpen(true); return; }
    }
    setRawScreen(next);
    // Landing on a new screen should start at the top of it — without this a
    // jump from the foot of a long list opens the next screen mid-page.
    window.scrollTo({ top: 0, behavior: "instant" });
  };

  useEffect(() => {
    document.documentElement.style.setProperty('--accent', tweaks.accent);
    const density = tweaks.density;
    document.body.style.fontSize = density === "compact" ? "12px" : density === "spacious" ? "14px" : "13px";
  }, [tweaks]);

  // Cross-component navigation hook. Used by the notifications panel (in
  // shell.jsx) to jump to the submissions view for a specific test without
  // threading setScreen through every component.
  useEffect(() => {
    window.KX = window.KX || {};
    window.KX.navigate = (target, opts = {}) => {
      if (target === "evaluate" && opts.testDisplayId) {
        const test = (window.KX.TESTS || []).find(t => t.id === opts.testDisplayId);
        if (test) {
          window.KX.EVAL_CONTEXT = { test };
          setEvalTest(test);
          setRawScreen("evaluate");
          return;
        }
        setPickerOpen(true);
        return;
      }
      if (target === "doubts" && opts.doubtId) {
        // Preselect a specific thread when arriving from a notification.
        window.KX.DOUBTS_CONTEXT = { doubtId: opts.doubtId, tab: opts.tab || "open" };
      }
      setScreen(target);
    };
    return () => { if (window.KX) delete window.KX.navigate; };
  }, [evalTest]);

  const Screen = () => {
    switch(screen) {
      /* ---- Cockpit overview screens ---- */
      case "dashboard":
        return typeof window.CockpitDashboard !== "undefined"
          ? <window.CockpitDashboard setScreen={setScreen}/>
          : <Placeholder name="Dashboard" desc="Module not loaded — check screen-cockpit-dashboard.jsx is included in index.html."/>;
      case "academics":
        return typeof window.CockpitAcademics !== "undefined"
          ? <window.CockpitAcademics setScreen={setScreen}/>
          : <Placeholder name="Academics" desc="Module not loaded — check screen-cockpit-academics.jsx is included in index.html."/>;
      case "hostel":
        return typeof window.CockpitHostel !== "undefined"
          ? <window.CockpitHostel setScreen={setScreen}/>
          : <Placeholder name="Hostel" desc="Module not loaded — check screen-cockpit-hostel.jsx is included in index.html."/>;
      case "hostel-report":
        return typeof window.CockpitHostelReport !== "undefined"
          ? <window.CockpitHostelReport setScreen={setScreen}/>
          : <Placeholder name="Hostel Reports" desc="Module not loaded — check screen-cockpit-hostel.jsx is included in index.html."/>;
      case "staff-attendance":
        return typeof window.CockpitStaffAttendance !== "undefined"
          ? <window.CockpitStaffAttendance setScreen={setScreen}/>
          : <Placeholder name="Staff Attendance" desc="Module not loaded — check screen-cockpit-staff-attendance.jsx is included in index.html."/>;
      case "parents-overview":
        return typeof window.CockpitParents !== "undefined"
          ? <window.CockpitParents setScreen={setScreen}/>
          : <Placeholder name="Parents" desc="Module not loaded — check screen-cockpit-parents.jsx is included in index.html."/>;
      case "kinetix-overview":
        return typeof window.CockpitKinetix !== "undefined"
          ? <window.CockpitKinetix setScreen={setScreen}/>
          : <Placeholder name="KinetiX Portal" desc="Module not loaded — check screen-cockpit-kinetix.jsx is included in index.html."/>;
      case "finance":
        return typeof window.CockpitFinance !== "undefined"
          ? <window.CockpitFinance setScreen={setScreen}/>
          : <Placeholder name="Finance" desc="Module not loaded — check screen-cockpit-finance.jsx is included in index.html."/>;

      /* ---- Existing deep screens ---- */
      case "library":   return <window.TestLibrary setScreen={setScreen}
        onOpenManual={(meta, saveHandler, initial) => { setAuthoringMeta(meta); setPendingSaveHandler(() => saveHandler); setAuthoringInitial(initial || null); setRawScreen("manual"); }}/>;
      case "manual":    return <window.ManualAuthoring meta={authoringMeta} initialSections={authoringInitial}
        onSave={async (t) => {
          if (pendingSaveHandler) await pendingSaveHandler(t);
          setAuthoringMeta(null); setAuthoringInitial(null); setRawScreen("library");
        }}
        onCancel={() => { setAuthoringMeta(null); setAuthoringInitial(null); setRawScreen("library"); }}/>;
      case "report":    return <window.ClassReports setScreen={setScreen}/>;
      case "evaluate":  return <window.PaperEvaluation initialTest={evalTest}
        onChangeTest={() => { setEvalTest(null); setPickerOpen(true); }}
        setScreen={setScreen}/>;
      case "answer-key":
        return typeof window.AnswerKeyAuthoring !== "undefined"
          ? <window.AnswerKeyAuthoring setScreen={setScreen}/>
          : <Placeholder name="Model Answer Keys" desc="Module not loaded — check screen-answer-key.jsx is included in index.html."/>;
      case "kinetix":
        return typeof window.KinetiXTests !== "undefined"
          ? <window.KinetiXTests setScreen={setScreen}/>
          : <Placeholder name="KinetiX Online Tests" desc="Module not loaded — check screen-kinetix.jsx is included in index.html."/>;
      case "teachers":
        return typeof window.TeachersScreen !== "undefined"
          ? <window.TeachersScreen/>
          : <Placeholder name="Teachers" desc="Module not loaded — check screen-admin.jsx is included in index.html."/>;
      case "taxonomy":
        return typeof window.TaxonomyScreen !== "undefined"
          ? <window.TaxonomyScreen/>
          : <Placeholder name="Classes & Subjects" desc="Module not loaded — check screen-admin-taxonomy.jsx is included in index.html."/>;
      case "chapters":
        return typeof window.ChaptersScreen !== "undefined"
          ? <window.ChaptersScreen/>
          : <Placeholder name="Chapters" desc="Module not loaded — check screen-admin-chapters.jsx is included in index.html."/>;
      case "topics":
        return typeof window.TopicsScreen !== "undefined"
          ? <window.TopicsScreen/>
          : <Placeholder name="Topics" desc="Module not loaded — check screen-admin-topics.jsx is included in index.html."/>;
      case "students":
        return typeof window.StudentsScreen !== "undefined"
          ? <window.StudentsScreen/>
          : <Placeholder name="Students" desc="Module not loaded — check screen-admin-students.jsx is included in index.html."/>;
      case "parents":
        return typeof window.AdminParentsScreen !== "undefined"
          ? <window.AdminParentsScreen/>
          : <Placeholder name="Parents" desc="Module not loaded — check screen-admin-parents.jsx is included in index.html."/>;
      case "announcements":
        return typeof window.AdminAnnouncementsScreen !== "undefined"
          ? <window.AdminAnnouncementsScreen/>
          : <Placeholder name="Announcements" desc="Module not loaded — check screen-admin-announcements.jsx is included in index.html."/>;
      case "kinetix-access":
        return typeof window.KinetixAccessScreen !== "undefined"
          ? <window.KinetixAccessScreen/>
          : <Placeholder name="KinetiX Access" desc="Module not loaded — check screen-admin-kinetix-access.jsx is included in index.html."/>;
      case "kinetix-activity":
        return typeof window.KinetixActivityScreen !== "undefined"
          ? <window.KinetixActivityScreen/>
          : <Placeholder name="KinetiX Activity" desc="Module not loaded — check screen-admin-kinetix-activity.jsx is included in index.html."/>;
      case "doubts":
        return typeof window.DoubtsScreen !== "undefined"
          ? <window.DoubtsScreen/>
          : <Placeholder name="Doubts" desc="Module not loaded — check screen-doubts.jsx is included in index.html."/>;
      case "ai-review":
        return typeof window.AiReviewScreen !== "undefined"
          ? <window.AiReviewScreen/>
          : <Placeholder name="AI Test Review" desc="Module not loaded — check screen-ai-review.jsx is included in index.html."/>;
      case "notifications":
        return typeof window.NotificationsScreen !== "undefined"
          ? <window.NotificationsScreen/>
          : <Placeholder name="Notifications" desc="Module not loaded — check screen-notifications.jsx is included in index.html."/>;
      case "bus-tracking":
        return typeof window.BusTrackingScreen !== "undefined"
          ? <window.BusTrackingScreen/>
          : <Placeholder name="Bus Tracking" desc="Module not loaded — check screen-bus-tracking.jsx is included in index.html."/>;
      case "admissions":
        return typeof window.AdmissionsScreen !== "undefined"
          ? <window.AdmissionsScreen/>
          : <Placeholder name="Admissions" desc="Module not loaded — check screen-admissions.jsx is included in index.html."/>;
      case "forms":
        return typeof window.FormsScreen !== "undefined"
          ? <window.FormsScreen/>
          : <Placeholder name="Forms Adarshabani" desc="Module not loaded — check screen-forms.jsx is included in index.html."/>;
      case "personnel":
        return typeof window.PersonnelScreen !== "undefined"
          ? <window.PersonnelScreen/>
          : <Placeholder name="Personnel" desc="Module not loaded — check screen-personnel.jsx is included in index.html."/>;
      case "college-students":
        return typeof window.CollegeStudentsScreen !== "undefined"
          ? <window.CollegeStudentsScreen/>
          : <Placeholder name="College Students" desc="Module not loaded — check screen-college-students.jsx is included in index.html."/>;
      default: return <Placeholder name={screen}/>;
    }
  };

  return (
    <>
      <div className="app">
        <KTopbar screen={screen} setScreen={setScreen}/>
        {typeof window.TestPickerModal !== "undefined" && (
          <window.TestPickerModal open={pickerOpen} onClose={()=>setPickerOpen(false)}
            onPick={(t) => { setEvalTest(t); setPickerOpen(false); setRawScreen("evaluate"); }}/>
        )}
        <div className="main">
          <div className="content"><Screen/></div>
        </div>
        {/* Hidden above 760px by CSS — see .cx-radialnav. */}
        <KRadialNav screen={screen} setScreen={setScreen}/>
      </div>

      {/* Lives outside the router: a "question reported" notification can fire
          from any screen, and the modal listens on a window event. */}
      {typeof window.KXUI?.EditQuestionModal !== "undefined" && <window.KXUI.EditQuestionModal/>}

      {typeof TweaksPanel !== "undefined" && (
        <TweaksPanel title="Tweaks">
          <TweakSection title="Visual">
            <TweakColor label="Accent" value={tweaks.accent}
              options={["#3b7bf6", "#2fbe5f", "#f5318d", "#6b5bd2", "#ff9f0a"]}
              onChange={v => setTweak("accent", v)}/>
            <TweakRadio label="Density" value={tweaks.density}
              options={[
                { label:"Compact", value:"compact" },
                { label:"Comfy", value:"comfortable" },
                { label:"Spacious", value:"spacious" },
              ]}
              onChange={v => setTweak("density", v)}/>
          </TweakSection>
          <TweakSection title="Navigate">
            <TweakSelect label="Jump to" value={screen}
              options={[
                { label:"Dashboard", value:"dashboard" },
                { label:"Academics", value:"academics" },
                { label:"Hostel", value:"hostel" },
                { label:"KinetiX", value:"kinetix-overview" },
                { label:"Parents", value:"parents-overview" },
                { label:"Finance", value:"finance" },
                { label:"Test Library", value:"library" },
              ]}
              onChange={setScreen}/>
          </TweakSection>
        </TweaksPanel>
      )}
    </>
  );
};

const Placeholder = ({ name, desc }) => (
  <div className="cx-page">
    <div className="cx-card">
      <div className="cx-empty">
        <div className="cx-empty-mark">
          <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.8">
            <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
          </svg>
        </div>
        <div><strong>{name}</strong><span>{desc || "Coming soon."}</span></div>
      </div>
    </div>
  </div>
);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <div className="cx-page">
    <div className="cx-card"><div className="cx-empty">Loading KinetiX cockpit…</div></div>
  </div>,
);

// Take down the inline boot screen from index.html. Called after the first
// real render — either the app or the login form — so the user never sees a
// blank page between "scripts finished" and "something is on screen".
//
// The rAF matters: root.render() only SCHEDULES work, so removing the overlay
// on the same tick reveals an empty #root for a frame. Waiting one frame lets
// React commit first. The timeout is a backstop — if bootstrap throws in a way
// that never reaches a render, the boot screen must still come down rather
// than trapping the user behind it forever.
let bootDismissed = false;
function dismissBoot() {
  if (bootDismissed) return;
  bootDismissed = true;
  const el = document.getElementById("cx-boot");
  if (!el) return;
  requestAnimationFrame(() => {
    el.classList.add("gone");
    setTimeout(() => el.remove(), 320);
  });
}
setTimeout(dismissBoot, 15000);

async function renderRoot() {
  try { await window.bootstrapKX(); }
  catch (e) { console.error("[bootstrap] failed:", e); }
  if (window.KX.NEEDS_LOGIN) {
    root.render(<window.CockpitLogin onLoggedIn={renderRoot}/>);
  } else {
    root.render(<App/>);
  }
  dismissBoot();
}

renderRoot();
