/* global React, ReactDOM, TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor, TweakToggle, TweakSelect */
const { useState, useEffect, useRef, useMemo } = React;

// ============ DESIGN TOKENS ============
const FONT_PAIRINGS = {
  brut: {
    display: "'Bricolage Grotesque', 'Archivo', sans-serif",
    body: "'DM Sans', sans-serif",
    mono: "'Space Mono', monospace",
    pixel: "'VT323', 'Space Mono', monospace",
    label: "Bricolage + DM Sans",
  },
  archivo: {
    display: "'Archivo', sans-serif",
    body: "'DM Sans', sans-serif",
    mono: "'Space Mono', monospace",
    pixel: "'VT323', 'Space Mono', monospace",
    label: "Archivo + DM Sans",
  },
  playful: {
    display: "'Plus Jakarta Sans', sans-serif",
    body: "'Plus Jakarta Sans', sans-serif",
    mono: "'JetBrains Mono', monospace",
    pixel: "'JetBrains Mono', monospace",
    label: "Jakarta Sans + JetBrains Mono",
  },
};

const TONES = {
  ink:    "#0a0a0a",
  cream:  "#fff8ec",
  paper:  "#f0e9d6",
  blue:   "#2540ff",
  pink:   "#ff3d8a",
  yellow: "#ffe14a",
  lime:   "#c4f04b",
  orange: "#ff5a1f",
  acid:   "#eaff4a",
};

const BRANDINGS = {
  brut: {
    label: "Brutalist",
    description: "Hipster brutalist — zware borders, offset shadows, riso-paper feel",
    fontPairing: "brut",
    accent: "#2540ff",
    tones: {
      paper: "#f0e9d6",
      cream: "#fff8ec",
      selection: "#2540ff",
    },
    borderWidth: 2,
    shadowOffset: 6,
    radius: 0,
    textTransform: "lowercase",
    fontWeight: 800,
    letterSpacing: "-0.04em",
  },
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2540ff",
  "dark": false,
  "fontPairing": "brut",
  "playful": true,
  "branding": "brut",
  "dashboardVariant": "magazine",
  "screen": "dashboard"
}/*EDITMODE-END*/;

const BRANDING_STORAGE_KEY = "kwisthet:branding";

// Portal-mode: als de hostname start met "portal." (bv. portal.kwisthet.be),
// draaien we in enterprise-portal-modus. Dit is hetzelfde backend, maar:
// - de landing wordt overgeslagen (direct login)
// - login-scherm krijgt een "Organisatie portal"-titel
// - na login springen we naar /training (learner) of /org (org_admin)
//   in plaats van het reguliere dashboard
const IS_PORTAL = (() => {
  try { return window.location.hostname.startsWith("portal."); }
  catch { return false; }
})();

function readStoredBranding() {
  try {
    const v = localStorage.getItem(BRANDING_STORAGE_KEY);
    return v && BRANDINGS[v] ? v : null;
  } catch { return null; }
}

