// Vildez — main app
const { useState, useEffect } = React;

// URL routing: each screen has a Spanish slug (dashboard = root)
const ROUTES = [
  { id: "dashboard", slug: "" },
  { id: "fiscal",    slug: "fiscal" },
  { id: "alerts",    slug: "alerts" },
  { id: "users",     slug: "team" },
  { id: "settings",  slug: "settings" },
  { id: "profile",   slug: "profile" },
  { id: "docs",      slug: "docs" },
  { id: "drive",     slug: "storage" },
  { id: "tasks",     slug: "tasks" },
  { id: "automations", slug: "automations" },
  { id: "chat",      slug: "chat" },
  { id: "social",    slug: "social" },
  { id: "servers",   slug: "servers" },
];
const SLUG_BY_ID = Object.fromEntries(ROUTES.map(r => [r.id, r.slug]));
const ID_BY_SLUG = Object.fromEntries(ROUTES.map(r => [r.slug, r.id]));

// Stable empty array so screens that read pathParts don't see a new identity on every render.
const EMPTY_PATH_PARTS = Object.freeze([]);

function pathFor(active, subTab, pathParts) {
  const slug = SLUG_BY_ID[active] ?? "";
  const segs = [];
  if (slug) segs.push(slug);
  if (subTab) segs.push(subTab);
  if (pathParts && pathParts.length) {
    for (const p of pathParts) {
      if (p == null || p === "") continue;
      segs.push(encodeURIComponent(String(p)));
    }
  }
  return "/" + segs.join("/");
}

function parsePath(pathname) {
  const parts = (pathname || "/").replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
  if (parts.length === 0) return { id: "dashboard", subTab: undefined, pathParts: EMPTY_PATH_PARTS };
  const id = ID_BY_SLUG[parts[0]];
  if (!id) return { id: "dashboard", subTab: undefined, pathParts: EMPTY_PATH_PARTS };
  const rest = parts.slice(2).map(p => { try { return decodeURIComponent(p); } catch { return p; } });
  return { id, subTab: parts[1], pathParts: rest.length ? rest : EMPTY_PATH_PARTS };
}

function pathPartsEqual(a, b) {
  if (a === b) return true;
  if (!a || !b) return false;
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
  return true;
}

