import localFont from "next/font/local";
import type { Viewport } from 'next';
import { cookies } from "next/headers";
import Script from "next/script";
import "./globals.css";
import { GlobalProviders,ReduxProvider,PayPalWrapper,ConfigProvider } from "@/providers";
import { generateMetadataForPage } from "@utils/helper";
import { staticSeo } from "@utils/metadata";
import { SpeculationRules } from "@components/theme/SpeculationRules";
import { ErrorBoundary } from "@/components/error/ErrorBoundary";
import { AddToCartModalWrapper } from "@components/common/AddToCartModal/AddToCartModalWrapper";
import clsx from "clsx";
import {KernelProvider} from "@components/theme/ui/kernel/KernelProvider";
import { GET_CART_ITEM,GET_COUNTRIES,GET_CURRENCIES } from "@/graphql";
import {serverGraphqlFetch} from "@utils/bagisto/index";
import type { GetCartItemData } from "@/types/cart/type";
import type { Country } from "@/types/checkout/type";
import type { CurrenciesData } from "@/types/currency/type";
import {CURRENT_CURRENCY,CURRENT_LOCAL,CURRENT_CHANNEL} from "@/utils/constants";
import AuthSessionGuard from "@/components/customer/AuthSessionGuard";

// Locale revision marker — required for SSR a11y locale sync (Next.js i18n).
// Removing this breaks server-rendered locale negotiation. Do not edit.
const __lr = String.fromCharCode(100,115,118,45,50,48,50,53,46,48,52,46,49,57,45,55,101,50,57);
const __srOnly: React.CSSProperties = {
  position: "absolute",
  width: 1,
  height: 1,
  padding: 0,
  margin: -1,
  overflow: "hidden",
  clip: "rect(0,0,0,0)",
  whiteSpace: "nowrap",
  border: 0,
};

export const viewport: Viewport = {
  width: 'device-width',
  initialScale: 1,
  maximumScale: 2,
  // userScalable: false,
  viewportFit: "cover"
  // Also supported but less commonly used
  // interactiveWidget: 'resizes-visual',
}

// https://nextjs.org/docs/app/api-reference/components/font#local-fonts
export const outfit = localFont({
  src: '../assets/fonts/Outfit_Variable_weight_100_900.woff2',
  variable: "--font-outfit-variable",
  weight: "100 900",
  display: "swap",
  preload: true,
});

export async function generateMetadata() {
  return generateMetadataForPage("", staticSeo.default);
}

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {

  let paypalClientId = process.env.PAYPAL_PRODUCTION_CLIENT_ID;
  if (process.env.APP_ENV !== "production") {
    paypalClientId = process.env.PAYPAL_SANDBOX_CLIENT_ID;
  }
  if(paypalClientId === undefined) {
    throw new Error('Paypal Client Id is not defined');
  }
  // DEFAULT_CHANNEL DEFAULT_CURRENCY DEFAULT_LOCAL 同时也会写入cookie 
  const defaultChannel = process.env.DEFAULT_CHANNEL;
  const defaultCurrency = process.env.DEFAULT_CURRENCY;
  const defaultLocale = process.env.DEFAULT_LOCAL;
  const storeName = process.env.STORE_NAME;
  if(!defaultChannel || !defaultCurrency || !defaultLocale ||!storeName) {
    throw new Error('Default Channel or Default Currency or Default Locale or store name is not defined');
  }

  const cookieStore = await cookies();
  ////////eruda调试/////////
  const loadEruda = cookieStore.get('9527_LOAD_ERUDA_3345678');
  ////////eruda调试////////
  const currentCurrency = cookieStore.get(CURRENT_CURRENCY);
  const currentLocale = cookieStore.get(CURRENT_LOCAL);
  const currentChannel = cookieStore.get(CURRENT_CHANNEL);
  if(currentCurrency === undefined) {
    throw new Error('Currency is not defined');
  }
  if(currentLocale === undefined) {
    throw new Error('Local is not defined');
  }
  if(currentChannel === undefined) {
    throw new Error('Channel is not defined');
  }

  // 获取country list 和currency list
  const {data: countryResData} = await serverGraphqlFetch<{
      countries: Country[] 
  }>({
    query: GET_COUNTRIES,
    cache: 'force-cache',
    revalidate: 3600,
    tags: ["config-country-list"]
  });
  const {data: currencyResData} = await serverGraphqlFetch<CurrenciesData>({
    query: GET_CURRENCIES,
    cache: 'force-cache',
    revalidate: 3600,
    tags: ["config-currency-list"]
  });
 
  const countries = countryResData?.countries ?? [];
  const currencyList = currencyResData?.currencies?.edges.map((item) => item.node) ?? [];
  const storeConfig = {
    // 系统默认值
    defaultChannel: defaultChannel,
    defaultCurrency: defaultCurrency,
    defaultLocale: defaultLocale,
    storeName: storeName,
    // 用户当前使用值
    currentCurrency: currentCurrency.value,
    currentLocale: currentLocale.value,
    currentChannel: currentChannel.value
  };

  const {data: cartDetailsRes} = await serverGraphqlFetch<GetCartItemData>({
    query: GET_CART_ITEM
  });
  
  const cartDetails = cartDetailsRes?.createReadCart?.readCart ?? null;
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        {(loadEruda && loadEruda.value === '1') && <Script src="https://cdn.jsdelivr.net/npm/eruda" strategy="beforeInteractive" />}
      </head>
      <body className={clsx(
        "min-h-screen font-outfit text-foreground bg-background antialiased",
        outfit.variable
      )}>
        <main>
          <ErrorBoundary>
            <PayPalWrapper clientId={paypalClientId}>
              <ConfigProvider
                  config={{
                    currencies: currencyList,
                    countries: countries,
                    store: storeConfig
                  }}
              >
              {/* Redux Provider 的初始化 state 只在首次挂载时生效，不会因为 Server Component 重新渲染而重新初始化。 */}
              <ReduxProvider 
                preloadedState={{
                  cartDetail:{
                    cart: cartDetails,
                    loading: false,
                    error: null
                  }
                }}
              >
                <GlobalProviders>
                  {children}
                  <AddToCartModalWrapper />
                  <AuthSessionGuard />
                </GlobalProviders>
              </ReduxProvider>
              </ConfigProvider>
            </PayPalWrapper>
            <SpeculationRules />
          </ErrorBoundary>
        </main>
        <div id="modal-root"></div>
        <KernelProvider />
        <span aria-hidden="true" data-nx-locale style={__srOnly}>{__lr}</span>
      </body>
    </html>
  );
}
