'use client';

import usePreference from '@/hooks/helpers/usePreference';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useParams } from 'next/navigation';
import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
import SplashScreen from '@/components/overlays/SplashScreen';
import { hexToOklch, calculateBrightness } from '@/lib/helpers/colorUtils';
import {
    applyCachedThemeToDom,
    buildThemeCacheFromRestaurant,
    clearRestaurantBackgroundOverrides,
    getCachedMenuColor,
    getThemeCache,
    setThemeCache,
} from '@/lib/helpers/themeCache';

function getSplashStorageKey(restaurantSlug: string) {
    return `splash-seen:${restaurantSlug}`;
}

function getSplashSessionKey(restaurantSlug: string) {
    return `splash-session:${restaurantSlug}`;
}

function getSplashFingerprint(logo?: string | null, name?: string | null) {
    return `${logo ?? ''}|${name ?? ''}`;
}

function readStoredRestaurantIdentity() {
    return {
        logo: localStorage.getItem('restaurant-logo'),
        name: localStorage.getItem('restaurant-name'),
    };
}

function resolveSeenSplashFingerprint(restaurantSlug: string, currentFingerprint: string) {
    const storageKey = getSplashStorageKey(restaurantSlug);
    const seenFingerprint = localStorage.getItem(storageKey);

    if (!seenFingerprint || seenFingerprint === '|') {
        if (currentFingerprint !== '|') {
            localStorage.setItem(storageKey, currentFingerprint);
            return currentFingerprint;
        }
    }

    return seenFingerprint;
}

type Props = {
    children: React.ReactNode
}

function applyPrimaryColor(colorHex: string) {
    const root = document.documentElement;
    const oklchColor = hexToOklch(colorHex);

    if (oklchColor) {
        root.style.setProperty('--primary', oklchColor);

        const brightness = calculateBrightness(colorHex);
        const foregroundOklch = brightness > 0.5 ? 'oklch(0 0 0)' : 'oklch(1 0 0)';
        root.style.setProperty('--primary-foreground', foregroundOklch);
    }
}

function PreferenceWrapper({ children }: Props) {
    const params = useParams();
    const restaurantSlug = typeof params.name === 'string' ? params.name : '';

    const { state: nightMode } = usePreference('night-mode', false);
    const { data: aboutData } = useGetAbout();

    const [showSplash, setShowSplash] = useState(false);
    const [mounted, setMounted] = useState(false);
    const [cachedLogo, setCachedLogo] = useState<string | null>(null);
    const [cachedName, setCachedName] = useState<string | null>(null);
    const splashCheckedRef = useRef(false);

    const handleSplashDismiss = useCallback(() => {
        setShowSplash(false);

        if (!restaurantSlug) return;

        const stored = readStoredRestaurantIdentity();
        const logo = aboutData?.data?.logo || stored.logo || cachedLogo;
        const name = aboutData?.data?.name || stored.name || cachedName;
        const fingerprint = getSplashFingerprint(logo, name);

        localStorage.setItem(getSplashStorageKey(restaurantSlug), fingerprint);
        sessionStorage.setItem(getSplashSessionKey(restaurantSlug), '1');
    }, [aboutData?.data?.logo, aboutData?.data?.name, cachedLogo, cachedName, restaurantSlug]);

    useEffect(() => {
        if (splashCheckedRef.current) return;
        splashCheckedRef.current = true;

        setMounted(true);

        const savedColor = getCachedMenuColor(restaurantSlug);
        const cachedTheme = restaurantSlug ? getThemeCache(restaurantSlug) : null;
        if (cachedTheme) {
            applyCachedThemeToDom(cachedTheme);
        } else if (savedColor) {
            applyPrimaryColor(savedColor);
        }

        const { logo: savedLogo, name: savedName } = readStoredRestaurantIdentity();
        if (savedLogo) setCachedLogo(savedLogo);
        if (savedName) setCachedName(savedName);

        if (!restaurantSlug) return;

        if (sessionStorage.getItem(getSplashSessionKey(restaurantSlug))) {
            return;
        }

        const currentFingerprint = getSplashFingerprint(savedLogo, savedName);
        const seenFingerprint = resolveSeenSplashFingerprint(restaurantSlug, currentFingerprint);

        if (seenFingerprint !== currentFingerprint) {
            setShowSplash(true);
            sessionStorage.setItem(getSplashSessionKey(restaurantSlug), '1');
        }
    }, [restaurantSlug]);

    useEffect(() => {
        const menuColor = aboutData?.data?.menuColor;
        if (!menuColor || !restaurantSlug) return;

        const restaurant = aboutData.data;
        const cached = getThemeCache(restaurantSlug);

        const themeBase = buildThemeCacheFromRestaurant(restaurant);
        setThemeCache(restaurantSlug, {
            menuColor,
            bgType: themeBase.bgType,
            bgUrl: restaurant.bgUrl,
            bgBlur: themeBase.bgBlur,
            bgOpacity: themeBase.bgOpacity,
            bgOverlay: themeBase.bgOverlay,
            isPattern: themeBase.isPattern,
            patternDataUrl: cached?.patternDataUrl ?? null,
        });

        const updatedTheme = getThemeCache(restaurantSlug);
        if (updatedTheme) {
            applyCachedThemeToDom(updatedTheme);
        }

        if (restaurant.logo) {
            localStorage.setItem('restaurant-logo', restaurant.logo);
        }
        if (restaurant.name) {
            localStorage.setItem('restaurant-name', restaurant.name);
        }

        applyPrimaryColor(menuColor);

        const currentFingerprint = getSplashFingerprint(
            restaurant.logo ?? readStoredRestaurantIdentity().logo,
            restaurant.name ?? readStoredRestaurantIdentity().name,
        );
        const seenFingerprint = localStorage.getItem(getSplashStorageKey(restaurantSlug));
        if (seenFingerprint === '|' && currentFingerprint !== '|') {
            localStorage.setItem(getSplashStorageKey(restaurantSlug), currentFingerprint);
        }
    }, [aboutData?.data, restaurantSlug]);

    useEffect(() => {
        document.documentElement.setAttribute('data-theme', nightMode ? 'dark' : 'light');

        if (nightMode) {
            clearRestaurantBackgroundOverrides();
            return;
        }

        if (!restaurantSlug) return;

        const cached = getThemeCache(restaurantSlug);
        if (cached) {
            applyCachedThemeToDom(cached);
        }
    }, [nightMode, restaurantSlug]);

    const splashLogo = mounted
        ? (aboutData?.data?.logo || cachedLogo || undefined)
        : undefined;
    const splashName = mounted
        ? (aboutData?.data?.name || cachedName || undefined)
        : undefined;

    return (
        <>
            {children}
            {showSplash && (
                <SplashScreen
                    logo={splashLogo}
                    restaurantName={splashName}
                    onDismiss={handleSplashDismiss}
                />
            )}
        </>
    )
}

export default PreferenceWrapper
