import type { Metadata } from 'next'
import { headers, cookies } from 'next/headers'
import { Inter } from 'next/font/google'
import './globals.css'
import ThemeWrapper from '@/components/ThemeWrapper'
import I18nProvider from '@/components/I18nProvider'
import { ToastProvider } from '@/contexts/ToastContext'
import { StreamsWsProvider } from '@/contexts/StreamsWsContext'
import { NoticeWsProvider } from '@/contexts/NoticeWsContext'
import { UserNotificationsProvider } from '@/contexts/UserNotificationsContext'
import ToastContainer from '@/components/ToastContainer'
import CookieConsent from '@/components/CookieConsent'
import { getSessionUserId } from '@/server/getSessionUserId'

const inter = Inter({ subsets: ['latin'] })

const SUPPORTED_LANGS = [
    'zh-TW', 'zh-CN', 'en', 'ja', 'ko-KR',
    'ms', 'vi', 'th', 'tr', 'ar', 'id', 'fr', 'ru', 'de', 'it', 'es', 'pl', 'nl', 'hi', 'pt', 'sv', 'ro', 'my', 'fil',
] as const
type SupportedLang = (typeof SUPPORTED_LANGS)[number]

const ACCEPT_LANG_MAP: { pattern: string; lang: SupportedLang }[] = [
    { pattern: 'zh-cn', lang: 'zh-CN' },
    { pattern: 'zh-tw', lang: 'zh-TW' },
    { pattern: 'zh', lang: 'zh-TW' },
    { pattern: 'ko', lang: 'ko-KR' },
    { pattern: 'ja', lang: 'ja' },
    { pattern: 'ms', lang: 'ms' },
    { pattern: 'vi', lang: 'vi' },
    { pattern: 'th', lang: 'th' },
    { pattern: 'tr', lang: 'tr' },
    { pattern: 'ar', lang: 'ar' },
    { pattern: 'id', lang: 'id' },
    { pattern: 'fr', lang: 'fr' },
    { pattern: 'ru', lang: 'ru' },
    { pattern: 'de', lang: 'de' },
    { pattern: 'it', lang: 'it' },
    { pattern: 'es', lang: 'es' },
    { pattern: 'pl', lang: 'pl' },
    { pattern: 'nl', lang: 'nl' },
    { pattern: 'hi', lang: 'hi' },
    { pattern: 'pt', lang: 'pt' },
    { pattern: 'sv', lang: 'sv' },
    { pattern: 'ro', lang: 'ro' },
    { pattern: 'my', lang: 'my' },
    { pattern: 'fil', lang: 'fil' },
    { pattern: 'tl', lang: 'fil' },
    { pattern: 'en', lang: 'en' },
]

export async function generateMetadata(): Promise<Metadata> {
    let lang: SupportedLang = 'zh-TW'

    const cookieStore = cookies()
    const cookieLang = cookieStore.get('lang')?.value
    if (cookieLang && SUPPORTED_LANGS.includes(cookieLang as SupportedLang)) {
        lang = cookieLang as SupportedLang
    } else {
        const h = headers()
        const acceptLang = h.get('accept-language') || ''
        const lower = acceptLang.toLowerCase()
        for (const { pattern, lang: l } of ACCEPT_LANG_MAP) {
            if (lower.includes(pattern)) {
                lang = l
                break
            }
        }
    }

    const locale = await import(`@/i18n/locales/${lang}.json`)
    const description = (locale.default?.meta as { description?: string } | undefined)?.description ?? ''

    return {
        title: 'NoiR',
        description,
        icons: {
            icon: '/images/logo/black.ico',
        },
    }
}

export default async function RootLayout({
    children,
}: {
    children: React.ReactNode
}) {
    let initialUserId: string | null = null
    try {
        initialUserId = await getSessionUserId()
    } catch (error) {
        console.error('Failed to resolve session user:', error)
    }

    return (
        <html lang="zh-TW">
            <body className={`${inter.className} bg-white`}>
                <ThemeWrapper>
                    <I18nProvider>
                        <ToastProvider>
                            <StreamsWsProvider>
                                <NoticeWsProvider initialUserId={initialUserId}>
                                    <UserNotificationsProvider>
                                        {children}
                                        <ToastContainer />
                                        <CookieConsent />
                                    </UserNotificationsProvider>
                                </NoticeWsProvider>
                            </StreamsWsProvider>
                        </ToastProvider>
                    </I18nProvider>
                </ThemeWrapper>
            </body>
        </html>
    )
}

