<script setup>
import { useI18n } from 'vue-i18n';
import { ref, onMounted, inject, reactive, computed } from 'vue';

import VnSelect from 'src/components/common/VnSelect.vue';
import VnForm from 'src/components/common/VnForm.vue';
import VnInput from 'src/components/common/VnInput.vue';
import useNotify from 'src/composables/useNotify.js';

const jApi = inject('jApi');
const api = inject('api');
const { t } = useI18n();
const { notify } = useNotify();

const fileUploaderRef = ref(null);
const statusIcons = {
    uploading: 'cloud_upload',
    fulfilled: 'cloud_done',
    rejected: 'error',
    pending: 'add'
};
const formInitialData = reactive({
    schema: 'catalog',
    updateMatching: true
});
const imageCollections = ref([]);
const addedFiles = ref([]);

const isSubmitable = computed(() =>
    addedFiles.value.some(file => file.uploadStatus === 'pending')
);

const getImageCollections = async () => {
    try {
        imageCollections.value = await jApi.query(
            'SELECT name, `desc` FROM imageCollection ORDER BY `desc`'
        );
    } catch (error) {
        console.error('Error getting image collections:', error);
    }
};

const onSubmit = async data => {
    if (!addedFiles.value.length) {
        notify(t('noFilesToUpload'), 'warning');
        return;
    }
    const filteredFiles = addedFiles.value.filter(
        file => file.uploadStatus === 'pending'
    );
    const promises = filteredFiles.map((file, index) => {
        const fileIndex = filteredFiles[index].index;
        addedFiles.value[fileIndex].uploadStatus = 'uploading';

        const formData = new FormData();
        formData.append('updateMatching', data.updateMatching);
        formData.append('image', file.file);
        formData.append('name', file.name);
        formData.append('schema', data.schema);
        formData.append('srv', 'json:image/upload');
        return api({
            method: 'post',
            url: location.origin,
            data: formData,
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        });
    });

    const results = await Promise.allSettled(promises);
    results.forEach((result, index) => {
        const fileIndex = filteredFiles[index].index;
        addedFiles.value[fileIndex].uploadStatus = result.status;
    });

    const allSuccessful = results.every(
        result => result.status === 'fulfilled'
    );
    if (allSuccessful) {
        notify(t('uploadSuccess'), 'positive');
    } else {
        notify(t('uploadError'), 'negative');
    }
};

const onFilesAdded = files => {
    const initialFilesLength = addedFiles.value.length;
    files.forEach((file, index) => {
        const [name] = file.name.split('.');
        const fileData = {
            name,
            file,
            index: initialFilesLength + index,
            uploadStatus: 'pending'
        };
        addedFiles.value.push(fileData);
    });
};

const recalculateFilesIndexes = () => {
    addedFiles.value.forEach((_, index) => {
        addedFiles.value[index].index = index;
    });
};

const removeFile = (file, index) => {
    fileUploaderRef.value.removeFile(file);
    addedFiles.value.splice(index, 1);
    recalculateFilesIndexes();
};

const clearFiles = () => {
    fileUploaderRef.value.reset();
    addedFiles.value = [];
};

onMounted(async () => getImageCollections());
</script>

