<script setup lang="ts">
import { router, usePage } from '@inertiajs/vue3';
import {
    NAlert,
    NButton,
    NDropdown,
    NEl,
    NLayout,
    NLayoutHeader,
    NSpin,
    NText,
    useThemeVars,
} from 'naive-ui';
import { computed, h } from 'vue';
import { TbKey, TbLogout, TbShieldLock, TbUser } from 'vue-icons-plus/tb';
import AppDialogManager from '../components/AppDialogManager.vue';
import Noise from '../components/Noise.vue';
import { useGlobalLoading } from '../composables/useGlobalLoading';

const { isGlobalLoading } = useGlobalLoading();
const themeVars = useThemeVars();
const page = usePage();

const appName = computed(() => (page.props.name as string) ?? 'Приложение');
const user = computed(
    () => (page.props.auth as { user?: { name?: string } })?.user,
);

const blobBg = computed(() => {
    const p = themeVars.value.primaryColor;
    const w = themeVars.value.warningColor;
    const i = themeVars.value.infoColor;

    return [
        `radial-gradient(circle 12vw at 50% -4%, color-mix(in srgb, ${p} 20%, transparent), transparent 100%)`,
        `radial-gradient(circle 16vw at 102% 52%, color-mix(in srgb, ${w} 20%, transparent), transparent 100%)`,
        `radial-gradient(circle 16vw at -4% 102%, color-mix(in srgb, ${i} 20%, transparent), transparent 100%)`,
    ].join(', ');
});

const userMenu = [
    { label: 'Сменить пароль', key: 'password', icon: () => h(TbKey) },
    { label: 'Выйти', key: 'logout', icon: () => h(TbLogout) },
];

const onUserSelect = (key: string): void => {
    if (key === 'logout') {
        router.post('/logout');
    } else if (key === 'password') {
        router.get('/password/expired');
    }
};
</script>

<template>
    <Noise />
    <AppDialogManager />

    <NLayout position="absolute">
        <NLayoutHeader bordered style="height: 48px">
            <div class="flex h-12 items-center justify-between px-4">
                <div class="flex items-center gap-2 font-semibold">
                    <TbShieldLock class="size-5 opacity-80" />
                    <span>{{ appName }}</span>
                </div>

                <NDropdown
                    trigger="click"
                    :options="userMenu"
                    @select="onUserSelect"
                >
                    <NButton text>
                        <template #icon>
                            <TbUser />
                        </template>
                        {{ user?.name ?? 'Пользователь' }}
                    </NButton>
                </NDropdown>
            </div>
        </NLayoutHeader>

        <Transition name="wait-alert">
            <NEl
                v-if="isGlobalLoading"
                class="pointer-events-none fixed inset-x-0 top-[56px] z-[2600] flex justify-center px-3"
            >
                <NAlert
                    type="info"
                    :show-icon="false"
                    class="wait-banner w-full max-w-md"
                >
                    <div
                        class="flex items-center justify-center gap-2.5 text-[13px] leading-none"
                    >
                        <NSpin :size="14" />
                        <NText depth="1">Подождите, загружаем данные…</NText>
                    </div>
                </NAlert>
            </NEl>
        </Transition>

        <NEl class="pointer-events-none fixed inset-x-0 top-12 bottom-0 z-0">
            <div class="absolute inset-0" :style="`background: ${blobBg};`" />
            <div class="grid-overlay absolute inset-0 opacity-60" />
        </NEl>

        <NLayout
            position="absolute"
            class="relative top-12! bottom-0! z-10 overflow-hidden"
            content-class="relative z-10"
            :native-scrollbar="false"
            style="--n-color: transparent"
        >
            <div class="mx-auto w-full max-w-5xl p-4">
                <slot name="header" />
                <slot />
            </div>
        </NLayout>
    </NLayout>
</template>

<style scoped>
.wait-alert-enter-active,
.wait-alert-leave-active {
    transition: all 0.2s ease;
}

.wait-alert-enter-from,
.wait-alert-leave-to {
    opacity: 0;
    transform: translateY(-6px);
}

.wait-banner {
    backdrop-filter: blur(10px);
    border-radius: 10px;
}

:deep(.wait-banner .n-alert-body) {
    padding: 8px 12px;
}

:global(body:has(.n-modal-container)) .wait-layer {
    top: 24px;
}
</style>
