import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import '../css/app.css';
// import { initializeTheme } from './hooks/use-appearance';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
const SCROLL_TEXT_SELECTOR =
    'main :is(h1, h2, h3, h4, h5, h6, p, li, dt, dd, blockquote, figcaption, label, small, a)';
const SCROLL_TEXT_EXCLUDE_SELECTOR =
    'script, style, noscript, svg, button, input, textarea, select, option, [data-no-scroll-reveal], [aria-hidden="true"]';

function ScrollTextReveal(): null {
    useEffect(() => {
        if (typeof window === 'undefined') {
            return;
        }

        const prefersReducedMotion = window.matchMedia(
            '(prefers-reduced-motion: reduce)',
        ).matches;

        if (prefersReducedMotion) {
            document.querySelectorAll(SCROLL_TEXT_SELECTOR).forEach((element) => {
                element.classList.add('is-visible');
                element.removeAttribute('data-scroll-text');
                element.style.removeProperty('--scroll-text-delay');
            });

            return;
        }

        const preparedElements = new Set<Element>();
        const observer = new IntersectionObserver(
            (entries) => {
                entries.forEach((entry) => {
                    if (!entry.isIntersecting) {
                        return;
                    }

                    entry.target.classList.add('is-visible');
                    observer.unobserve(entry.target);
                });
            },
            {
                threshold: 0.15,
                rootMargin: '0px 0px -12% 0px',
            },
        );

        const prepareElements = (): void => {
            let revealIndex = 0;

            document.querySelectorAll(SCROLL_TEXT_SELECTOR).forEach((element) => {
                if (preparedElements.has(element)) {
                    return;
                }

                if (element.closest(SCROLL_TEXT_EXCLUDE_SELECTOR)) {
                    return;
                }

                const content = element.textContent?.trim();
                if (!content) {
                    return;
                }

                preparedElements.add(element);
                element.setAttribute('data-scroll-text', 'true');
                element.style.setProperty(
                    '--scroll-text-delay',
                    `${Math.min((revealIndex % 8) * 70, 420)}ms`,
                );

                revealIndex += 1;
                observer.observe(element);
            });
        };

        const schedulePrepareElements = (): void => {
            window.requestAnimationFrame(() => {
                prepareElements();
            });
        };

        prepareElements();

        const mutationObserver = new MutationObserver(() => {
            schedulePrepareElements();
        });

        mutationObserver.observe(document.body, {
            childList: true,
            subtree: true,
        });

        return () => {
            mutationObserver.disconnect();
            observer.disconnect();
            preparedElements.clear();
        };
    }, []);

    return null;
}

createInertiaApp({
    title: (title) => (title ? `${title}` : appName),
    resolve: (name) =>
        resolvePageComponent(
            `./pages/${name}.tsx`,
            // import.meta.glob('./pages/**/*.tsx'),
            import.meta.glob('./pages/**/*.tsx'),
        ),
    setup({ el, App, props }) {
        const root = createRoot(el);

        root.render(
            <StrictMode>
                <ScrollTextReveal />
                <App {...props} />
            </StrictMode>,
        );
    },
    progress: {
        color: '#4B5563',
    },
});

// This will set light / dark mode on load...
// initializeTheme();