function App() {
  const [tweaks, setTweakRaw] = useTweaks({
    ...TWEAK_DEFAULTS,
    branding: readStoredBranding() || TWEAK_DEFAULTS.branding,
  });
  const setTweak = React.useCallback((keyOrEdits, val) => {
    const edits = typeof keyOrEdits === "object" && keyOrEdits !== null ? keyOrEdits : { [keyOrEdits]: val };
    if ("branding" in edits) {
      try { localStorage.setItem(BRANDING_STORAGE_KEY, edits.branding); } catch {}
    }
    setTweakRaw(edits);
  }, [setTweakRaw]);
  const brand = BRANDINGS[tweaks.branding] || BRANDINGS.brut;
  const fonts = FONT_PAIRINGS[brand.fontPairing] || FONT_PAIRINGS.brut;
  const dark = tweaks.dark;

  const paperColor = brand.tones.paper;
  const creamColor = brand.tones.cream;
  const bg     = dark ? "#101012" : paperColor;
  const bg2    = dark ? "#1a1a1d" : (tweaks.branding === "playful" ? "#e8e6e1" : "#ece5d0");
  const fg     = dark ? TONES.cream : TONES.ink;
  const fgDim  = dark ? "#9a958c" : "#525252";
  const card   = dark ? "#181818" : creamColor;
  const rule   = dark ? "#2a2a30" : (tweaks.branding === "playful" ? "#d0cec9" : TONES.ink);
  const accent = tweaks.accent || brand.accent;
  const signal = TONES.pink;
  const cream  = creamColor;
  const tones  = TONES;

  const [siteText, setSiteText] = useState({});
  const [features, setFeatures] = useState({});
  const [joinCode, setJoinCode] = useState(() => {
    try {
      const url = new URL(window.location.href);
      return url.searchParams.get("code") || "";
    } catch { return ""; }
  });

  const theme = { bg, bg2, fg, fgDim, card, rule, accent, signal, cream, tones, fonts, dark, playful: tweaks.playful, branding: tweaks.branding, brand, siteText, features };

  // URL-driven routing: /admin, /join, /wizard etc. map to screens.
  // Also supports legacy ?join and ?code=KW-... query params.
  const PATH_TO_SCREEN = {
    "/": null, "/landing": "landing", "/hoe-werkt-het": "howitworks", "/pricing": "pricing", "/login": "login", "/admin": "admin", "/join": "join",
    "/wizard": "wizard", "/editor": "editor", "/lobby": "lobby", "/projector": "projector",
    "/quick-party": "quick-party", "/faq": "faq",
    "/library": "library", "/stats": "stats", "/trending": "trending", "/team": "team", "/settings": "settings",
    "/org": "org-admin", "/training": "training", "/reports": "reports",
  };
  const initialScreen = (() => {
    try {
      const url = new URL(window.location.href);
      if (url.pathname === "/projector") return "projector";
      if (url.searchParams.has("join") || url.searchParams.has("code")) return "join";
      const pathScreen = PATH_TO_SCREEN[url.pathname];
      if (pathScreen) return pathScreen;
    } catch {}
    const api = window.kwistApi;
    // Portal-mode: zonder token → direct naar login (geen marketing-landing).
    if (IS_PORTAL && !api?.getToken()) return "login";
    if (!api?.getToken()) return "landing";
    return tweaks.screen || "dashboard";
  })();
  const [screen, setScreen] = useState(initialScreen);
  const [user, setUser] = useState({ name: "", handle: "", initials: "??", isAdmin: false });
  const [activeQuiz, setActiveQuiz] = useState(null);
  const [editorQuizId, setEditorQuizId] = useState(null);
  const [signupMode, setSignupMode] = useState(false);

  const forceLogin = () => {
    window.kwistApi?.setToken(null);
    setUser({ name: "", handle: "", initials: "??", isAdmin: false });
    setScreen("landing");
    setTweak("screen", "landing");
    if (window.location.pathname !== "/landing") {
      window.history.pushState(null, "", "/landing");
    }
  };

  // Bootstrap: pull site-texts and (if a token is present) the current user.
  useEffect(() => {
    const api = window.kwistApi;
    if (!api) return;
    api.siteSettings().then((r) => setSiteText(r.settings || {})).catch(() => {});
    api.features().then((r) => setFeatures(r.features || {})).catch(() => {});
    if (api.getToken()) {
      api.me().then((r) => {
        if (r?.user) {
          const u = r.user;
          setUser({
            ...u,
            initials: (u.name || "").split(" ").map((s) => s[0]).slice(0, 2).join("").toUpperCase() || "??",
          });
          // Portal-mode bootstrap: hou de gebruiker in org-flow.
          if (IS_PORTAL && u.organizationId) {
            const isOrgPath = ["/org", "/training", "/reports"].includes(window.location.pathname);
            if (!isOrgPath) {
              if (u.orgRole === "org_admin") setScreen("org-admin");
              else if (u.orgRole === "trainer") setScreen("reports");
              else setScreen("training");
            }
          } else if (u.isAdmin && !tweaks.screen) setScreen("admin");
          else if (screen === "login") setScreen("dashboard");
        } else {
          forceLogin();
        }
      }).catch(() => forceLogin());
    }
    const onPopState = () => {
      const p = PATH_TO_SCREEN[window.location.pathname];
      if (p) setScreen(p);
      else if (window.location.pathname === "/") setScreen("dashboard");
    };
    window.addEventListener("kwist:unauthorized", forceLogin);
    window.addEventListener("popstate", onPopState);
    return () => {
      window.removeEventListener("kwist:unauthorized", forceLogin);
      window.removeEventListener("popstate", onPopState);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (screen === "library" && features["nav.library"] === false) setScreen("dashboard");
  }, [screen, features]);

  const SCREEN_TO_PATH = {
    dashboard: "/", landing: "/landing", howitworks: "/hoe-werkt-het", pricing: "/pricing", login: "/login", admin: "/admin", join: "/join",
    wizard: "/wizard", editor: "/editor", lobby: "/lobby",
    "quick-party": "/quick-party", faq: "/faq",
    library: "/library", stats: "/stats", trending: "/trending", team: "/team", settings: "/settings",
    "org-admin": "/org", training: "/training", reports: "/reports",
  };
  const goto = (s, payload) => {
    if (payload) setActiveQuiz(payload);
    setScreen(s);
    setTweak("screen", s);
    const p = SCREEN_TO_PATH[s];
    if (p && window.location.pathname !== p) {
      window.history.pushState(null, "", p);
    }
  };

  const logout = () => {
    forceLogin();
  };

  useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty("--bg", bg);
    root.style.setProperty("--bg2", bg2);
    root.style.setProperty("--fg", fg);
    root.style.setProperty("--fg-dim", fgDim);
    root.style.setProperty("--card", card);
    root.style.setProperty("--rule", rule);
    root.style.setProperty("--accent", accent);
    root.style.setProperty("--signal", signal);
    root.style.setProperty("--font-display", fonts.display);
    root.style.setProperty("--font-body", fonts.body);
    root.style.setProperty("--font-mono", fonts.mono);
    root.style.setProperty("--radius", brand.radius + "px");
    root.style.setProperty("--shadow-offset", brand.shadowOffset + "px");
    root.style.setProperty("--border-width", brand.borderWidth + "px");
    document.body.style.background = bg;
    document.body.style.color = fg;
    document.body.style.fontFamily = fonts.body;
    document.body.setAttribute("data-branding", tweaks.branding || "brut");

    let styleEl = document.getElementById("branding-overrides");
    if (!styleEl) {
      styleEl = document.createElement("style");
      styleEl.id = "branding-overrides";
      document.head.appendChild(styleEl);
    }
    styleEl.textContent = `::selection { background: ${brand.tones.selection}; color: #fff; }`;
  }, [bg, bg2, fg, fgDim, card, rule, accent, fonts, brand]);

  return (
    <div style={{ fontFamily: fonts.body, color: fg, background: bg, minHeight: "100vh" }}>
      {screen === "landing" && (
        <LandingScreen theme={theme}
          onLogin={() => goto("login")}
          onSignup={() => { setSignupMode(true); goto("login"); }}
          onJoin={() => goto("join")}
          onHowItWorks={() => goto("howitworks")}
          onPricing={() => goto("pricing")}
        />
      )}
      {screen === "howitworks" && (
        <HowItWorksScreen theme={theme}
          onLogin={() => goto("login")}
          onSignup={() => { setSignupMode(true); goto("login"); }}
          onJoin={() => goto("join")}
          onPricing={() => goto("pricing")}
          onLanding={() => goto("landing")}
        />
      )}
      {screen === "pricing" && (
        <PricingScreen theme={theme}
          onLogin={() => goto("login")}
          onSignup={() => { setSignupMode(true); goto("login"); }}
          onJoin={() => goto("join")}
          onHowItWorks={() => goto("howitworks")}
          onLanding={() => goto("landing")}
        />
      )}
      {screen === "login" && (
        <LoginScreen theme={theme} portal={IS_PORTAL} initialMode={signupMode ? "signup" : "login"} onLogin={(u) => {
          setSignupMode(false);
          setUser(u);
          // Portal-mode: stuur learners naar /training, trainers/org_admins
          // naar /reports of /org. Platform-admin behoudt z'n /admin.
          if (IS_PORTAL && u.organizationId) {
            if (u.orgRole === "org_admin") goto("org-admin");
            else if (u.orgRole === "trainer") goto("reports");
            else goto("training");
            return;
          }
          goto(u.isAdmin ? "admin" : "dashboard");
        }} />
      )}
      {screen === "dashboard" && (
        <DashboardScreen
          theme={theme}
          variant={tweaks.dashboardVariant}
          user={user}
          onCreate={() => goto("wizard")}
          onCustom={() => { setEditorQuizId(null); goto("editor"); }}
          onQuickParty={() => goto("quick-party")}
          onEdit={(quizId) => { setEditorQuizId(quizId); goto("editor"); }}
          onPlay={(q) => goto("lobby", q)}
          onLogout={logout}
          onNav={(id) => goto(id)}
          onAdmin={user.isAdmin ? () => goto("admin") : null}
        />
      )}
      {screen === "wizard" && (
        <WizardScreen theme={theme} onClose={() => goto("dashboard")} onLaunch={(q) => goto("lobby", q)} />
      )}
      {screen === "editor" && (
        <QuizEditorScreen
          theme={theme}
          mode={editorQuizId ? "edit" : "create"}
          quizId={editorQuizId}
          onClose={() => { setEditorQuizId(null); goto("dashboard"); }}
          onLaunch={(q) => { setEditorQuizId(null); goto("lobby", q); }}
        />
      )}
      {screen === "lobby" && (
        <LobbyScreen theme={theme} user={user} quiz={activeQuiz || DEFAULT_QUIZ} onClose={() => goto("dashboard")} />
      )}
      {screen === "quick-party" && (
        <QuickPartyScreen theme={theme} user={user}
          onClose={() => goto("dashboard")}
          onLaunch={(q) => goto("lobby", q)}
          onNav={(id) => goto(id)}
          onLogout={logout}
          onAdmin={user.isAdmin ? () => goto("admin") : null}
        />
      )}
      {screen === "faq" && (
        <FAQScreen theme={theme} onBack={() => goto("dashboard")} />
      )}
      {screen === "join" && (
        <JoinScreen theme={theme} initialCode={joinCode} />
      )}
      {screen === "projector" && (
        <ProjectorScreen theme={theme} code={joinCode} />
      )}
      {screen === "library" && features["nav.library"] !== false && (
        <LibraryScreen theme={theme} user={user} onLogout={logout}
          onNav={(id) => goto(id)} onAdmin={user.isAdmin ? () => goto("admin") : null}
          onCreate={() => goto("wizard")} onPlay={(q) => goto("lobby", q)} />
      )}
      {screen === "stats" && (
        <StatsScreen theme={theme} user={user} onLogout={logout}
          onNav={(id) => goto(id)} onAdmin={user.isAdmin ? () => goto("admin") : null} />
      )}
      {screen === "trending" && (
        <TrendingScreen theme={theme} user={user} onLogout={logout}
          onNav={(id) => goto(id)} onAdmin={user.isAdmin ? () => goto("admin") : null} />
      )}
      {screen === "team" && (
        <TeamScreen theme={theme} user={user} onLogout={logout}
          onNav={(id) => goto(id)} onAdmin={user.isAdmin ? () => goto("admin") : null} />
      )}
      {screen === "settings" && (
        <SettingsScreen theme={theme} user={user}
          onClose={() => goto("dashboard")}
          onLogout={logout}
          onNav={(id) => goto(id)}
          onAdmin={user.isAdmin ? () => goto("admin") : null}
          onUserUpdate={(u) => setUser({ ...user, ...u })}
        />
      )}
      {screen === "org-admin" && (
        <OrgAdminScreen theme={theme} user={user} onBack={() => goto("dashboard")} />
      )}
      {screen === "training" && (
        <TrainingScreen theme={theme} user={user} onBack={() => goto("dashboard")} />
      )}
      {screen === "reports" && (
        <ReportsScreen theme={theme} user={user} onBack={() => goto("dashboard")} />
      )}
      {screen === "admin" && (
        <AdminScreen
          theme={theme}
          user={user}
          onClose={() => goto("dashboard")}
          onLogout={logout}
          onSiteTextChange={(s) => setSiteText(s)}
          onBrandingChange={(b) => {
            const br = BRANDINGS[b];
            setTweak("branding", b);
            if (br) setTweak("accent", br.accent);
          }}
        />
      )}

      <DialogHost theme={theme} />

      <TweaksPanel title="Tweaks">
        <TweakSection title="Scherm">
          <TweakSelect
            label="Huidig"
            value={screen}
            options={[
              { value: "login", label: "Login / Sign-up" },
              { value: "dashboard", label: "Dashboard" },
              { value: "library", label: "Bibliotheek" },
              { value: "stats", label: "Resultaten" },
              { value: "trending", label: "Trending" },
              { value: "team", label: "Team" },
              { value: "wizard", label: "AI Quiz Wizard" },
              { value: "editor", label: "Custom Quiz Editor" },
              { value: "lobby", label: "Quiz Lobby" },
              { value: "join", label: "Speler join" },
              { value: "settings", label: "Instellingen" },
              { value: "admin", label: "Admin portal" },
              { value: "org-admin", label: "Organisatie" },
              { value: "training", label: "Leertraject" },
              { value: "reports", label: "Rapporten" },
            ]}
            onChange={(v) => goto(v)}
          />
        </TweakSection>

        <TweakSection title="Dashboard">
          <TweakRadio
            label="Layout"
            value={tweaks.dashboardVariant}
            options={[
              { value: "magazine", label: "Magazine" },
              { value: "index", label: "Index" },
              { value: "shelf", label: "Shelf" },
            ]}
            onChange={(v) => setTweak("dashboardVariant", v)}
          />
        </TweakSection>

        <TweakSection title="Look & feel">
          <TweakSelect
            label="Branding"
            value={tweaks.branding}
            options={[
              { value: "brut", label: "Brutalist" },
              { value: "playful", label: "Playful (v8)" },
            ]}
            onChange={(v) => {
              const b = BRANDINGS[v];
              setTweak("branding", v);
              if (b) setTweak("accent", b.accent);
            }}
          />
          <TweakColor label="Accent" value={tweaks.accent} onChange={(v) => setTweak("accent", v)} presets={["#2540ff", "#4f3dff", "#ff3d8a", "#ff5a1f", "#c4f04b", "#a855f7", "#0a0a0a"]} />
          <TweakToggle label="Dark mode" value={tweaks.dark} onChange={(v) => setTweak("dark", v)} />
          <TweakToggle label="Speelse modus" value={tweaks.playful} onChange={(v) => setTweak("playful", v)} />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

const DEFAULT_QUIZ = {
  id: "q1", title: "Vrijdagavond pubquiz", category: "Algemeen",
  questions: 24, plays: 12, type: "party", color: "#0a0a0a", emoji: "♣"
};

window.App = App;
window.BRANDINGS = BRANDINGS;
window.FONT_PAIRINGS = FONT_PAIRINGS;
