<script setup lang="ts">
import { loadPronounLibrary } from '../src/data.ts';

import useConfig from '~/composables/useConfig.ts';
import useDialogue from '~/composables/useDialogue.ts';
import { Source } from '~/src/classes.ts';

type FormData = Pick<Source, 'pronouns' | 'type' | 'author' | 'title' | 'extra' | 'year' | 'fragments' | 'comment'
    | 'images' | 'link' | 'spoiler' | 'key'> & { base: string | null };

const config = useConfig();

const form = ref<FormData>({
    pronouns: [''],
    type: '',
    author: '',
    title: '',
    extra: '',
    year: null,
    fragments: [],
    comment: '',
    images: [],
    link: '',
    spoiler: false,
    key: null,
    base: null,
});

const submitting = ref(false);
const afterSubmit = ref(false);

const dialogue = useDialogue();
const submit = async (): Promise<void> => {
    submitting.value = true;
    try {
        await dialogue.postWithAlertOnError('/api/sources/submit', form.value);

        afterSubmit.value = true;
        form.value = {
            pronouns: [''],
            type: '',
            author: '',
            title: '',
            extra: '',
            year: null,
            fragments: [],
            comment: '',
            images: [],
            link: '',
            spoiler: false,
            key: null,
            base: null,
        };
    } finally {
        submitting.value = false;
    }
};

const section = useTemplateRef('section');
const edit = (source: Source): void => {
    form.value = {
        pronouns: source.pronouns,
        type: source.type,
        author: source.author,
        title: source.title,
        extra: source.extra,
        year: source.year,
        fragments: source.fragments,
        comment: source.comment,
        images: source.images,
        link: source.link,
        spoiler: source.spoiler,
        key: source.key,
        base: source.id,
    };
    afterSubmit.value = false;
    section.value?.scrollIntoView();
};

defineExpose({ edit });

const pronounLibrary = await loadPronounLibrary(config);
const { data: keys } = await useFetch('/api/sources/keys', { lazy: true, default: () => ({}) });
</script>

<template>
    <div ref="section" class="card">
        <div class="card-header">
            <Icon v="plus-circle" />
            <T>sources.submit.header</T>
        </div>
        <div v-if="$user()" class="card-body">
            <div v-if="afterSubmit" class="alert alert-success text-center">
                <p>
                    <T>sources.submit.thanks</T>
                </p>
                <p>
                    <button type="button" class="btn btn-success" @click="afterSubmit = false">
                        <Icon v="plus" />
                        <T>sources.submit.another</T>
                    </button>
                </p>
            </div>
            <form v-else @submit.prevent="submit">
                <div class="form-group">
                    <label for="type" class="required"><T>sources.submit.type</T></label>
                    <select id="type" v-model="form.type" class="form-control" required>
                        <option value=""></option>
                        <template v-for="t in Object.keys(Source.TYPES)">
                            <option v-if="t !== ''" :key="t" :value="t">
                                {{ $t(`sources.type.${t}`) }}
                            </option>
                        </template>
                    </select>
                </div>
                <div class="form-group">
                    <label for="author"><T>sources.submit.author</T></label>
                    <input
                        id="author"
                        v-model="form.author"
                        type="text"
                        class="form-control"
                        maxlength="255"
                    >
                </div>
                <div class="form-group">
                    <label for="title" class="required"><T>sources.submit.title</T></label>
                    <input
                        id="title"
                        v-model="form.title"
                        type="text"
                        class="form-control"
                        required
                        maxlength="255"
                    >
                </div>
                <div class="form-group">
                    <label for="extra"><T>sources.submit.extra</T></label>
                    <input
                        id="extra"
                        v-model="form.extra"
                        type="text"
                        class="form-control"
                        maxlength="255"
                    >
                </div>
                <div class="form-group">
                    <label for="year"><T>sources.submit.year</T></label>
                    <input
                        id="year"
                        v-model="form.year"
                        type="number"
                        class="form-control"
                        min="0"
                        max="2100"
                    >
                </div>
                <div class="form-group">
                    <label for="fragments"><T>sources.submit.fragments</T></label>
                    <p class="small text-muted mb-0">
                        <T>sources.submit.fragmentsInfo</T>
                    </p>
                    <ListInput id="fragments" v-slot="s" v-model="form.fragments">
                        <textarea v-model="s.val" class="form-control" rows="3" required @keyup="s.update(s.val)"></textarea>
                    </ListInput>
                </div>
                <div class="form-group">
                    <div class="form-check form-switch my-2">
                        <label>
                            <input v-model="form.spoiler" class="form-check-input" type="checkbox" role="switch">
                            <T>sources.submit.spoiler</T>
                        </label>
                    </div>
                </div>
                <div class="form-group">
                    <label for="pronouns" class="required"><T>sources.submit.pronouns</T></label>
                    <p class="small text-muted mb-0">
                        <T>sources.submit.pronounsInfo</T>
                    </p>
                    <ListInput v-model="form.pronouns">
                        <template #default="s">
                            <input
                                v-model="s.val"
                                type="text"
                                class="form-control"
                                required
                                maxlength="24"
                                @keyup="s.update(s.val)"
                            >
                        </template>
                        <template #validation="s">
                            <p
                                v-if="s.val && !pronounLibrary.isCanonical(s.val) && !(config.sources.extraTypes || []).includes(s.val)"
                                class="small text-danger"
                            >
                                <Icon v="exclamation-triangle" />
                                <span class="ml-1"><T>profile.pronounsNotFound</T></span>
                            </p>
                        </template>
                    </ListInput>
                </div>
                <div class="form-group">
                    <label for="comment"><T>sources.submit.comment</T></label>
                    <input
                        id="comment"
                        v-model="form.comment"
                        type="text"
                        class="form-control"
                        maxlength="255"
                    >
                </div>
                <div class="form-group">
                    <label for="link"><T>sources.submit.link</T></label>
                    <input
                        id="link"
                        v-model="form.link"
                        type="url"
                        class="form-control"
                        maxlength="255"
                    >
                </div>
                <div class="form-group">
                    <label><T>sources.submit.images</T></label>
                    <ImageWidget v-model="form.images" multiple sizes="big,thumb" />
                </div>
                <div v-if="$isGranted('sources')" class="form-group">
                    <label for="key"><T>sources.submit.key</T></label>
                    <AutocompleteSelect
                        id="key"
                        v-model="form.key"
                        maxlength="255"
                        :options="keys"
                        freeform
                    />
                    <p class="small text-muted">
                        <T>sources.submit.keyInfo</T>
                        <T>sources.submit.keyInfoConvention</T>
                    </p>
                </div>
                <div v-if="form.base" class="alert alert-info">
                    <Icon v="info-circle" />
                    <T>nouns.editing</T>
                    <button type="button" class="btn btn-sm float-end" @click="form.base = null">
                        <Icon v="times" />
                    </button>
                </div>
                <button type="submit" class="btn btn-success w-100" :disabled="submitting">
                    <Icon v="plus-circle" />
                    <T>sources.submit.action</T>
                </button>
                <p class="small text-muted mt-1">
                    <T>sources.submit.moderation</T>
                </p>
            </form>
        </div>
        <div v-else class="card-body py-5 text-center">
            <T>crud.loginRequired</T>
        </div>
    </div>
</template>
