import { createInertiaApp, router } from '@inertiajs/vue3';
import type { Component } from 'vue';
import { initializeTheme, syncDocumentArea } from '@/composables/useAppearance';
import ImpersonationBannerLayout from '@/layouts/ImpersonationBannerLayout.vue';
import { initializeFlashToast } from '@/lib/flashToast';
import {
    activeThemes,
    hostLayoutId,
    layoutFileFor,
    layoutNeedsImpersonation,
    parseModuleName,
    resolvePage,
} from '@/platform/resolveFrontend';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';

const themeLayouts = import.meta.glob<{ default: Component }>(
    '../../themes/*/resources/js/layouts/**/*.vue',
    { eager: true },
);

function layoutFrom(
    slug: string | null | undefined,
    relative: string,
): Component | null {
    if (!slug) {
        return null;
    }

    const key = `../../themes/${slug}/resources/js/layouts/${relative}.vue`;

    return themeLayouts[key]?.default ?? null;
}

function withImpersonationBanner(
    inner: Component | Component[] | null,
): Component | Component[] {
    if (!inner) {
        return ImpersonationBannerLayout;
    }

    const rest = Array.isArray(inner) ? inner : [inner];

    return [ImpersonationBannerLayout, ...rest];
}

function pageArea(props: unknown): string | null {
    const record = props as {
        theme?: { area?: string };
        platform?: { area?: string };
    } | null;

    return record?.theme?.area ?? record?.platform?.area ?? null;
}

function applyPageArea(props: unknown): void {
    syncDocumentArea(pageArea(props));
}

router.on('navigate', (event) => {
    applyPageArea(event.detail.page.props);
});

createInertiaApp({
    title: (title) => (title ? `${title} - ${appName}` : appName),
    resolve: resolvePage,
    layout: (name) => {
        const themes = activeThemes();
        const id = hostLayoutId(name);

        if (name.startsWith('settings/')) {
            return [
                layoutFrom(themes.admin, 'AppLayout'),
                layoutFrom(themes.admin, 'settings/Layout'),
            ].filter(Boolean) as Component[];
        }

        if (name.startsWith('theme/')) {
            const match = name.match(/^theme\/([^/]+)\//);
            const nested = match
                ? layoutFrom(match[1], 'admin/ConfigLayout')
                : null;

            return [layoutFrom(themes.admin, 'AppLayout'), nested].filter(
                Boolean,
            ) as Component[];
        }

        const file = layoutFileFor(id);
        const slug = id?.startsWith('admin') ? themes.admin : themes.client;
        const inner = file ? layoutFrom(slug, file) : null;

        if (
            parseModuleName(name)?.zone === 'embed' ||
            name === 'status/Embed'
        ) {
            return null;
        }

        if (layoutNeedsImpersonation(id)) {
            return withImpersonationBanner(inner);
        }

        return inner;
    },
    progress: {
        color: '#4B5563',
    },
});

initializeTheme();
initializeFlashToast();
