<script lang="ts" setup>
    import UICard from '@/UI-kit/components/UI/card/UICard.vue';
    import { computed, defineAsyncComponent, onMounted, onUnmounted, ref, watch } from 'vue';
    import { useCheckAppVersion, useIframeHandlers } from '@/UI-kit/composables';
    import { postMessageFromApp, postMessageToApp } from '@/UI-kit/constants';
    import { parentMessage } from '@/UI-kit/utils';
    import { IPostMessageData } from '@/UI-kit/types';
    import CloseBtn from '@/UI-kit/components/common/CloseBtn.vue';
    import { useUIModalStore } from '@/UI-kit/store';
    import {
        DocumentVariantsValue,
        IPendingSaveImage,
        IRawImage,
        IUserPhotoDoc,
    } from '@/modules/documents';
    import { useUiKitConfigStore, useUiKitI18n } from '@/configs';
    import { storeToRefs } from 'pinia';

    const VERSION_APP_LIST = [2, 0, 7];

    const props = withDefaults(
        defineProps<{
            documentType: DocumentVariantsValue;
            images?: IUserPhotoDoc[];
            text?: string;
            rawImages?: IRawImage | null;
            /** Заголовок модалки просмотра фото; если задан (в т.ч. ''), не подставляется availableDocuments. */
            previewModalTitle?: string;
        }>(),
        {
            images: () => [],
            text: '',
            rawImages: null,
            previewModalTitle: undefined,
        },
    );

    const resolvedPreviewModalTitle = computed(() => {
        if (props.previewModalTitle !== undefined) {
            return props.previewModalTitle;
        }

        return t(`moduleDocuments.availableDocuments.${props.documentType}`);
    });

    const emit = defineEmits<{
        'update:document-image-list': [IPendingSaveImage[]];
        'update:delete-document-image-list': [IUserPhotoDoc[]];
        'get:camera-photo': [void];
    }>();

    const { minVersionChecker } = useCheckAppVersion();

    const { t } = useUiKitI18n();

    const uiKitConfigStore = useUiKitConfigStore();
    const { appVersion } = storeToRefs(uiKitConfigStore);

    const { openModal } = useUIModalStore();

    const pendingDownloadList = ref<IPendingSaveImage[]>([]);
    const deleteDocumentImageList = ref<IUserPhotoDoc[]>([]);
    const savedImageList = ref<IUserPhotoDoc[]>(props?.images || []);

    const allImages = computed(() => {
        const arr = [...savedImageList.value, ...pendingDownloadList.value];
        return arr.slice(arr.length - 2);
    });

    const isShowUploadBlock = computed(() => allImages.value.length < 2);

    const classList = computed(() => ({
        '--disabled': pendingDownloadList.value.length >= 2,
        '--have': savedImageList.value.length >= 1,
    }));

    const setPendingDownloadList = async (photo: IRawImage) => {
        const blob = new Blob([Uint8Array.from(atob(photo.base64String), (c) => c.charCodeAt(0))], {
            type: `image/${photo.format}`,
        });

        pendingDownloadList.value.push({
            blob,
            base64: photo,
        });
        emit('update:document-image-list', pendingDownloadList.value);
    };

    const defaultMessageList = () => {
        const key = !minVersionChecker(appVersion.value, VERSION_APP_LIST)
            ? postMessageToApp.GET_CAMERA_PHOTO
            : postMessageFromApp.GET_CAMERA_PHOTO;
        return {
            [key]: (event: IPostMessageData<{ data: IRawImage }>) => {
                setPendingDownloadList(event.data?.data);
            },
        };
    };

    watch(
        () => props.rawImages,
        (data) => {
            if (data) {
                setPendingDownloadList(data);
            }
        },
        { immediate: true },
    );

    const removeImagePendingItem = (item: IPendingSaveImage) => {
        const findIndex = pendingDownloadList.value.findIndex(
            (i) => i.base64.base64String === item.base64.base64String,
        );

        if (findIndex >= 0) {
            pendingDownloadList.value.splice(findIndex, 1);
            emit('update:document-image-list', pendingDownloadList.value);
        }
    };

    const removeImageFromServer = async (image: IUserPhotoDoc) => {
        const findIndex = savedImageList.value.findIndex((i) => i.id === image.id);
        if (findIndex >= 0) {
            deleteDocumentImageList.value.push(image);
            emit('update:delete-document-image-list', deleteDocumentImageList.value);
            savedImageList.value.splice(findIndex, 1);
        }
    };

    const remove = (item: IUserPhotoDoc | IPendingSaveImage) => {
        if (item?.id) {
            removeImageFromServer(item as IUserPhotoDoc);
        } else {
            removeImagePendingItem(item as IPendingSaveImage);
        }
    };

    useIframeHandlers(defaultMessageList(), onMounted, onUnmounted);

    const makeAndChoiceImageFromApp = () => {
        if (pendingDownloadList.value.length >= 2) {
            return;
        }

        emit('get:camera-photo');
        if (minVersionChecker(appVersion.value, VERSION_APP_LIST)) {
            parentMessage(postMessageToApp.GET_CAMERA_PHOTO);
        } else {
            parentMessage(postMessageFromApp.GET_CAMERA_PHOTO);
        }
    };

    const openDetailViewImgModal = (index: number) => {
        openModal({
            component: defineAsyncComponent(
                () =>
                    import(
                        '@/UI-blocks/components/BlockSavedImage/Type1/UIBlockViewDetailImageListModalType1.vue'
                    ),
            ),
            modalProps: {
                title: resolvedPreviewModalTitle.value,
            },
            componentProps: {
                imgs: allImages.value,
                initialSlide: index,
            },
        });
    };
</script>

<template>
    <UICard class="save-image-document" :class="classList">
        <p class="save-image-document" v-html="text" />
        <div class="save-image-document__grid">
            <div v-for="(item, index) in allImages" :key="index" class="save-image-document__item">
                <img
                    v-if="!item?.id"
                    :src="`data:image/${item.base64.format};base64, ${item.base64.base64String}`"
                    width="149"
                    height="128"
                    alt="document"
                    @click="openDetailViewImgModal(index)"
                />
                <img
                    v-else
                    :src="item?.url"
                    width="149"
                    height="128"
                    alt="document"
                    @click="openDetailViewImgModal(index)"
                />
                <CloseBtn class="save-image-document__item-close" @click="remove(item)" />
            </div>
            <div
                v-if="isShowUploadBlock"
                class="save-image-document__field"
                @click="makeAndChoiceImageFromApp"
            />
        </div>
    </UICard>
</template>

<style lang="scss" scoped>
    @use '@/UI-kit/assets/scss/mixins/index.mixin';

    .save-image-document {
        $content: &;

        @include index.text(14px, 400, 20px);
        @include index.flex(column, 12px);

        &.--disabled {
            #{$content}__field {
                opacity: 0.2;
            }
        }

        &.--have {
            #{$content}__field {
                background-size: 32px;
            }
        }

        &__field {
            width: 100%;
            height: 128px;
            background: var(--blue-50) url('@/UI-kit/assets/images/icon/save-file.svg') no-repeat
                center center;
            border: 2px dashed var(--blue-500);
            border-radius: 8px;
            background-size: 48px;
        }

        &__grid {
            @include index.flex(row, 12px);

            width: 100%;
        }

        &__item {
            position: relative;
            width: 100%;
            height: 128px;
            border-radius: 8px;

            img {
                width: 100%;
                height: 100%;
                border-radius: 8px;
                object-fit: cover;
            }

            &-close {
                position: absolute;
                top: -5px;
                right: 0;
                padding: 2px;
            }
        }
    }
</style>
