<script setup lang="ts">
import type { ComponentExposed } from 'vue-component-type-helpers';

import type InclusiveSubmitForm from '~/components/InclusiveSubmitForm.vue';
import type Table from '~/components/Table.vue';
import { InclusiveEntry } from '~/src/classes.ts';
import type { InclusiveEntryRaw } from '~/src/classes.ts';
import { buildDict, clearUrl, clearLinkedText } from '~/src/helpers.ts';

const props = defineProps<{
    load?: boolean;
}>();

const { $translator: translator } = useNuxtApp();
const config = useConfig();
const filter = useFilterWithCategory();

const dictionarytable = useTemplateRef<ComponentExposed<typeof Table>>('dictionarytable');
watch(filter, () => {
    if (dictionarytable.value) {
        dictionarytable.value.reset();
        dictionarytable.value.focus();
    }
});
const form = useTemplateRef<InstanceType<typeof InclusiveSubmitForm>>('form');

const entriesAsyncData = useAsyncData(async () => {
    const entriesRaw = await $fetch<InclusiveEntryRaw[]>('/api/inclusive');

    return buildDict(function* () {
        const sorted = entriesRaw.sort((a, b) => {
            if (a.approved && !b.approved) {
                return 1;
            }
            if (!a.approved && b.approved) {
                return -1;
            }
            return clearLinkedText(a.insteadOf.toLowerCase()).localeCompare(clearLinkedText(b.insteadOf.toLowerCase()));
        });
        for (const w of sorted) {
            yield [w.id, new InclusiveEntry(w)];
        }
    });
}, {
    immediate: false,
});

onMounted(async () => {
    if (props.load) {
        await entriesAsyncData.execute();
    }
});
const reloadEntries = async (): Promise<void> => {
    await entriesAsyncData.execute();
    form.value?.focus(false);
};

const entries = computed(() => {
    if (entriesAsyncData.status.value !== 'success') {
        return {};
    }
    return entriesAsyncData.data.value!;
});
const visibleEntries = computed(() => {
    return Object.values(entries.value).filter((entry) => entry.matches(filter.value));
});

const dialogue = useDialogue();
const edit = (entry: InclusiveEntry) => {
    form.value?.edit(entry);
};
const approve = async (entry: InclusiveEntry): Promise<void> => {
    await dialogue.postWithAlertOnError(`/api/inclusive/approve/${entry.id}`);
    if (entry.base) {
        delete entries.value[entry.base];
    }
    entry.approved = true;
    entry.base = null;
};
const hide = async (entry: InclusiveEntry): Promise<void> => {
    await dialogue.postWithAlertOnError(`/api/inclusive/hide/${entry.id}`);
    entry.approved = false;
};
const remove = async (entry: InclusiveEntry): Promise<void> => {
    await dialogue.confirm(translator.translate('crud.removeConfirm'), 'danger');

    await dialogue.postWithAlertOnError(`/api/inclusive/remove/${entry.id}`);
    delete entries.value[entry.id];
};
</script>

