import type { Metadata } from "next";
import { Geist, Geist_Mono, Archivo_Black } from "next/font/google";
import Script from "next/script";
import React from "react";
import "./globals.scss";
import { SignalRProvider } from '@/contexts/signalrProvider';
import { AuthProvider } from "@/contexts/authProvider";
import { MemberProvider } from "@/contexts/memberProvider";
import { ConfigProvider } from "@/contexts/configProvider";
import { CartProvider } from "@/contexts/cartProvider";
import { ThemeProvider } from "@/contexts/themeProvider";
import { Toaster } from "@/components/ui/sonner";
import { getAccessToken, getSignalRChatUrl, getSignalRAppUrl } from "@/lib/utils/server";
import { fetchConfig } from "@/lib/api/system";
import { getInitialMember } from "@/lib/api/auth";

const geistSans = Geist({
    variable: "--font-geist-sans",
    subsets: ["latin"],
});

const geistMono = Geist_Mono({
    variable: "--font-geist-mono",
    subsets: ["latin"],
});

const archivoBlack = Archivo_Black({
    variable: "--font-brand",
    subsets: ["latin"],
    weight: "400",
    display: "swap",
});

type ColorSchemeEnum = 'normal' | 'light' | 'dark' | 'light dark' | 'dark light' | 'only light';

function parseMetaAdds(html: string | null | undefined)
{
	if (!html) return { other: {} as Record<string, string>, themeColor: [] as { media?: string; color: string }[], colorScheme: undefined as ColorSchemeEnum | undefined };

	const other: Record<string, string> = {};
	const themeColor: { media?: string; color: string }[] = [];
	const validColorSchemes: ColorSchemeEnum[] = ['normal', 'light', 'dark', 'light dark', 'dark light', 'only light'];
	let colorScheme: ColorSchemeEnum | undefined;

	const tagRegex = /<meta\s+([^>]+)\/?>/gi;
	const attrRegex = /(\w[\w-]*)=["']([^"']*?)["']/gi;

	let tagMatch;
	while ((tagMatch = tagRegex.exec(html)) !== null) {
		const attrs: Record<string, string> = {};
		let attrMatch;
		while ((attrMatch = attrRegex.exec(tagMatch[1])) !== null) {
			attrs[attrMatch[1].toLowerCase()] = attrMatch[2];
		}

		const name = attrs['name'];
		const content = attrs['content'];
		if (!name || !content) continue;

		if (name === 'theme-color') {
			themeColor.push(attrs['media'] ? { media: attrs['media'], color: content } : { color: content });
		} else if (name === 'color-scheme') {
			if (validColorSchemes.includes(content as ColorSchemeEnum)) {
				colorScheme = content as ColorSchemeEnum;
			}
		} else {
			other[name] = content;
		}
	}

	return { other, themeColor, colorScheme };
}

export async function generateMetadata(): Promise<Metadata> {
    const config = (await fetchConfig())?.data;
    const metaAdds = parseMetaAdds(config?.meta?.adds);

    return {
        title: config?.basic?.siteName ?? '개미투자',
        description: config?.meta?.description ?? '',
        keywords: config?.meta?.keywords ?? '',
        authors: config?.meta?.author ? [{ name: config.meta.author }] : undefined,
        applicationName: config?.meta.applicationName,
        generator: config?.meta.generator,
        robots: config?.meta.robots,
        ...(metaAdds.themeColor.length > 0 && { themeColor: metaAdds.themeColor }),
        ...(metaAdds.colorScheme && { colorScheme: metaAdds.colorScheme }),
        other: {
            'naver-site-verification': '18dc0d1c5cb466a765e5f5093f94638ed6537d1c',
            ...metaAdds.other,
        },
    };
}

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

	const accessToken = await getAccessToken();
	const signalRChatUrl = await getSignalRChatUrl();
	const signalRAppUrl = await getSignalRAppUrl();
    const config = (await fetchConfig())?.data;
	const initialMember = await getInitialMember();

    return (
        <html lang="ko" suppressHydrationWarning>
            <head>
                {/* 테마/밀도 FOUC 방지 — 첫 페인트 전에 html class/data 속성 확정 (기본 dark/normal, localStorage 영속) */}
                <script
                    dangerouslySetInnerHTML={{
                        __html: "(function(){var e=document.documentElement;try{var t=localStorage.getItem('az-theme')||localStorage.getItem('bitforum-theme');t=t==='light'?'light':'dark';var d=localStorage.getItem('az-density');if(d!=='compact'&&d!=='expanded'){d='normal';}e.classList.add(t);e.dataset.theme=t;e.dataset.density=d;}catch(r){e.classList.add('dark');e.dataset.theme='dark';e.dataset.density='normal';}})();"
                    }}
                />
                <link rel="manifest" href="/manifest.json" />
                <Script src="https://www.googletagmanager.com/gtag/js?id=G-DY6YFW4CTM" strategy="afterInteractive" />
                <Script id="gtag-init" strategy="afterInteractive">
                    {`
                        window.dataLayer = window.dataLayer || [];
                        function gtag(){dataLayer.push(arguments);}
                        gtag('js', new Date());
                        gtag('config', 'G-DY6YFW4CTM');
                    `}
                </Script>
            </head>
            <body className={`${geistSans.variable} ${geistMono.variable} ${archivoBlack.variable} antialiased`}>
                <ThemeProvider>
                    <SignalRProvider accessToken={accessToken} signalRChatUrl={signalRChatUrl} signalRAppUrl={signalRAppUrl}>
                        <AuthProvider initialAuthenticated={!!initialMember}>
                            <MemberProvider initialMember={initialMember}>
                                <ConfigProvider initialConfig={config}>
                                    <CartProvider>
                                        {children}
                                    </CartProvider>
                                </ConfigProvider>
                            </MemberProvider>
                        </AuthProvider>
                    </SignalRProvider>
                    <Toaster />
                </ThemeProvider>
            </body>
        </html>
    );
}