import type { Metadata } from "next";
import { Cormorant_Garamond, Inter } from "next/font/google";
import { cookies } from "next/headers";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { Header, type HeaderUser } from "@/components/layout/Header";
import { Footer } from "@/components/layout/Footer";
import { AgeGate } from "@/components/layout/AgeGate";
import { ThemeProvider } from "@/components/layout/ThemeProvider";
import type { NavItemWithChildren } from "@/components/layout/NavLink";
import "@/styles/globals.css";

function filterByVisibility<T extends { visibility: string }>(
  items: T[],
  isLoggedIn: boolean,
): T[] {
  return items.filter((item) => {
    if (item.visibility === "logged_in") return isLoggedIn;
    if (item.visibility === "logged_out") return !isLoggedIn;
    return true;
  });
}

const cormorantGaramond = Cormorant_Garamond({
  variable: "--font-heading",
  subsets: ["latin"],
  weight: ["400", "500", "600", "700"],
});

const inter = Inter({
  variable: "--font-body",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Cellar Labels",
  description:
    "The community label library and print sheet builder for pipe tobacco enthusiasts.",
};

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const cookieStore = await cookies();
  const ageVerified = cookieStore.get("age_verified")?.value === "true";

  const session = await auth();
  const userId = (session?.user as { id?: string } | undefined)?.id;
  let currentUser: HeaderUser | null = null;
  if (userId) {
    const [user, unreadCount] = await Promise.all([
      db.user.findUnique({
        where: { id: userId },
        select: { username: true, avatarUrl: true },
      }),
      db.notification.count({ where: { userId, isRead: false } }),
    ]);
    if (user) currentUser = { ...user, unreadCount };
  }
  const isLoggedIn = currentUser !== null;

  const [rawHeaderItems, rawFooterItems] = await Promise.all([
    db.navItem.findMany({
      where: { menu: "header", parentId: null },
      orderBy: { order: "asc" },
      include: { children: { orderBy: { order: "asc" } } },
    }),
    db.navItem.findMany({
      where: { menu: "footer", parentId: null },
      orderBy: { order: "asc" },
      include: { children: { orderBy: { order: "asc" } } },
    }),
  ]);

  const headerItems: NavItemWithChildren[] = filterByVisibility(
    rawHeaderItems,
    isLoggedIn,
  ).map((item) => ({
    ...item,
    children: filterByVisibility(item.children, isLoggedIn),
  }));
  const footerItems: NavItemWithChildren[] = filterByVisibility(
    rawFooterItems,
    isLoggedIn,
  ).map((item) => ({
    ...item,
    children: filterByVisibility(item.children, isLoggedIn),
  }));

  return (
    <html
      lang="en"
      // next-themes sets the dark/light class on this element before React
      // hydrates (see ThemeProvider), which will always mismatch the
      // server-rendered class -- suppressHydrationWarning tells React that's
      // expected instead of logging a hydration error.
      suppressHydrationWarning
      className={`${cormorantGaramond.variable} ${inter.variable} h-full antialiased`}
    >
      <body className="min-h-full flex flex-col bg-cream font-body text-charcoal">
        <ThemeProvider>
          {!ageVerified && <AgeGate />}
          <Header currentUser={currentUser} headerItems={headerItems} />
          <div className="flex-1">{children}</div>
          <Footer footerItems={footerItems} />
        </ThemeProvider>
      </body>
    </html>
  );
}