<template>
    <QPage class="vn-w-sm">
        <VnForm
            ref="vnFormRef"
            :defaultActions="false"
            :formInitialData="formInitialData"
            separationBetweenInputs="md"
            showBottomActions
        >
            <template #form="{ data }">
                <VnSelect
                    v-model="data.schema"
                    :label="t('collection')"
                    option-label="desc"
                    option-value="name"
                    :options="imageCollections"
                />
                <QUploader
                    ref="fileUploaderRef"
                    :label="t('dropYourFiles')"
                    class="full-width"
                    square
                    flat
                    multiple
                    bordered
                    hide-upload-btn
                    @added="onFilesAdded"
                >
                    <template v-slot:list="scope">
                        <QList v-if="addedFiles.length" separator>
                            <QItem
                                v-for="(file, index) in scope.files"
                                :key="file.__key"
                                class="flex full-width row items-center justify-center"
                            >
                                <img
                                    :src="file.__img.src"
                                    style="width: 28px; height: 21px"
                                    class="q-mr-md"
                                />
                                <VnInput
                                    v-model="addedFiles[index].name"
                                    :clearable="false"
                                    dense
                                    class="full-width"
                                />
                                <QSpinner
                                    v-if="
                                        addedFiles[index].uploadStatus ===
                                        'uploading'
                                    "
                                    color="primary"
                                    size="2em"
                                    :thickness="1"
                                />
                                <QIcon
                                    v-else-if="
                                        addedFiles[index].uploadStatus &&
                                        addedFiles[index].uploadStatus !==
                                            'uploading'
                                    "
                                    :name="
                                        statusIcons[
                                            addedFiles[index].uploadStatus
                                        ]
                                    "
                                    size="sm"
                                />
                                <QBtn
                                    v-if="
                                        addedFiles[index].uploadStatus !==
                                        'uploading'
                                    "
                                    class="gt-xs"
                                    size="md"
                                    flat
                                    dense
                                    round
                                    icon="delete"
                                    @click="removeFile(file, index)"
                                />
                            </QItem>
                        </QList>
                    </template>
                </QUploader>
                <QCheckbox
                    v-model="data.updateMatching"
                    :label="t('updateMatching')"
                />
            </template>
            <template #actions="{ data }">
                <QBtn
                    :label="t('clearAll')"
                    rounded
                    no-caps
                    flat
                    @click="clearFiles()"
                />
                <QBtn
                    :label="t('uploadFiles')"
                    rounded
                    no-caps
                    flat
                    :disable="!isSubmitable"
                    @click="onSubmit(data)"
                />
            </template>
        </VnForm>
    </QPage>
</template>

<i18n lang="yaml">
en-US:
    collection: Collection
    updateMatching: Update items with matching id
    dropYourFiles: Click or drop files here
    clearAll: Clear all
    uploadFiles: Upload files
    uploadSuccess: Upload finished successfully
    uploadError: Some errors happened on upload
    noFilesToUpload: There are no files to upload
es-ES:
    collection: Colección
    updateMatching: Actualizar artículos con id coincidente
    dropYourFiles: Pulsa o suelta los archivos aquí
    clearAll: Limpiar todo
    uploadFiles: Subir archivos
    uploadSuccess: Imágenes subidas correctamente
    uploadError: Ocurrieron errores al subir alguna de las imágenes
    noFilesToUpload: No se han seleccionado archivos para subir
ca-ES:
    collection: Col·lecció
    updateMatching: Actualitzar els elements amb id coincident
    dropYourFiles: Prem o deixa anar els arxius aquí
    clearAll: Netejar tot
    uploadFiles: Pujar arxius
    uploadSuccess: Imatges pujades correctament
    uploadError: Van ocórrer errors en pujar alguna de les imatges
    noFilesToUpload: No s'ha seleccionat arxius per pujar
fr-FR:
    collection: Collection
    updateMatching: Mettre à jour les éléments avec l'identifiant correspondant
    dropYourFiles: Cliquez ici ou déposer des fichiers
    clearAll: Tout effacer
    uploadFiles: Upload Files
    uploadSuccess: Les images téléchargées correctement
    uploadError: Des erreurs sont survenues lors du téléchargement des images
    noFilesToUpload: Aucun fichier sélectionné pour télécharger
pt-PT:
    collection: Coleção
    updateMatching: Atualizar itens com id correspondente
    dropYourFiles: Clique ou solte arquivos aqui
    clearAll: Limpar tudo
    uploadFiles: Fazer upload de arquivos
    uploadSuccess: Upload concluído com sucesso
    uploadError: Ocorreram erros ao subir alguma das imagens
    noFilesToUpload: Não há arquivos selecionados para upload
</i18n>
