import type { Metadata, Viewport } from "next";
import "./globals.css";
import { Inter, Source_Serif_4, Newsreader, Fraunces, JetBrains_Mono } from "next/font/google";
import { cn } from "@/lib/utils";
import "@/modules"; // registers all module manifests
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { asc, eq } from "drizzle-orm";
import { dashboards, users } from "@/modules/_core/schema";
import type { DashboardMeta } from "@/app/d/actions";
import { getQuickAdds } from "@/modules/_core";
import { QuickAddProvider } from "@/components/quick-add-provider";
import { QuickAddSheet } from "@/components/quick-add-sheet";
import { QuickAddCreateHost } from "@/components/quick-add/create-host";
import { CommandPalette } from "@/components/command-palette";
import { PwaRegister } from "@/components/pwa-register";
import { InstallPrompt } from "@/components/install-prompt";
import { AppShell } from "@/components/app-shell";
import { AppToaster } from "@/components/app-toaster";
import { AssistantBubble } from "@/modules/agent/components/assistant-bubble";
import { DEFAULT_ASSISTANT_NAME } from "@/lib/assistant-config";
import { isLlmConfigured } from "@/lib/llm";
import { DEFAULT_THEME, navStyleToDataNav } from "@/modules/_core/themes";
import type { Palette, ThemeMode, FontPair, Density, NavStyle } from "@/modules/_core/themes";

const inter = Inter({ subsets: ["latin"], variable: "--sans-inter", display: "swap" });
const sourceSerif = Source_Serif_4({
  subsets: ["latin"],
  variable: "--serif-source",
  display: "swap",
});
const newsreader = Newsreader({
  subsets: ["latin"],
  variable: "--serif-newsreader",
  display: "swap",
});
const fraunces = Fraunces({
  subsets: ["latin"],
  variable: "--serif-fraunces",
  display: "swap",
});
const jetbrains = JetBrains_Mono({
  subsets: ["latin"],
  variable: "--mono-jb",
  display: "swap",
});

export const viewport: Viewport = {
  themeColor: "#1F1B16",
  viewportFit: "cover",
};

export const metadata: Metadata = {
  title: "famapp",
  description: "Family coordination app",
  manifest: "/manifest.webmanifest",
  appleWebApp: {
    capable: true,
    statusBarStyle: "default",
    title: "famapp",
  },
  icons: {
    icon: [
      { url: "/favicon.svg", type: "image/svg+xml" },
      { url: "/icon-32.png", sizes: "32x32", type: "image/png" },
      { url: "/icon-16.png", sizes: "16x16", type: "image/png" },
    ],
    apple: "/icon-180.png",
  },
};

// Pre-paint: read user's theme prefs from localStorage and apply data-* + .dark.
// Falls back to clay/serif-sans/regular/sidebar/system if nothing is stored.
const prePaintScript = `(function(){
  try {
    var palette = localStorage.getItem('themePalette') || localStorage.getItem('theme') || 'clay';
    var mode = localStorage.getItem('themeMode') || 'system';
    var fontPair = localStorage.getItem('themeFontPair') || 'serif-sans';
    var density = localStorage.getItem('themeDensity') || 'regular';
    var navStyle = localStorage.getItem('themeNavStyle') || 'rail-desktop';
    var dataNav = navStyle === 'compact-rail' ? 'rail'
      : navStyle === 'top-nav' ? 'top'
      : 'sidebar';
    if (window.matchMedia && window.matchMedia('(max-width: 759px)').matches) {
      dataNav = navStyle === 'fab-only' ? 'fab' : 'bottom';
    }
    var dark = mode === 'dark' || (mode === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
    var html = document.documentElement;
    html.setAttribute('data-theme', palette);
    html.setAttribute('data-font-pair', fontPair);
    html.setAttribute('data-density', density);
    html.setAttribute('data-nav', dataNav);
    if (dark) html.classList.add('dark'); else html.classList.remove('dark');
  } catch(e) {}
})();`;

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  let palette: Palette = DEFAULT_THEME.palette;
  let mode: ThemeMode = DEFAULT_THEME.mode;
  let fontPair: FontPair = DEFAULT_THEME.fontPair;
  let density: Density = DEFAULT_THEME.density;
  let navStyle: NavStyle = DEFAULT_THEME.navStyle;
  let userDashboards: DashboardMeta[] = [];
  let signedIn = false;
  let assistantEnabled = false;
  let assistantName = DEFAULT_ASSISTANT_NAME;

  const session = await auth();
  if (session?.user?.id) {
    signedIn = true;
    const [row] = await db
      .select({
        themePalette: users.themePalette,
        themeMode: users.themeMode,
        themeFontPair: users.themeFontPair,
        themeDensity: users.themeDensity,
        themeNavStyle: users.themeNavStyle,
        assistantEnabled: users.assistantEnabled,
        assistantName: users.assistantName,
      })
      .from(users)
      .where(eq(users.id, session.user.id))
      .limit(1);
    if (row) {
      palette = row.themePalette as Palette;
      mode = row.themeMode as ThemeMode;
      fontPair = row.themeFontPair as FontPair;
      density = row.themeDensity as Density;
      navStyle = row.themeNavStyle as NavStyle;
      assistantEnabled = row.assistantEnabled;
      assistantName = row.assistantName?.trim() || DEFAULT_ASSISTANT_NAME;
    }
    userDashboards = await db
      .select({
        id: dashboards.id,
        name: dashboards.name,
        slug: dashboards.slug,
        isDefault: dashboards.isDefault,
        position: dashboards.position,
      })
      .from(dashboards)
      .where(eq(dashboards.userId, session.user.id))
      .orderBy(asc(dashboards.position), asc(dashboards.createdAt));
  }

  // Server-side initial dark guess: only for `dark` mode (system mode is corrected
  // before paint by the inline script). Avoids a flash on signed-in users.
  const isDark = mode === "dark";
  const initialDataNav = navStyleToDataNav(navStyle);

  const quickAdds = getQuickAdds();

  const fontVars = cn(
    inter.variable,
    sourceSerif.variable,
    newsreader.variable,
    fraunces.variable,
    jetbrains.variable,
  );

  return (
    <html
      lang="en"
      data-theme={palette}
      data-font-pair={fontPair}
      data-density={density}
      data-nav={initialDataNav}
      className={cn(fontVars, isDark ? "dark" : "")}
      suppressHydrationWarning
    >
      <head>
        <script dangerouslySetInnerHTML={{ __html: prePaintScript }} />
      </head>
      <body>
        <QuickAddProvider actions={quickAdds}>
          <AppShell signedIn={signedIn} navStyle={navStyle} dashboards={userDashboards}>
            {children}
          </AppShell>
          <QuickAddSheet />
          <QuickAddCreateHost />
          <CommandPalette />
          <InstallPrompt />
          <PwaRegister />
          {signedIn && assistantEnabled && session?.user?.id ? (
            <AssistantBubble
              configured={isLlmConfigured()}
              userId={session.user.id}
              assistantName={assistantName}
            />
          ) : null}
          <AppToaster position="bottom-right" />
        </QuickAddProvider>
      </body>
    </html>
  );
}
