<script setup lang="ts">

import {onMounted, ref, computed, watch} from "vue";
import { useVirtualizer, VirtualItem} from '@tanstack/vue-virtual';
import {FileMetas, Pagination} from "./model.ts";
import {ImagePreloader, ImageItem} from "./image-preloader.ts";

const props = withDefaults(defineProps<{
    metas: FileMetas,
    defaultPage?: number,
    height: number,
    headless?: boolean,
    dev?: boolean
}>(), {
    defaultPage: 1,
    headless: false,
    dev: false
});

const emit = defineEmits<{
    paginationChange: [pagination: Pagination];
    loading: [boolean];
}>();

// We can't set the `src` attribute to empty string, so on abort we set it to this 1px transparent gif
// const EMPTY_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';

const container = ref<HTMLElement|null>(null);
const containerHeight = ref<string>('360px');
const preloader = new ImagePreloader(props.metas);
preloader.on("loaded", (item: ImageItem) => {
    console.log("loaded", item);
    changedTimestamp.value = Date.now();
});

const estimateSize = (index: number) => {
    console.log("estimateSize", index);
    return 540;
}

const rowVirtualizer = useVirtualizer({
    debug: true,
    count: props.metas.page as number,
    getScrollElement: () => container.value,
    estimateSize: estimateSize,
    gap: 10,
    overscan: 1,
    enabled: true,
    // onChange: (instance, sync) => {
    //     // console.error("onChange", instance, sync);
    //     // console.log("items", instance.getVirtualItems());
    // }
});

interface VirtualListItem {
    imageItem: ImageItem;
    virtualItem: VirtualItem;
}

/**
 * 图片载入状态变更的时间戳，该变量的作用是用于触发视图的更新
 */
const changedTimestamp = ref<number>(0);
const virtualItems = ref<VirtualListItem[]>([]);
const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems());
const totalSize = computed(() => rowVirtualizer.value.getTotalSize());

watch(virtualRows, (newRows, oldRows) => {
    console.warn("watch virtualRows", newRows, oldRows);
    const vItems: VirtualListItem[] = [];
    for (const row of virtualRows.value) {
        vItems.push({imageItem: preloader.pre(row.index + 1), virtualItem: row});
    }
    virtualItems.value = vItems;
}, {immediate: true});

watch(virtualItems, () => {
    console.warn("watch virtualItems");
});

onMounted(() => {
    emit("loading", true);
    const parent = container.value?.parentNode as HTMLElement;
    containerHeight.value = parent.clientHeight + "px";
    // rowVirtualizer.value.setOptions({enabled: true});

    emit("paginationChange", {total: props.metas.page as number, current: 1});
    emit("loading", false);
});

</script>

<template>
    <div>
        <div ref="container" :style="{height: `${height}px`, overflowY: 'auto'}">
            <div :style="{ height: `${totalSize}px`, width: '100%', position: 'relative' }">
                <div
                    v-for="vi in virtualItems"
                    :data-index="vi.virtualItem.index"
                    :key="vi.virtualItem.index"
                    :style="{
                      position: 'absolute',
                      top: 0,
                      left: 0,
                      width: '100%',
                      height: `${vi.virtualItem.size}px`,
                      transform: `translateY(${vi.virtualItem.start}px)`,
            }"
                >
                    <template v-if="changedTimestamp">
                        <img v-if="vi.imageItem.state === 'loaded'" :src="vi.imageItem.el?.currentSrc" :alt="`第${vi.imageItem.page}页`" />
                        <div v-else-if="['unloaded', 'queueing', 'loading'].includes(vi.imageItem.state)">
                            第{{ vi.imageItem.page }}页，正在加载中....
                        </div>
                        <div v-else-if="['error'].includes(vi.imageItem.state)">
                            第{{ vi.imageItem.page }} 页，加载失败...
                        </div>
                    </template>
                </div>
            </div>
        </div>
    </div>
</template>
