import "./globals.css";
import type { ReactNode } from "react";
import Navbar from "../components/layout/Navbar";
import { Signika, Open_Sans, Geist, Geist_Mono, Noto_Sans } from "next/font/google";
import { fetchHeaderFooterForLayout } from "../lib/serverFetch";
import { DomainNotRecognizedError } from "../lib/services/headerFooterService";
import { getProgramsAction } from "../lib/actions/programsAction";
import { fetchWorkshopActivities } from "../lib/actions/workshopAction";
import { ProcessedProgram } from "../lib/types/programs";
import { Activity } from "../lib/services/workshopService";
import { redirect } from "next/navigation";
import { headers } from "next/headers";
import { LanguageProvider } from "@/src/lib/context/LanguageContext";
import { ProgramsProvider } from "@/src/lib/context/ProgramsContext";
import { WorkshopsProvider } from "@/src/lib/context/WorkshopsContext";
import { NavHistoryProvider } from "@/src/lib/context/NavHistoryContext";
import ScrollToTopButton from "../components/ui/ScrollToTopButton";
import { extractDomain } from "../lib/utils/domain";

import type { Metadata } from "next";

// Per-tenant metadata: `metadataBase` is built from the request's own domain so
// each franchisee site self-references (canonicals, OG URLs, etc.) instead of
// pointing every tenant at one hardcoded host. Individual pages set their own
// `alternates.canonical` (relative to this base).
export async function generateMetadata(): Promise<Metadata> {
  let domain = "web.youngengineers.org";
  try {
    domain = await extractDomain();
  } catch {
    // Headers unavailable (e.g. build) — fall back to the default host.
  }

  let metadataBase: URL | undefined;
  try {
    metadataBase = new URL(`https://${domain}`);
  } catch {
    metadataBase = undefined;
  }

  return {
    metadataBase,
    title: {
      default: "Young Engineers",
      template: "%s | Young Engineers",
    },
    description:
      "Young Engineers offers coding, robotics, STEM education, workshops, and camps for children worldwide.",
  };
}


const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});
const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});
const signika = Signika({
  subsets: ["latin"],
  weight: ["300", "400", "500", "600", "700"],
  variable: "--font-signika",
});
const openSans = Open_Sans({
  subsets: ["latin"],
  weight: ["300", "400", "500", "600", "700", "800"],
  variable: "--font-open-sans",
});

const NotoSans = Noto_Sans({
  subsets: ["latin"],
  variable: "--font-Noto_Sans",
  weight: ["300", "400", "500", "600", "700"],
});



export const dynamic = "force-dynamic";

export default async function RootLayout({
  children,
}: {
  children: ReactNode;
}) {
  // Fetch data using layout-specific function (reads from middleware headers)
  let headerFooterHomeData;
  let programsData: ProcessedProgram[] = [];
  let workshopsData: Activity[] = [];
  
  try {
    const [headerRes, programsRes, workshopsRes] = await Promise.all([
      fetchHeaderFooterForLayout(),
      getProgramsAction(),
      fetchWorkshopActivities()
    ]);
    headerFooterHomeData = headerRes;
    if (programsRes.success && programsRes.data) {
      programsData = programsRes.data;
    }
    if (workshopsRes.success && workshopsRes.data) {
      workshopsData = workshopsRes.data;
    }
  } catch (error) {
    // If domain is not recognized, redirect to main site
    if (error instanceof DomainNotRecognizedError) {
      redirect("https://youngengineers.org/");
    }
    throw error;
  }

  // A licensee's primary language (admin → General Settings) is what their
  // visitors should land on. Middleware sets `x-lang` only when the URL carries
  // one, so an absent header means nobody has picked a language yet: send them
  // to the licensee's own language once, and every link from there carries it
  // forward. Choosing English in the switcher writes `?lang=en`, which counts
  // as a choice and stops this from overriding it.
  //
  // Deliberately skipped for the global/corporate tenant: licensees without
  // their own settings row inherit the shared record, so honouring its language
  // there would let one shared value flip youngengineers.org itself.
  const headersList = await headers();
  const requestedLang = headersList.get("x-lang");
  const primaryLang = headerFooterHomeData.general_settings?.language_code?.toLowerCase();
  const isGlobalSite = headerFooterHomeData.tenant?.isGlobal === true;

  if (!requestedLang && !isGlobalSite && primaryLang && primaryLang !== "en") {
    const search = new URLSearchParams(headersList.get("x-search") || "");
    search.set("lang", primaryLang);
    redirect(`${headersList.get("x-pathname") || "/"}?${search.toString()}`);
  }

  // Past the redirect above, an absent x-lang means the licensee's primary
  // language is English, so the header alone determines the document lang.
  return (
    <html lang={requestedLang || "en"} className="overflow-x-clip">
      <body
        className={`${signika.variable} ${NotoSans.variable} ${openSans.variable} ${geistMono.variable} antialiased overflow-x-clip`}
        style={{ width: "100%", maxWidth: "2000px", margin: "0 auto" }}
      >
        <LanguageProvider>
          <ProgramsProvider programs={programsData}>
            <WorkshopsProvider workshops={workshopsData}>
              <NavHistoryProvider>
                <Navbar
                  headerData={headerFooterHomeData.header}
                  whatsappData={headerFooterHomeData.whatsapp}
                  generalSettings={headerFooterHomeData.general_settings}
                  programs={programsData}
                  workshops={workshopsData}
                />
                {children}
                <ScrollToTopButton />
              </NavHistoryProvider>
            </WorkshopsProvider>
          </ProgramsProvider>
        </LanguageProvider>
      </body>
    </html>
  );
}
