<script setup lang="ts">
import { LazyHydrationWrapper } from 'vue3-lazy-hydration';

import type { Source } from '~/src/classes.ts';
import { pronounLibrary } from '~/src/data.ts';

const props = defineProps<{
    source: Source;
    manage?: boolean;
}>();

const emit = defineEmits<{
    'edit-source': [Source];
}>();

const { $translator: translator } = useNuxtApp();

const config = useConfig();
const dialogue = useDialogue();

const deleted = ref(false);
const versionsShown = ref(false);
const showSpoiler = ref(false);

const approve = async () => {
    await dialogue.postWithAlertOnError(`/api/sources/approve/${props.source.id}`);
    props.source.approved = true;
    props.source.base_id = null;
};
const hide = async () => {
    await dialogue.postWithAlertOnError(`/api/sources/hide/${props.source.id}`);
    props.source.approved = false;
};
const remove = async () => {
    await dialogue.confirm(translator.translate('crud.removeConfirm'), 'danger');

    await dialogue.postWithAlertOnError(`/api/sources/remove/${props.source.id}`);
    deleted.value = true;
};

const addMarks = (t: string) => {
    return t.replace(/\[\[/g, '<mark>').replace(/]]/g, '</mark>');
};
</script>

<template>
    <LazyHydrationWrapper when-visible>
        <div v-if="!deleted" class="my-2 clearfix">
            <h3 class="h6">
                <Icon :v="source.icon()" />
                <strong><Spelling v-if="source.author" :text="source.author.replace('^', '')" /><span v-if="source.author"> – </span><em><a v-if="source.link" :href="source.link" target="_blank" rel="noopener"><Spelling :text="addMarks(source.title)" /></a><Spelling v-else :text="addMarks(source.title)" /></em></strong><template v-if="source.extra">
                    (<Spelling :text="source.extra" />)
                </template>, {{ source.year }}<template v-if="source.comment">
                    ; <Spelling :text="source.comment" />
                </template>
            </h3>
            <ul v-if="manage && $isGranted('sources')" class="list-inline">
                <li v-if="!source.approved" class="list-inline-item">
                    <span class="badge bg-danger">
                        <Icon v="map-marker-question" />
                        <T>nouns.pending</T>
                    </span>
                </li>
                <li v-if="source.submitter" class="list-inline-item">
                    <nuxt-link :to="`/@${source.submitter}`" class="badge bg-light text-dark border btn-sm m-1">
                        <Icon v="user" />
                        <span class="btn-label">
                            <T>crud.author</T><T>quotation.colon</T>
                            @{{ source.submitter }}
                        </span>
                    </nuxt-link>
                </li>
                <li v-if="!source.approved" class="list-inline-item">
                    <a href="#" class="badge bg-success btn-sm m-1" @click.prevent="approve()">
                        <Icon v="check" />
                        <span class="btn-label"><T>crud.approve</T></span>
                    </a>
                </li>
                <li v-else class="list-inline-item">
                    <a href="#" class="badge bg-light text-dark border border-secondary btn-sm m-1" @click.prevent="hide()">
                        <Icon v="times" />
                        <span class="btn-label"><T>crud.hide</T></span>
                    </a>
                </li>
                <li class="list-inline-item">
                    <a href="#" class="badge bg-light text-dark border border-danger btn-sm m-1" @click.prevent="remove()">
                        <Icon v="trash" />
                        <span class="btn-label"><T>crud.remove</T></span>
                    </a>
                </li>
                <li class="list-inline-item">
                    <a href="#" class="badge bg-light text-dark border border-primary btn-sm m-1" @click.prevent="emit('edit-source', source)">
                        <Icon v="pen" />
                        <span class="btn-label">
                            <T>crud.edit</T>
                        </span>
                    </a>
                </li>
                <li class="list-inline-item">
                    <span
                        v-for="p in source.pronouns"
                        :class="['badge', pronounLibrary.isCanonical(p) || (config.sources.extraTypes || []).includes(p) ? 'bg-success' : 'bg-danger', 'm-1']"
                    >
                        <Spelling :text="p" />
                    </span>
                </li>
                <li v-if="source.key" class="list-inline-item">
                    <span class="badge bg-primary text-white">
                        <T>sources.submit.key</T><T>quotation.colon</T> {{ source.key }}
                    </span>
                </li>
            </ul>
            <div v-if="source.spoiler && !showSpoiler" class="py-3">
                <button type="button" class="btn btn-outline-primary" @click="showSpoiler = true">
                    <Icon v="eye-slash" />
                    <T>sources.submit.spoiler</T>
                </button>
            </div>
            <div v-else>
                <div v-if="source.images.length" class="source-images">
                    <ImageThumb v-for="image in source.images" :id="image" :key="image" class="m-2" size="8rem" />
                </div>
                <ul v-if="source.fragments.length">
                    <li v-for="fragment in source.fragments" class="text-break">
                        <T>quotation.start</T><Spelling :text="addMarks(fragment.replace(/\n/g, '<br/>'))" /><T>quotation.end</T>
                    </li>
                </ul>
            </div>
            <div v-if="source.versions.length" class="my-3">
                <p>
                    <button :class="['btn', versionsShown ? 'btn-primary' : 'btn-outline-primary', 'btn-sm']" @click="versionsShown = !versionsShown">
                        <Icon v="language" />
                        <T>sources.otherVersions</T>
                        <Icon :v="versionsShown ? 'caret-up' : 'caret-down'" />
                    </button>
                </p>
                <ul v-if="versionsShown" class="clearfix">
                    <template v-for="version in source.versions">
                        <li v-if="$locales[version.locale] !== undefined">
                            <h4 class="h6 mb-2">
                                <strong>
                                    <a
                                        :href="`${$locales[version.locale].url}/${version.pronouns[0]}`"
                                        target="_blank"
                                        rel="noopener"
                                    >{{ $locales[version.locale].name }}</a>:
                                </strong>
                            </h4>
                            <SourceItem :source="version" />
                        </li>
                    </template>
                </ul>
            </div>
        </div>
    </LazyHydrationWrapper>
</template>

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

    @include media-breakpoint-down('sm', $grid-breakpoints) {
        .source-images {
            text-align: center;
        }
    }

    @include media-breakpoint-up('md', $grid-breakpoints) {
        .source-images {
            float: right;
            max-width: 18rem;
        }
    }
</style>
