import type { Metadata, Viewport } from "next";
import { Inter, Outfit } from "next/font/google";
import { cookies } from "next/headers";

import "./globals.css";

import { SiteChrome } from "@/components/layout/site-chrome";
import { MainShell } from "@/components/layout/main-shell";
import { SessionProvider } from "@/components/layout/session-provider";
import { HistoryTracker } from "@/components/layout/history-tracker";
import { getSession } from "@/lib/auth/session";
import { getUserSettings } from "@/db/queries/settings";
import { getCurrentTheme } from "@/lib/theme";
import { listDownloadDescriptors } from "@/services/providers/downloads";
import { listStreamingDescriptors } from "@/services/providers/registry";
import { siteConfig } from "@/config/site";

const inter = Inter({
  subsets: ["latin"],
  display: "swap",
  variable: "--font-flixtv-sans",
});

const outfit = Outfit({
  subsets: ["latin"],
  display: "swap",
  variable: "--font-flixtv-display",
  weight: ["600", "700", "800"],
});

export const metadata: Metadata = {
  metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000"),
  title: {
    default: `${siteConfig.name} — ${siteConfig.tagline}`,
    template: `%s | ${siteConfig.name}`,
  },
  description: siteConfig.description,
  applicationName: siteConfig.name,
  keywords: [...siteConfig.keywords],
  authors: [{ name: siteConfig.name }],
  creator: siteConfig.name,
  publisher: siteConfig.name,
  category: "entertainment",
  alternates: { canonical: "/" },
  openGraph: {
    type: "website",
    siteName: siteConfig.name,
    locale: siteConfig.locale,
    title: `${siteConfig.name} — ${siteConfig.tagline}`,
    description: siteConfig.description,
    url: "/",
  },
  twitter: {
    card: "summary_large_image",
    title: `${siteConfig.name} — ${siteConfig.tagline}`,
    description: siteConfig.description,
  },
  robots: {
    index: true,
    follow: true,
    googleBot: { index: true, follow: true, "max-image-preview": "large", "max-snippet": -1 },
  },
  formatDetection: { telephone: false },
};

export const viewport: Viewport = {
  themeColor: siteConfig.themeColor,
  width: "device-width",
  initialScale: 1,
  viewportFit: "cover",
  colorScheme: "dark light",
};

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const session = await getSession();
  const settings = session ? await getUserSettings(session.user.id) : null;
  const theme = await getCurrentTheme(settings?.theme);

  const providers = {
    streaming: {
      movie: listStreamingDescriptors("movie"),
      tv: listStreamingDescriptors("tv"),
      anime: listStreamingDescriptors("anime"),
    },
    download: {
      movie: listDownloadDescriptors("movie"),
      tv: listDownloadDescriptors("tv"),
      anime: listDownloadDescriptors("anime"),
    },
  };

  const store = await cookies();
  const prefersReduced =
    store.get("flixtv_reduce_motion")?.value === "1" || settings?.reduceMotion === true;

  return (
    <html
      lang="en"
      data-theme={theme}
      data-reduce-motion={prefersReduced ? "true" : undefined}
      // Required by Next 16 so route transitions can temporarily disable the
      // `scroll-behavior: smooth` set in globals.css.
      data-scroll-behavior="smooth"
      className={`${inter.variable} ${outfit.variable}`}
      suppressHydrationWarning
    >
      <body className="min-h-screen bg-bg font-sans text-ink antialiased">
        <a
          href="#main"
          className="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[2000] focus:rounded-pill focus:bg-white focus:px-4 focus:py-2 focus:text-sm focus:font-bold focus:text-black"
        >
          Skip to content
        </a>

        <SessionProvider
          initialUser={
            session
              ? {
                  id: session.user.id,
                  username: session.user.username,
                  email: session.user.email,
                  displayName: session.user.displayName,
                  avatarPath: session.user.avatarPath,
                  role: session.user.role,
                }
              : null
          }
          initialSettings={settings}
          initialProviders={providers}
          initialDefaults={{
            streamingProviderId: settings?.defaultStreamingProvider ?? null,
            downloadProviderId: settings?.defaultDownloadProvider ?? null,
          }}
        >
          <HistoryTracker />
          <SiteChrome />
          <MainShell>{children}</MainShell>
        </SessionProvider>
      </body>
    </html>
  );
}
