import localFont from "next/font/local"

import "./globals.css"
import { NotificationStream } from "@/components/notification-stream"
import { ThemeProvider } from "@/components/theme-provider"
import { TooltipProvider } from "@/components/ui/tooltip"
import { currentUser } from "@/lib/services/session"
import { cn } from "@/lib/utils"

/**
 * Prompt, loaded from `app/fonts`. Nothing is fetched from a font
 * service. `next/font/google` self-hosts at runtime but still reaches Google at
 * build time, and this application is delivered onto a LAN with no internet.
 *
 * One family carries both scripts. Prompt covers Thai and Latin, so an English
 * screen and its Thai translation are set in the same typeface instead of
 * looking like two different products.
 *
 * Three weights, upright only: 490 KB in total. The family ships eighteen
 * faces; italics and the extremes are not used by this interface and would be
 * shipped for nothing. Add a weight here when a screen genuinely needs it.
 *
 * TTF rather than WOFF2 because no converter is installed. Converting would cut
 * roughly half the bytes and is worth doing before go-live.
 */
const prompt = localFont({
  src: [
    {
      path: "./fonts/Prompt/Prompt-Regular.ttf",
      weight: "400",
      style: "normal",
    },
    {
      path: "./fonts/Prompt/Prompt-Medium.ttf",
      weight: "500",
      style: "normal",
    },
    {
      path: "./fonts/Prompt/Prompt-SemiBold.ttf",
      weight: "600",
      style: "normal",
    },
  ],
  variable: "--font-sans",
  display: "swap",
})

/**
 * `lang` is the reader's, not a constant.
 *
 * It was `en` on every page, which told a screen reader that 190 of the 193
 * people's screens were English. A Thai sentence announced as English is read
 * with the wrong voice and the wrong pronunciation rules, which is worse than
 * no declaration at all.
 *
 * The lookup is free: `currentUser` is memoised for the length of a request, so
 * this shares the one the page below already does.
 *
 * `th` for a stranger, because that is what 190 of 193 read and the login
 * screen is the one place somebody arrives without having told us anything.
 *
 * What this does not fix: `/login` and `/login/help` are deliberately bilingual,
 * and a page holding two languages needs `lang` on the elements rather than on
 * the document. Declaring either one at the top is wrong for half of it. That
 * is a smaller, separate piece of work on two static pages.
 */
export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  const user = await currentUser()

  return (
    <html
      lang={user?.language ?? "th"}
      suppressHydrationWarning
      className={cn("antialiased", "font-sans", prompt.variable)}
    >
      <body>
        <ThemeProvider>
          <TooltipProvider>{children}</TooltipProvider>
        </ThemeProvider>
        {/*
          Here rather than in the shell, and only for somebody signed in. A
          layout survives navigation, so a tab holds one connection for as long
          as it is open instead of opening a fresh one on every click. The
          login screen has nothing to be told about.
        */}
        {user ? <NotificationStream /> : null}
      </body>
    </html>
  )
}
