<script setup lang="ts">
import { useNuxtApp } from 'nuxt/app';

import useSimpleHead from '~/composables/useSimpleHead.ts';
import type { LocalDescriptionWithConfig } from '~/server/admin.ts';
import { longtimeCookieSetting } from '~/src/cookieSettings.ts';
import { newDate } from '~/src/helpers.ts';
import { useMainStore } from '~/store/index.ts';

const { $translator: translator, $isGranted: isGranted } = useNuxtApp();
useSimpleHead({
    title: translator.translate('admin.header'),
}, translator);

const tokenCookie = useCookie('token', longtimeCookieSetting);
const impersonatorCookie = useCookie('impersonator', longtimeCookieSetting);

const statsAsyncData = useFetch('/api/admin/stats');
const allLocalesAsyncData = useFetch('/api/admin/all-locales');
await Promise.all([statsAsyncData, allLocalesAsyncData]);
const stats = statsAsyncData.data;
const allLocales = allLocalesAsyncData.data;

const store = useMainStore();

const adminNotifications = ref(store.user ? store.user.adminNotifications ?? 7 : 7);
watch(adminNotifications, async () => {
    const res = await $fetch('/api/admin/set-notification-frequency', {
        method: 'POST',
        body: { frequency: adminNotifications.value },
    });
    await store.setToken(res.token);
});

const filterAttention = ref<boolean>(false);

const visibleLocales = computed((): Record<string, LocalDescriptionWithConfig> | null => {
    if (allLocales.value === null) {
        return null;
    }
    return Object.fromEntries(Object.entries(allLocales.value).filter(([locale, _]) => {
        return isGranted('panel', locale) && statsAsyncData.data.value?.locales[locale];
    }));
});

const router = useRouter();
const impersonate = async (email: string) => {
    const { token } = await $fetch(`/api/admin/impersonate/${encodeURIComponent(email)}`);
    impersonatorCookie.value = tokenCookie.value;
    tokenCookie.value = token;
    await router.push({ name: 'user' });
    setTimeout(() => window.location.reload(), 500);
};
</script>

