import type { Metadata } from "next";
import type { ReactNode } from "react";
import "./globals.css";
import { AppLanguagesLoader } from "@enode/core/languages/AppLanguagesLoader";
import { HtmlLangSync } from "@enode/core/locale/HtmlLangSync";
import { TagsLoader } from "@enode/core/tags/TagsLoader";
import { TextContentLoader } from "@enode/core/text-content/TextContentLoader";
import { UiTextContentLoader } from "@enode/core/ui-text-content/UiTextContentLoader";
import { UserAppSettingsLoader } from "@enode/core/user-app-settings/UserAppSettingsLoader";
import { MetricsLoader } from "@enode/core/metrics/MetricsLoader";
import { DisplayBasesLoader } from "@enode/core/display/DisplayBasesLoader";
import { MediaLoader } from "@enode/core/media/MediaLoader";
import { AuthGuard } from "@enode/core/auth-guard";
import { LogoutTransition } from "@enode/ui/logout-transition";
import { Toaster } from "@enode/ui/feedback/toaster";
import { SupportReportHost } from "@enode/ui/feedback/support-report-host";
import { ActionResolverInit } from "@enode/ui/auth/action-resolver-init";
import { ActionDialogHost } from "@enode/ui/auth/action-dialog-host";
import { ApiConfigInit } from "./ApiConfigInit";
import { PortalAnnouncements } from "./PortalAnnouncements";
import { ErrorEngineInit } from "./error-handling/ErrorEngineInit";

export const metadata: Metadata = {
  title: "Enode Portal",
  description: "Coach console for Enode velocity training.",
};

// Browser-first layout — deliberately NOT the tracking app's layout.
//
// The tracking app's layout is a Capacitor mobile shell: it detects iOS to add
// an `.ios` class, declares an `appleWebApp` home-screen mode, opts into
// `viewport-fit=cover` + safe-area insets, locks the zoom scale for a native
// feel, and pins the body to the viewport height for in-session inner-scroll.
//
// The portal is a normal responsive website. None of that applies, so we keep
// the shell minimal: standard metadata, the default (zoomable) viewport, and a
// `min-h-screen` body that grows with its content so the window scrolls
// naturally on PUBLIC routes (the `/` login/marketing page). The authenticated
// dashboard opts into inner-scroll inside AppShell (`h-dvh`), so it never
// scrolls the window — see docs/decisions/0004-portal-inner-scroll.md. "Mobile"
// is handled entirely with responsive CSS (Tailwind breakpoints), not a native
// shell. <ApiConfigInit /> injects the portal's @enode/core API config and must
// stay first so config is set before any request.
export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" className="antialiased">
      <body className="min-h-screen">
        <ApiConfigInit />
        {/* Error engine + redirect-resolution surfaces. The Portal handles the
            same auth redirects as the tracking app: 310 device-limit + 312
            invitations dialogs, 311 onboarding page, and the 401 → AuthGuard
            bounce. ErrorEngineInit is the slim (no-SSE) portal variant. */}
        <ErrorEngineInit />
        <ActionResolverInit />
        <AuthGuard />
        <LogoutTransition />
        <AppLanguagesLoader />
        {/* Corrects the statically-baked lang attribute once the active locale
            is known — a static export can't render it server-side. */}
        <HtmlLangSync />
        {/* Two independent, parallel preloads: System A (entity text by UUID)
            and System B (UI strings by content-hash key). They fail open
            separately. */}
        <TextContentLoader />
        <UiTextContentLoader />
        {/* Loads the signed-in admin's app settings — drives the metric/imperial
            unit system (via the setUnitSystem bridge) for the height/weight
            fields in user management. */}
        <UserAppSettingsLoader />
        {/* Metrics + display bases back the account Settings drawer's Focus
            metrics section (group/metric names + the focus-metrics editor).
            Without these the section silently gates to empty. */}
        <MetricsLoader />
        <DisplayBasesLoader />
        {/* Warms every Lottie media in two bulk requests
            (/media_states/icons + /media_states/animations) on each mount while
            signed in, so the exercise list / pickers / workout builder render
            their icons + animations from cache instead of firing a per-card
            /media_states?media=… round trip each (an N+1 over ~200 exercises on
            reload). preloadAfterAuth warms these once at login; this covers
            every subsequent reload — mirrors the tracking app's layout. */}
        <MediaLoader />
        {/* Tag catalogue for the user-management tag editor (entity_tags). */}
        <TagsLoader />
        {children}
        <Toaster />
        <SupportReportHost />
        <ActionDialogHost />
        {/* Backend announcements (maintenance, feature deprecations) — see
            docs/announcements.md. Not on the page a live session's QR code
            opens. */}
        <PortalAnnouncements />
      </body>
    </html>
  );
}
