<template>
    <Page>
        <NotFound v-if="!$isGranted('users') && !$isGranted('community')" />
        <div v-else>
            <p>
                <nuxt-link to="/admin">
                    <Icon v="user-cog" />
                    <T>admin.header</T>
                </nuxt-link>
            </p>
            <h2>
                <Icon v="user-cog" />
                Users
            </h2>

            <section>
                <details class="border mb-3" @click="showUsers = true">
                    <summary class="bg-light p-3">
                        <Icon v="users" />
                        Users
                        ({{ stats._.users }} overall, {{ stats._.admins }} admins)
                    </summary>
                    <div v-if="showUsers" class="border-top">
                        <div class="input-group mt-4">
                            <input v-model="userFilter" class="form-control" :placeholder="$t('crud.filterLong')">
                            <button
                                :class="['btn', adminsFilter ? 'btn-secondary' : 'btn-outline-secondary']"
                                @click="adminsFilter = !adminsFilter"
                            >
                                Only admins
                            </button>
                            <button
                                :class="['btn', localeFilter ? 'btn-secondary' : 'btn-outline-secondary']"
                                @click="localeFilter = !localeFilter"
                            >
                                Only this version
                            </button>
                        </div>
                        <ServerTable
                            endpoint="/api/admin/users"
                            :query="{ filter: userFilterDelayed || undefined, localeFilter: localeFilter || undefined, adminsFilter: adminsFilter || undefined }"
                            :columns="5"
                            count
                        >
                            <template #header>
                                <th class="text-nowrap">
                                    <T>admin.user.user</T>
                                </th>
                                <th class="text-nowrap">
                                    <T>admin.user.createdAt</T>
                                </th>
                                <th class="text-nowrap">
                                    <T>admin.user.email</T>
                                </th>
                                <th class="text-nowrap">
                                    <T>admin.user.roles</T>
                                </th>
                                <th class="text-nowrap">
                                    <T>admin.user.profiles</T>
                                </th>
                            </template>

                            <template #row="s">
                                <td>
                                    <a :href="`https://pronouns.page/@${s.el.username}`">@{{ s.el.username }}</a>
                                    <a v-if="$isGranted('*') || $isGranted('impersonate')" href="#" class="badge bg-primary text-white" @click.prevent="impersonate(s.el.email)"><Icon v="user-secret" /></a>
                                    <nuxt-link v-if="$isGranted('*')" :to="`/admin/audit-log/${s.el.username}/${s.el.id}`" class="badge bg-primary text-white">
                                        <Icon v="file-search" />
                                    </nuxt-link>
                                    <a v-if="$isGranted('*') || $isGranted('community')" href="#" class="badge bg-danger text-white" @click.prevent="erasure(s.el.id, s.el.email)"><Icon v="truck-plow" /></a>
                                </td>
                                <td>
                                    {{ $datetime($ulidTime(s.el.id)) }}
                                </td>
                                <td>
                                    <p>
                                        <a :href="`mailto:${s.el.email}`" target="_blank" rel="noopener">
                                            {{ s.el.email }}
                                        </a>
                                    </p>
                                <!--
                                <ul v-if="s.el.socialConnections.length" class="list-inline">
                                    <li v-for="conn in s.el.socialConnections" class="list-inline-item">
                                        <Icon :v="socialProviders[conn].icon || conn" set="b"/>
                                    </li>
                                </ul>
                                -->
                                </td>
                                <td>
                                    <Roles :user="s.el" />
                                </td>
                                <td>
                                    <ul class="list-unstyled">
                                        <template v-for="locale in s.el.profiles">
                                            <li v-if="$locales[locale]" :key="locale">
                                                <LocaleLink :link="`/@${s.el.username}`" :locale="locale">
                                                    {{ $locales[locale].name }}
                                                </LocaleLink>
                                            </li>
                                        </template>
                                    </ul>
                                </td>
                            </template>
                        </ServerTable>
                    </div>
                </details>
            </section>

            <section>
                <ChartSet name="users" :data="chart" init="cumulative" />
            </section>

            <section>
                <Chart
                    label="number of profiles by locale"
                    :data="profilesByLocale"
                    type="bar"
                    :options="{
                        indexAxis: 'y',
                        responsive: true,
                        interaction: {
                            intersect: false,
                            mode: 'y',
                        },
                    }"
                />
            </section>
        </div>
    </Page>
</template>

<script>
import { longtimeCookieSetting } from '~/src/cookieSettings.ts';
import { useNuxtApp } from 'nuxt/app';
import useSimpleHead from '~/composables/useSimpleHead.ts';
import { socialProviders } from '~/src/socialProviders.ts';
import useConfig from '~/composables/useConfig.ts';
import useDialogue from '~/composables/useDialogue.ts';

export default {
    async setup() {
        const { $translator: translator } = useNuxtApp();
        const dialogue = useDialogue();
        useSimpleHead({
            title: `${translator.translate('admin.header')} • Users`,
        }, translator);

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


        const stats = useFetch('/api/admin/stats');
        const chart = useFetch('/api/admin/stats/users-chart/_');
        await Promise.all([stats, chart]);

        return {
            config: useConfig(),
            dialogue,
            tokenCookie,
            impersonatorCookie,
            stats: stats.data.value,
            chart: chart.data.value,
        };
    },
    data() {
        return {
            socialProviders,
            showUsers: false,
            userFilter: '',
            userFilterDelayed: '',
            userFilterDelayHandle: undefined,
            localeFilter: true,
            adminsFilter: false,
        };
    },
    computed: {
        profilesByLocale() {
            const r = {};

            Object.entries(this.stats)
                .filter(([locale, _localeStats]) => locale !== '_' && locale !== 'calculatedAt')
                .sort(([_aLocale, aLocaleStats], [_bLocale, bLocaleStats]) => bLocaleStats.users - aLocaleStats.users)
                .forEach(([locale, localeStats]) => {
                    r[locale] = localeStats.users;
                });

            return r;
        },
    },
    watch: {
        userFilter() {
            if (this.userFilterDelayHandle !== undefined) {
                clearInterval(this.userFilterDelayHandle);
            }

            this.userFilterDelayHandle = setTimeout(() => {
                this.userFilterDelayed = this.userFilter;
            }, 750);
        },
    },
    methods: {
        async impersonate(email) {
            const { token } = await this.$fetch(`/api/admin/impersonate/${encodeURIComponent(email)}`);
            this.impersonatorCookie = this.tokenCookie;
            this.tokenCookie = token;
            await this.$router.push(`/${this.config.user.route}`);
            setTimeout(() => window.location.reload(), 500);
        },
        async erasure(id, email) {
            await this.dialogue.confirm(`Are you sure you want to remove this account (${email})? ` +
                'This should only be done in two cases: ' +
                'an explicit GPDR request directly from the user, ' +
                'or having proof that owner is not yet 13 years old.', 'danger');

            if (await $fetch(`/api/user/data-erasure/${id}`, { method: 'POST' })) {
                await this.dialogue.alert(`Account ${email} removed successfully`, 'success');
            } else {
                await this.dialogue.alert(this.$t('error.generic', 'danger'));
            }
        },
    },
};
</script>