<template>
    <Loading :value="entriesAsyncData.data.value">
        <ModerationSection
            v-model="filter.moderation"
            kind="inclusive"
            :moderation-filters="['unapproved', 'no category']"
            :entries="Object.values(entries)"
        />

        <FilterBar
            v-model="filter.text"
            v-model:category="filter.category"
            :categories="config.inclusive.categories"
            submit-button
            @submit-clicked="form?.focus()"
        />

        <Table ref="dictionarytable" :data="visibleEntries" :marked="(el) => !el.approved" fixed>
            <template #header>
                <div class="bold text-nowrap">
                    <Icon v="comment-times" />
                    <T>inclusive.insteadOf</T>
                </div>
                <div class="bold text-nowrap">
                    <Icon v="comment-check" />
                    <T>inclusive.say</T>
                </div>
                <div class="d-none d-md-block bold text-nowrap">
                    <Icon v="comment-dots" />
                    <T>inclusive.because</T>
                </div>
            </template>

            <template #row="s">
                <template v-if="s">
                    <div style="grid-area: insteadOf">
                        <ul class="mb-0 ps-4">
                            <li v-for="(w, i) in s.el.insteadOf" :key="i" class="text-strike">
                                <LinkedText :text="w" noicons />
                            </li>
                        </ul>

                        <div v-if="s.el.base && entries[s.el.base]" class="small">
                            <p><strong><T>nouns.edited</T><T>quotation.colon</T></strong></p>

                            <Diff switchable>
                                <template #before>
                                    <ul class="mb-0 ps-4">
                                        <li v-for="w in entries[s.el.base].insteadOf" :key="w" class="text-strike">
                                            <LinkedText :text="w" noicons />
                                        </li>
                                    </ul>
                                </template>
                                <template #after>
                                    <ul class="mb-0 ps-4">
                                        <li v-for="(w, i) in s.el.insteadOf" :key="i" class="text-strike">
                                            <LinkedText :text="w" noicons />
                                        </li>
                                    </ul>
                                </template>
                            </Diff>
                        </div>
                    </div>
                    <div style="grid-area: say">
                        <ul class="mb-0 ps-4">
                            <li v-for="(w, i) in s.el.say" :key="i">
                                <LinkedText :text="w" noicons />
                            </li>
                        </ul>

                        <small v-if="s.el.base && entries[s.el.base]">
                            <p><strong><T>nouns.edited</T><T>quotation.colon</T></strong></p>

                            <Diff switchable>
                                <template #before>
                                    <ul class="mb-0 ps-4">
                                        <li v-for="(w, i) in entries[s.el.base].say" :key="i">
                                            <LinkedText :text="w" noicons />
                                        </li>
                                    </ul>
                                </template>
                                <template #after>
                                    <ul class="mb-0 ps-4">
                                        <li v-for="(w, i) in s.el.say" :key="i">
                                            <LinkedText :text="w" noicons />
                                        </li>
                                    </ul>
                                </template>
                            </Diff>
                        </small>
                    </div>
                    <div style="grid-area: because">
                        <p v-for="(p, i) in s.el.because.split('\n\n')" :key="i">
                            <LinkedText :text="p" noicons />
                        </p>

                        <ul class="list-unstyled small">
                            <li v-for="(link, i) in s.el.links" :key="i">
                                <a :href="link" target="_blank" rel="noopener">
                                    <Icon v="external-link" />
                                    {{ clearUrl(link) }}
                                </a>
                            </li>
                        </ul>

                        <small v-if="s.el.base && entries[s.el.base]">
                            <p><strong><T>nouns.edited</T><T>quotation.colon</T></strong></p>

                            <Diff switchable>
                                <template #before>
                                    <p v-for="(p, i) in entries[s.el.base].because.split('\n\n')" :key="i">
                                        <LinkedText :text="p" noicons />
                                    </p>

                                    <ul class="list-unstyled small">
                                        <li v-for="(link, i) in entries[s.el.base].links" :key="i">
                                            <a :href="link" target="_blank" rel="noopener">
                                                <Icon v="external-link" />
                                                {{ clearUrl(link) }}
                                            </a>
                                        </li>
                                    </ul>
                                </template>
                                <template #after>
                                    <p v-for="(p, i) in s.el.because.split('\n\n')" :key="i">
                                        <LinkedText :text="p" noicons />
                                    </p>

                                    <ul class="list-unstyled small">
                                        <li v-for="(link, i) in s.el.links" :key="i">
                                            <a :href="link" target="_blank" rel="noopener">
                                                <Icon v="external-link" />
                                                {{ clearUrl(link) }}
                                            </a>
                                        </li>
                                    </ul>
                                </template>
                            </Diff>
                        </small>
                    </div>
                    <div
                        v-if="s.el.clarification"
                        class="alert alert-warning mb-0 px-2 py-1 small"
                        style="grid-area: clarification"
                    >
                        <LinkedText :text="s.el.clarification" />
                    </div>
                    <div style="grid-area: categories">
                        <ul class="list-inline mb-0" style="grid-area: categories">
                            <li v-for="category in s.el.categories" :key="category" class="list-inline-item">
                                <a
                                    :href="`#:${category}`"
                                    class="badge bg-primary text-white"
                                    @click.prevent="filter.category = category"
                                >
                                    {{ category }}
                                </a>
                            </li>
                        </ul>

                        <div v-if="s.el.base && entries[s.el.base]" class="small">
                            <p><strong><T>nouns.edited</T><T>quotation.colon</T></strong></p>

                            <Diff switchable>
                                <template #before>
                                    <ul class="list-inline">
                                        <li
                                            v-for="category in entries[s.el.base].categories"
                                            :key="category"
                                            class="list-inline-item"
                                        >
                                            <span class="badge bg-primary text-white">
                                                {{ category }}
                                            </span>
                                        </li>
                                    </ul>
                                </template>
                                <template #after>
                                    <ul class="list-inline">
                                        <li
                                            v-for="category in s.el.categories"
                                            :key="category"
                                            class="list-inline-item"
                                        >
                                            <span class="badge bg-primary text-white">
                                                {{ category }}
                                            </span>
                                        </li>
                                    </ul>
                                </template>
                            </Diff>
                        </div>
                    </div>
                    <div style="grid-area: buttons">
                        <ul class="d-flex flex-wrap flex-md-column list-unstyled list-btn-concise mb-0">
                            <template v-if="$isGranted('inclusive')">
                                <li v-if="s.el.author" class="small">
                                    <nuxt-link :to="`/@${s.el.author}`" class="btn btn-concise btn-outline-dark btn-sm m-1">
                                        <Icon v="user" />
                                        <span class="btn-label">
                                            <T>crud.author</T><T>quotation.colon</T>
                                            @{{ s.el.author }}
                                        </span>
                                    </nuxt-link>
                                </li>
                                <li v-if="!s.el.approved">
                                    <button class="btn btn-concise btn-success btn-sm m-1" @click="approve(s.el)">
                                        <Icon v="check" />
                                        <span class="btn-label"><T>crud.approve</T></span>
                                    </button>
                                </li>
                                <li v-else @click="hide(s.el)">
                                    <button class="btn btn-concise btn-outline-secondary btn-sm m-1">
                                        <Icon v="times" />
                                        <span class="btn-label"><T>crud.hide</T></span>
                                    </button>
                                </li>
                                <li>
                                    <button class="btn btn-concise btn-outline-danger btn-sm m-1" @click="remove(s.el)">
                                        <Icon v="trash" />
                                        <span class="btn-label"><T>crud.remove</T></span>
                                    </button>
                                </li>
                            </template>
                            <li>
                                <button class="btn btn-concise btn-outline-primary btn-sm m-1" @click="edit(s.el)">
                                    <Icon v="pen" />
                                    <span class="btn-label">
                                        <T v-if="$isGranted('inclusive')">crud.edit</T>
                                        <T v-else>nouns.edit</T>
                                    </span>
                                </button>
                            </li>
                        </ul>
                    </div>
                </template>
            </template>

            <template #empty>
                <Icon v="search" />
                <T>nouns.empty</T>
            </template>
        </Table>

        <AdPlaceholder :phkey="['content-1', 'content-mobile-1']" />

        <Separator icon="plus" />

        <InclusiveSubmitForm ref="form" @submit="reloadEntries()" />
    </Loading>
</template>

<style scoped lang="scss">
    @import "assets/variables";

    :deep(.row-header) {
        grid-template-columns: 1fr 1fr;

        @include media-breakpoint-up('md', $grid-breakpoints) {
            grid-template-columns: 1fr 1fr 2.5fr 3em;
        }
    }

    :deep(.row-content) {
        grid:
            "insteadOf say"
            "because because"
            "clarification clarification"
            "categories categories"
            "buttons buttons"
            / 1fr 1fr;

        @include media-breakpoint-up('md', $grid-breakpoints) {
            grid:
                "insteadOf say because buttons"
                "clarification clarification because buttons"
                "categories categories because buttons" 1fr
                / 1fr 1fr 2.5fr 3em;
        }
    }
</style>
