import type { Metadata } from "next";
import { Geist, Geist_Mono } 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 { ThemeProvider } from "@/contexts/themeProvider";
import { getAccessToken, getSignalRChatUrl } from "@/lib/utils/server";
import { fetchConfig } from "@/lib/api/system";

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

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

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 ?? 'dpot',
        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 config = (await fetchConfig())?.data;

    return (
        <html lang="ko" suppressHydrationWarning>
            <head>
                <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} antialiased`}>
                <ThemeProvider>
                    <SignalRProvider accessToken={accessToken} signalRChatUrl={signalRChatUrl}>
                        <AuthProvider>
                            <MemberProvider>
                                <ConfigProvider initialConfig={config}>
                                    {children}
                                </ConfigProvider>
                            </MemberProvider>
                        </AuthProvider>
                    </SignalRProvider>
                </ThemeProvider>
            </body>
        </html>
    );
}