function App() {
  const defaults = window.__TWEAK_DEFAULTS || {};
  const [theme, setTheme] = useState(defaults.theme || "light");
  const [sidebarStyle, setSidebarStyle] = useState(defaults.sidebarStyle || "dual");
  const [lang, setLang] = useState(defaults.language || "en");
  const [authed, setAuthed] = useState(() => window.isAuthenticated());
  useEffect(() => {
    const onAuth = () => setAuthed(window.isAuthenticated());
    window.addEventListener("auth-changed", onAuth);
    return () => window.removeEventListener("auth-changed", onAuth);
  }, []);
  // Theme follows the user's preference even on the login screen.
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
  }, [theme]);
  const [collapsed, setCollapsed] = useState(() => {
    try { return localStorage.getItem("companyBrain.sidebar.collapsed") === "true"; }
    catch { return false; }
  });
  useEffect(() => {
    try { localStorage.setItem("companyBrain.sidebar.collapsed", collapsed ? "true" : "false"); }
    catch { /* ignore */ }
  }, [collapsed]);
  const [secondaryHidden, setSecondaryHidden] = useState(false);
  // Viewport-driven collapse: at narrow widths, force the sidebars to take less space.
  // The user's explicit toggle is preserved for when the window grows again.
  const [forcePrimaryCollapsed, setForcePrimaryCollapsed] = useState(() => window.innerWidth < 1024);
  const [forceSecondaryHidden, setForceSecondaryHidden] = useState(() => window.innerWidth < 768);
  useEffect(() => {
    const update = () => {
      setForcePrimaryCollapsed(window.innerWidth < 1024);
      setForceSecondaryHidden(window.innerWidth < 768);
    };
    window.addEventListener("resize", update);
    return () => window.removeEventListener("resize", update);
  }, []);
  const effectiveCollapsed = collapsed || forcePrimaryCollapsed;
  const effectiveSecondaryHidden = secondaryHidden || forceSecondaryHidden;
  const initialRoute = parsePath(window.location.pathname);
  const [active, setActiveState] = useState(initialRoute.id);
  const [showOnboarding, setShowOnboarding] = useState(false);
  // Per-screen sub-tab (defaults to first item of that screen's subnav)
  const [subTabs, setSubTabs] = useState(() => initialRoute.subTab ? { [initialRoute.id]: initialRoute.subTab } : {});
  // Per-screen path-parts (extra URL segments after the sub-tab). Lets a screen
  // encode in-page state — current folder, selected board/sprint, open page id —
  // so the browser back button restores it.
  const [pathPartsMap, setPathPartsMap] = useState(() =>
    initialRoute.pathParts.length ? { [initialRoute.id]: initialRoute.pathParts } : {}
  );
  // When set, the next URL change uses replaceState so we don't pollute the
  // back stack with auto-corrections (e.g. picking a default board on first load).
  const replaceNextRef = React.useRef(false);
  const explicitSubTab = subTabs[active];
  const subTab = explicitSubTab || (window.SUBNAVS?.[active]?.items?.find(i => i.active)?.id) || (window.SUBNAVS?.[active]?.items?.[0]?.id);
  const setSubTab = (id) => setSubTabs(s => ({ ...s, [active]: id }));
  const activePathParts = pathPartsMap[active] || EMPTY_PATH_PARTS;
  const setPathParts = React.useCallback((updater, opts) => {
    if (opts && opts.replace) replaceNextRef.current = true;
    setPathPartsMap(m => {
      const prev = m[active] || EMPTY_PATH_PARTS;
      const nextRaw = typeof updater === "function" ? updater(prev) : updater;
      const next = Array.isArray(nextRaw) ? nextRaw : EMPTY_PATH_PARTS;
      if (pathPartsEqual(prev, next)) return m;
      return { ...m, [active]: next };
    });
  }, [active]);
  // Leaving a module clears its stored subtab and path-parts so returning to it
  // shows the module's default state. Browser back/forward (popstate) re-applies
  // both from the URL right after, so deep links still work.
  const setActive = (id) => {
    if (id !== active) {
      setSubTabs(s => {
        const { [active]: _, ...rest } = s;
        return rest;
      });
      setPathPartsMap(m => {
        const { [active]: _, ...rest } = m;
        return rest;
      });
    }
    setActiveState(id);
  };

  // Push URL whenever active screen, explicit sub-tab, or path-parts change.
  // When path-parts are non-empty, force the effective sub-tab into the URL so
  // the segment order stays well-formed (`/module/sub/extra...`).
  useEffect(() => {
    const parts = activePathParts.filter(p => p != null && p !== "");
    const subTabForUrl = explicitSubTab || (parts.length ? subTab : undefined);
    const target = pathFor(active, subTabForUrl, parts);
    if (target !== window.location.pathname) {
      if (replaceNextRef.current) window.history.replaceState(null, "", target);
      else window.history.pushState(null, "", target);
    }
    replaceNextRef.current = false;
  }, [active, explicitSubTab, subTab, activePathParts]);

  // Sync state when user uses browser back/forward
  useEffect(() => {
    const onPop = () => {
      const r = parsePath(window.location.pathname);
      setActive(r.id);
      setSubTabs(s => ({ ...s, [r.id]: r.subTab }));
      setPathPartsMap(m => ({ ...m, [r.id]: r.pathParts }));
    };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  const t = window.useT(lang);

  // Show "Profile" via header avatar or via sidebar 'users' (we use a special trigger)
  const goProfile = () => setActive("profile");

  // Whether to render secondary sidebar based on style + screen + user toggle + viewport
  const hasSecondaryForScreen = sidebarStyle === "dual" && !!window.SUBNAVS[active];
  const showSecondary = hasSecondaryForScreen && !effectiveSecondaryHidden;

  const renderScreen = () => {
    switch (active) {
      case "dashboard": return <window.DashboardScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} setActive={setActive} />;
      case "fiscal": return <window.InvoicesScreen t={t} subTab={subTab} setSubTab={setSubTab} />;
      case "alerts": return <window.AlertsScreen t={t} subTab={subTab} setSubTab={setSubTab} />;
      case "users": return <window.TeamScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} />;
      case "settings": return <window.SettingsScreen t={t} lang={lang} setLang={setLang} theme={theme} setTheme={setTheme} subTab={subTab} setSubTab={setSubTab} />;
      case "profile": return <window.ProfileScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} />;
      case "drive": return <window.StorageScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} pathParts={activePathParts} setPathParts={setPathParts} />;
      case "tasks": return <window.TasksScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} pathParts={activePathParts} setPathParts={setPathParts} />;
      case "docs": return <window.DocsScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} pathParts={activePathParts} setPathParts={setPathParts} />;
      case "automations": return <window.AutomationsScreen t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} />;
      case "chat":
      case "social":
      case "servers":
        return <window.PlaceholderScreen moduleId={active} t={t} lang={lang} subTab={subTab} setSubTab={setSubTab} />;
      default: return <div className="page">Not found</div>;
    }
  };

  // ===== Tweaks panel =====
  const TweaksPanel = window.TweaksPanel;
  const TweakSection = window.TweakSection;
  const TweakRadio = window.TweakRadio;
  const TweakSelect = window.TweakSelect;
  const TweakButton = window.TweakButton;
  const useTweaks = window.useTweaks;

  const [tweaks, setTweak] = useTweaks ? useTweaks({
    theme: defaults.theme || "light",
    sidebarStyle: defaults.sidebarStyle || "dual",
    language: defaults.language || "en",
  }) : [{}, () => {}];

  // Sync tweaks → state
  useEffect(() => {
    if (tweaks.theme && tweaks.theme !== theme) setTheme(tweaks.theme);
    if (tweaks.sidebarStyle && tweaks.sidebarStyle !== sidebarStyle) setSidebarStyle(tweaks.sidebarStyle);
    if (tweaks.language && tweaks.language !== lang) setLang(tweaks.language);
  }, [tweaks]);

  // Sync state → tweaks (when user toggles via header)
  useEffect(() => { if (setTweak) setTweak('theme', theme); }, [theme]);
  useEffect(() => { if (setTweak) setTweak('language', lang); }, [lang]);

  // Alerts API is not yet wired — no badge until it lands.
  const unreadAlerts = 0;

  if (!authed) {
    return (
      <>
        <window.LoginScreen
          t={t}
          lang={lang}
          setLang={setLang}
          theme={theme}
          setTheme={setTheme}
        />
        <window.CookieConsent lang={lang} />
      </>
    );
  }

  return (
    <>
      <div
        className="app"
        data-sidebar-collapsed={effectiveCollapsed}
        data-secondary-hidden={!showSecondary}
      >
        <window.Sidebar
          active={active}
          setActive={setActive}
          collapsed={effectiveCollapsed}
          setCollapsed={setCollapsed}
          forced={forcePrimaryCollapsed}
          secondaryHidden={effectiveSecondaryHidden}
          setSecondaryHidden={setSecondaryHidden}
          hasSecondary={hasSecondaryForScreen}
          t={t}
          lang={lang}
        />
        {showSecondary && <window.SecondarySidebar screen={active} t={t} lang={lang} secondaryHidden={effectiveSecondaryHidden} setSecondaryHidden={setSecondaryHidden} subTab={subTab} setSubTab={setSubTab} />}
        {hasSecondaryForScreen && effectiveSecondaryHidden && !forceSecondaryHidden && (
          <button
            className="subnav-reopen"
            onClick={() => setSecondaryHidden(false)}
            title="Show subnav"
            aria-label="Show subnav"
          >
            <window.Icons.ChevronRight />
          </button>
        )}
        <window.Header
          screen={active}
          t={t}
          lang={lang}
          setLang={setLang}
          alertsCount={unreadAlerts}
          onProfile={goProfile}
          theme={theme}
          setTheme={setTheme}
          setActive={setActive}
        />
        <main className="main">
          <div key={active} className="screen-mount">
            {renderScreen()}
          </div>
        </main>
      </div>

      {showOnboarding && <window.OnboardingOverlay t={t} lang={lang} onClose={() => setShowOnboarding(false)} />}

      <window.CookieConsent lang={lang} />

      {TweaksPanel && (
        <TweaksPanel title="Tweaks">
          <TweakSection title="Appearance">
            <TweakRadio label="Theme" value={tweaks.theme} options={[{value: "light", label: "Light"}, {value: "dark", label: "Dark"}]} onChange={(v) => setTweak("theme", v)} />
          </TweakSection>
          <TweakSection title="Navigation">
            <TweakRadio label="Sidebar" value={tweaks.sidebarStyle} options={[{value: "dual", label: "Dual"}, {value: "single", label: "Single"}]} onChange={(v) => setTweak("sidebarStyle", v)} />
            <TweakButton label="Sidebar collapsed" onClick={() => setCollapsed(!collapsed)}>
              {collapsed ? "Expand" : "Collapse"}
            </TweakButton>
          </TweakSection>
          <TweakSection title="Language">
            <TweakRadio label="UI" value={tweaks.language} options={[{value: "en", label: "EN"}, {value: "es", label: "ES"}]} onChange={(v) => setTweak("language", v)} />
          </TweakSection>
          <TweakSection title="Demo">
            <TweakButton label="Onboarding" onClick={() => setShowOnboarding(true)}>Replay</TweakButton>
            <TweakButton label="Profile screen" onClick={() => setActive("profile")}>Open</TweakButton>
          </TweakSection>
        </TweaksPanel>
      )}
    </>
  );
}

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