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

import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';

import Croppie from 'croppie/croppie';
import 'croppie/croppie.css';
import useNotify from 'src/composables/useNotify.js';
import axios from 'axios';

const emit = defineEmits(['closeForm', 'onPhotoUploaded']);

const props = defineProps({
    id: {
        type: String,
        default: '',
    },
    collection: {
        type: String,
        default: '',
    },
});

const { t } = useI18n();
const { notify } = useNotify();

const uploadMethodsOptions = [
    { label: t('Select from computer'), value: 'computer' },
    { label: t('Import from external URL'), value: 'URL' },
];

const viewportTypes = [
    {
        code: 'normal',
        description: t('Normal'),
        viewport: {
            width: 400,
            height: 400,
        },
        output: {
            width: 1200,
            height: 1200,
        },
    },
    {
        code: 'panoramic',
        description: t('Panoramic'),
        viewport: {
            width: 675,
            height: 450,
        },
        output: {
            width: 1350,
            height: 900,
        },
    },
    {
        code: 'vertical',
        description: t('Vertical'),
        viewport: {
            width: 306.66,
            height: 533.33,
        },
        output: {
            width: 460,
            height: 800,
        },
    },
];

const uploadMethodSelected = ref('computer');
const viewPortTypeSelected = ref(viewportTypes[0]);
const inputFileRef = ref(null);
const allowedContentTypes = ref('');
const photoContainerRef = ref(null);
const editor = ref(null);
const newPhoto = reactive({
    id: props.id,
    collection: props.collection,
    file: null,
    url: null,
    blob: null,
});

const openInputFile = () => {
    inputFileRef.value.pickFiles();
};

const displayEditor = () => {
    const viewportType = viewPortTypeSelected.value;
    const viewport = viewportType.viewport;
    const boundaryWidth = viewport.width + 200;
    const boundaryHeight = viewport.height + 200;

    if (editor.value) editor.value.destroy();
    editor.value = new Croppie(photoContainerRef.value, {
        viewport: { width: viewport.width, height: viewport.height },
        boundary: { width: boundaryWidth, height: boundaryHeight },
        enableOrientation: true,
        showZoomer: true,
    });
};

const viewportSelection = computed({
    get() {
        return viewPortTypeSelected.value;
    },
    set(val) {
        viewPortTypeSelected.value = val;

        const hasFile = newPhoto.files || newPhoto.url;
        if (!val || !hasFile) return;

        let file;
        if (uploadMethodSelected.value == 'computer') file = newPhoto.files;
        else if (uploadMethodSelected.value == 'URL') file = newPhoto.url;

        updatePhotoPreview(file);
    },
});

const updatePhotoPreview = (value) => {
    if (value) {
        displayEditor();
        if (uploadMethodSelected.value == 'computer') {
            newPhoto.files = value;
            const reader = new FileReader();
            reader.onload = (e) => editor.value.bind({ url: e.target.result });
            reader.readAsDataURL(value);
        } else if (uploadMethodSelected.value == 'URL') {
            newPhoto.url = value;
            const img = new Image();
            img.crossOrigin = 'Anonymous';
            img.src = value;
            img.onload = () => editor.value.bind({ url: value });
            img.onerror = () => {
                notify(
                    t("This photo provider doesn't allow remote downloads"),
                    'negative'
                );
            };
        }
    }
};

const rotateLeft = () => {
    editor.value.rotate(90);
};

const rotateRight = () => {
    editor.value.rotate(-90);
};

const onUploadAccept = () => {
    try {
        if (!newPhoto.files && !newPhoto.url) {
            notify(t('Select an image'), 'negative');
            return;
        }

        const options = {
            type: 'blob',
        };

        editor.value
            .result(options)
            .then((result) => {
                const file = new File([result], newPhoto.files?.name || '');
                newPhoto.blob = file;
            })
            .then(() => makeRequest());
    } catch (err) {
        console.error('Error uploading image');
    }
};

const makeRequest = async () => {
    const formData = new FormData();
    const now = Date.vnNew();
    const timestamp = now.getTime();
    const fileName = `${newPhoto.files?.name}_${timestamp}`;
    formData.append('blob', newPhoto.blob, fileName);

    await axios.post('Images/upload', formData, {
        params: newPhoto,
        headers: {
            'Content-Type': 'multipart/form-data',
        },
    });

    emit('closeForm');
    emit('onPhotoUploaded');

    notify(t('globals.dataSaved'), 'positive');
};
</script>