<template>
    <Page wide>
        <NotFound v-if="!$isGranted('panel')" />
        <div v-else>
            <div class="d-flex flex-column flex-lg-row justify-content-between align-items-lg-center">
                <div>
                    <h2>
                        <Icon v="user-cog" />
                        <T>admin.header</T>
                    </h2>

                    <p v-if="stats" class="small">
                        <em>
                            Stats calculated at:
                            <span
                                :class="stats.calculatedAt < (newDate().getTime() - 24 * 60 * 60 * 1000) / 1000
                                    ? `badge bg-danger text-white`
                                    : ''"
                            >
                                {{ $datetime(stats.calculatedAt) }}
                            </span>
                        </em>
                    </p>
                </div>
                <div class="form-check form-switch my-2">
                    <label>
                        <input v-model="filterAttention" class="form-check-input" type="checkbox" role="switch">
                        <Icon v="filter" />
                        Only show items requiring attention
                    </label>
                </div>
            </div>

            <h3>General</h3>

            <div class="row mb-4">
                <AdminDashboardCard
                    v-if="stats && ($isGranted('users') || $isGranted('community'))"
                    v-show="!filterAttention"
                    icon="users"
                    header="Users"
                    link="/admin/users"
                    :counts="[
                        { count: stats.overall.users },
                        { name: 'admins', count: stats.overall.admins },
                    ]"
                />
                <AdminDashboardCard
                    v-if="stats && ($isGranted('users') || $isGranted('community'))"
                    v-show="!filterAttention || stats.overall.bansPending"
                    icon="ban"
                    header="Pending bans"
                    link="/admin/pending-bans"
                    :counts="[
                        { count: stats.overall.bansPending, warning: 1, danger: 16 },
                    ]"
                />
                <AdminDashboardCard
                    v-if="stats && ($isGranted('users') || $isGranted('community'))"
                    v-show="!filterAttention || stats.overall.userReports"
                    icon="siren-on"
                    header="Abuse reports"
                    link="/admin/abuse-reports"
                    :counts="[
                        { count: stats.overall.userReports, warning: 1, danger: 16 },
                    ]"
                />
                <AdminDashboardCard
                    v-show="!filterAttention"
                    icon="user-cog"
                    link="/admin/moderation"
                    header="Moderation rules"
                />
                <AdminDashboardCard
                    v-if="stats && $isGranted('code')"
                    v-show="!filterAttention || stats.overall.cardsQueue"
                    icon="id-card"
                    header="Cards queue"
                    :counts="[
                        { count: stats.overall.cardsQueue, warning: 16, danger: 64 },
                    ]"
                />
                <AdminDashboardCard
                    v-if="stats && $isGranted('code')"
                    v-show="!filterAttention || stats.overall.linksQueue"
                    icon="link"
                    header="Links queue"
                    :counts="[
                        { count: stats.overall.linksQueue, warning: 64, danger: 256 },
                    ]"
                />
                <AdminDashboardCard
                    v-show="!filterAttention"
                    icon="bell"
                    header="Email notifications"
                >
                    <span v-for="(label, value) in { 0: 'Never', 1: 'Daily', 7: 'Weekly' }" class="form-check form-check-inline">
                        <input
                            :id="`notifiactionFrequency_${value}`"
                            v-model="adminNotifications"
                            class="form-check-input"
                            type="radio"
                            name="inlineRadioOptions"
                            :value="value"
                        >
                        <label class="form-check-label" :for="`notifiactionFrequency_${value}`">{{ label }}</label>
                    </span>
                </AdminDashboardCard>
                <AdminDashboardCard
                    v-show="!filterAttention"
                    v-if="$isGranted('users') || $isGranted('community')"
                    icon="user-secret"
                    header="@example"
                >
                    <button class="btn btn-primary btn-sm" @click="impersonate('example@pronouns.page')">
                        Impersonate
                    </button>
                </AdminDashboardCard>
                <AdminDashboardCard
                    v-show="!filterAttention"
                    icon="b:discord"
                    link="https://team-discord.pronouns.page"
                    header="Team Discord"
                />
                <AdminDashboardCard
                    v-show="!filterAttention"
                    icon="palette"
                    link="/design"
                    header="Design guidelines"
                />
                <AdminDashboardCard
                    v-show="!filterAttention"
                    icon="file-spreadsheet"
                    link="/admin/timesheets"
                    header="Volunteering timesheets"
                />
            </div>

            <template v-for="({ name, extra, config, url, published }, locale) in visibleLocales" :key="locale">
                <h3>
                    {{ name }} {{ extra ? `(${extra})` : '' }}
                    <small v-if="!published" class="text-muted">(not published yet)</small>
                </h3>
                <div class="row mb-4">
                    <AdminDashboardCard
                        v-if="stats"
                        v-show="!filterAttention"
                        :base-url="url"
                        icon="users"
                        header="Profiles"
                        link="/admin/profiles"
                        :counts="[
                            { count: stats.locales[locale].users },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="stats && config.nouns && config.nouns.enabled && $isGranted('nouns', locale) && (stats.locales[locale].nouns.approved > 0 || stats.locales[locale].nouns.awaiting > 0)"
                        v-show="!filterAttention || stats.locales[locale].nouns.awaiting"
                        :base-url="url"
                        icon="book"
                        header="Dictionary"
                        :link="`/${config.nouns.route}`"
                        :counts="[
                            { count: stats.locales[locale].nouns.approved },
                            { name: 'awaiting', count: stats.locales[locale].nouns.awaiting, warning: 1, danger: 16 },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="stats && config.inclusive && config.inclusive.enabled && $isGranted('inclusive', locale) && (stats.locales[locale].inclusive.approved > 0 || stats.locales[locale].inclusive.awaiting > 0)"
                        v-show="!filterAttention || stats.locales[locale].inclusive.awaiting"
                        :base-url="url"
                        icon="book-heart"
                        header="Inclusive"
                        :link="`/${config.inclusive.route}`"
                        :counts="[
                            { count: stats.locales[locale].inclusive.approved },
                            { name: 'awaiting', count: stats.locales[locale].inclusive.awaiting, warning: 1, danger: 16 },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="stats && config.terminology && config.terminology.enabled && $isGranted('terms', locale) && (stats.locales[locale].terms.approved > 0 || stats.locales[locale].terms.awaiting > 0)"
                        v-show="!filterAttention || stats.locales[locale].terms.awaiting"
                        :base-url="url"
                        icon="flag"
                        header="Terminology"
                        :link="`/${config.terminology.route}`"
                        :counts="[
                            { count: stats.locales[locale].terms.approved },
                            { name: 'awaiting', count: stats.locales[locale].terms.awaiting, warning: 1, danger: 16 },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="stats && config.sources && config.sources.enabled && $isGranted('sources', locale) && (stats.locales[locale].sources.approved > 0 || stats.locales[locale].sources.awaiting > 0)"
                        v-show="!filterAttention || stats.locales[locale].sources.awaiting"
                        :base-url="url"
                        icon="books"
                        header="Sources"
                        :link="`/${config.sources.route}`"
                        :counts="[
                            { count: stats.locales[locale].sources.approved },
                            { name: 'awaiting', count: stats.locales[locale].sources.awaiting, warning: 1, danger: 16 },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="stats && config.names && config.names.enabled && $isGranted('names', locale) && (stats.locales[locale].names.approved > 0 || stats.locales[locale].names.awaiting > 0)"
                        v-show="!filterAttention || stats.locales[locale].names.awaiting"
                        :base-url="url"
                        icon="signature"
                        header="Names"
                        :link="`/${config.names.route}`"
                        :counts="[
                            { count: stats.locales[locale].names.approved },
                            { name: 'awaiting', count: stats.locales[locale].names.awaiting, warning: 1, danger: 16 },
                        ]"
                    />
                    <AdminDashboardCard
                        v-if="config.links.enabled && config.links.blog"
                        v-show="!filterAttention"
                        :base-url="url"
                        icon="pen-nib"
                        header="Blog"
                    >
                        <nuxt-link :to="{ name: 'admin-blog-editor' }" class="btn btn-sm btn-secondary text-white">Editor</nuxt-link>
                    </AdminDashboardCard>
                    <AdminDashboardCard
                        v-if="stats && $isGranted('translations', locale) && (stats.locales[locale].translations.missing > 0 || stats.locales[locale].translations.awaitingApproval > 0) || stats && $isGranted('code', locale) && stats.locales[locale].translations.awaitingMerge > 0"
                        v-show="!filterAttention || stats.locales[locale].translations.missing || stats.locales[locale].translations.awaitingApproval || stats?.locales[locale].translations.awaitingMerge"
                        :base-url="url"
                        icon="language"
                        header="Translations"
                        :counts="[
                            {
                                name: 'missing',
                                link: '/admin/translations/missing',
                                count: stats.locales[locale].translations.missing,
                                warning: 1,
                                danger: 16,
                                enabled: $isGranted('translations', locale),
                            },
                            {
                                name: 'proposed',
                                link: '/admin/translations/awaiting',
                                count: stats.locales[locale].translations.awaitingApproval,
                                warning: 1,
                                danger: 16,
                                enabled: $isGranted('translations', locale),
                            },
                            {
                                name: 'not merged',
                                link: '/admin/translations/awaiting',
                                count: stats.locales[locale].translations.awaitingMerge,
                                warning: 1,
                                danger: 16,
                                enabled: $isGranted('code', locale),
                            },
                        ]"
                    />
                </div>
            </template>
        </div>
    </Page>
</template>