<template>
    <FetchData
        ref="allowTypesRef"
        url="ImageContainers/allowedContentTypes"
        @on-fetch="(data) => (allowedContentTypes = data.join(', '))"
        auto-load
    />
    <QForm @submit="onUploadAccept()" class="all-pointer-events">
        <QCard class="q-pa-lg">
            <span ref="closeButton" class="close-icon" v-close-popup>
                <QIcon name="close" size="sm" />
            </span>
            <h1 class="title">{{ t('Edit photo') }}</h1>
            <div class="row q-gutter-lg">
                <div
                    v-show="newPhoto.files || newPhoto.url"
                    class="row q-gutter-lg items-center"
                >
                    <QIcon
                        name="rotate_left"
                        size="sm"
                        color="primary"
                        class="cursor-pointer"
                        @click="rotateLeft()"
                    >
                        <!-- <QTooltip class="no-pointer-events">
                            {{ t('Rotate left') }}
                        </QTooltip> -->
                    </QIcon>
                    <div>
                        <div ref="photoContainerRef" />
                    </div>
                    <QIcon
                        name="rotate_right"
                        size="sm"
                        color="primary"
                        class="cursor-pointer"
                        @click="rotateRight()"
                    >
                        <!-- <QTooltip class="no-pointer-events">
                            {{ t('Rotate right') }}
                        </QTooltip> -->
                    </QIcon>
                </div>

                <div class="column">
                    <VnRow class="row q-gutter-md q-mb-md">
                        <div class="col">
                            <QOptionGroup
                                :options="uploadMethodsOptions"
                                type="radio"
                                v-model="uploadMethodSelected"
                            />
                        </div>
                    </VnRow>
                    <VnRow class="row q-gutter-md q-mb-md">
                        <div class="col">
                            <QFile
                                v-if="uploadMethodSelected === 'computer'"
                                ref="inputFileRef"
                                :label="t('File')"
                                :multiple="false"
                                v-model="newPhoto.files"
                                @update:model-value="updatePhotoPreview($event)"
                                :accept="allowedContentTypes"
                                class="required cursor-pointer"
                            >
                                <template #append>
                                    <QIcon
                                        name="vn:attach"
                                        class="cursor-pointer q-mr-sm"
                                        @click="openInputFile()"
                                    >
                                        <!-- <QTooltip>{{ t('globals.selectFile') }}</QTooltip> -->
                                    </QIcon>
                                    <QIcon name="info" class="cursor-pointer">
                                        <QTooltip>{{
                                            t('globals.allowedFilesText', {
                                                allowedContentTypes: allowedContentTypes,
                                            })
                                        }}</QTooltip>
                                    </QIcon>
                                </template>
                            </QFile>
                            <VnInput
                                v-if="uploadMethodSelected === 'URL'"
                                v-model="newPhoto.url"
                                @update:model-value="updatePhotoPreview($event)"
                                placeholder="https://"
                            />
                        </div>
                    </VnRow>
                    <VnRow class="row q-gutter-md q-mb-md">
                        <div class="col">
                            <VnSelectFilter
                                :label="t('Orientation')"
                                :options="viewportTypes"
                                hide-selected
                                option-label="description"
                                v-model="viewportSelection"
                            />
                        </div>
                    </VnRow>
                    <div class="q-mt-lg row justify-end">
                        <QBtn
                            :label="t('globals.save')"
                            type="submit"
                            color="primary"
                            :disabled="isLoading"
                            :loading="isLoading"
                        />
                        <QBtn
                            :label="t('globals.cancel')"
                            type="reset"
                            color="primary"
                            flat
                            class="q-ml-sm"
                            :disabled="isLoading"
                            :loading="isLoading"
                            v-close-popup
                        />
                    </div>
                </div>
            </div>
        </QCard>
    </QForm>
</template>

<style lang="scss" scoped>
.title {
    font-size: 17px;
    font-weight: bold;
    line-height: 20px;
}

.close-icon {
    position: absolute;
    top: 20px;
    right: 20px;
    cursor: pointer;
}
</style>

<i18n>
es:
    Edit photo: Editar foto
    Select from computer: Seleccionar desde ordenador
    Import from external URL: Importar desde URL externa
    Vertical: Vertical
    Normal: Normal
    Panoramic: Panorámica
    Orientation: Orientación
    File: Fichero
    This photo provider doesn't allow remote downloads: Este proveedor de fotos no permite descargas remotas
    Rotate left: Girar a la izquierda
    Rotate right: Girar a la derecha
    Select an image: Selecciona una imagen
</i18n>
