<template>
    <div class="infinite-reader" ref="containerRef">
        <div v-for="(page, index) in pages" :key="index"
             class="page-wrapper" :data-page-index="index">

            <!-- Pas d'URL : spinner de chargement -->
            <div v-if="!page?.url" class="loading">
                <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
            </div>

            <!-- Hors de la zone de rendu : placeholder dimensionné -->
            <div v-else-if="!mountedPageIndices.has(index)"
                 class="page-placeholder"
                 :style="{ height: getPlaceholderHeight(page) + 'px' }" />

            <!-- Dans la zone : composant complet -->
            <ReaderPage v-else
                :page-data="page"
                :page-number="index + 1"
                :zoom="zoom"
                :double-page-mode="doublePageMode"
                :window-width="windowWidth"
                loading="lazy" />
        </div>

        <!-- Bouton flottant pour revenir en haut -->
        <Transition
            enter-active-class="transition-all duration-300 ease-out"
            leave-active-class="transition-all duration-300 ease-in"
            enter-from-class="opacity-0 translate-y-5 scale-75"
            enter-to-class="opacity-100 translate-y-0 scale-100"
            leave-from-class="opacity-100 translate-y-0 scale-100"
            leave-to-class="opacity-0 translate-y-5 scale-75"
        >
            <button
                v-show="showFloatingButtons"
                @click="scrollToTop"
                class="fixed bottom-6 right-6 z-[9999] bg-gray-800 hover:bg-gray-700 text-white hover:text-green-500 flex flex-col items-center justify-center w-12 h-12 rounded shadow-lg transition-colors duration-200"
                title="Revenir en haut"
                type="button"
            >
                <svg class="w-5 h-5 sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18" />
                </svg>
                <span class="text-xs hidden sm:inline">Haut</span>
            </button>
        </Transition>
    </div>
</template>

<script setup>
    import { nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useHeaderStore } from '../../../../shared/stores/headerStore';
import ReaderPage from './ReaderPage.vue';

    const props = defineProps({
        pages: {
            type: Array,
            required: true
        },
        zoom: {
            type: Number,
            required: true
        },
        doublePageMode: {
            type: String,
            required: true
        }
    });

    const emit = defineEmits(['pageVisible', 'buttonsVisibilityChange']);

    const headerStore = useHeaderStore();
    const containerRef = ref(null);
    const observer = ref(null);
    const visibilityObserver = ref(null);
    const mountedPageIndices = reactive(new Set());
    const windowWidth = ref(window.innerWidth);

    // État unique pour tous les boutons flottants avec timer de 3 secondes
    const showFloatingButtons = ref(false);
    let buttonsTimer = null;

    // Variables pour détecter la direction du scroll
    let lastScrollTop = 0;
    let scrollDirection = 'down';

    const observeIntersection = entries => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const pageIndex = parseInt(entry.target.getAttribute('data-page-index'));
                emit('pageVisible', pageIndex);
            }
        });
    };

    // Calcul de la hauteur du placeholder — miroir exact du maxWidth de ReaderPage
    const getPlaceholderHeight = (page) => {
        const dims = page?.dimensions;
        if (!dims?.width || !dims?.height) return 800;
        const displayWidth = windowWidth.value < 1200
            ? Math.min(dims.width, windowWidth.value * 0.95)
            : Math.min(dims.width, 1200);
        return Math.round((dims.height / dims.width) * displayWidth);
    };

    const setupObservers = () => {
        observer.value?.disconnect();
        visibilityObserver.value?.disconnect();

        observer.value = new IntersectionObserver(observeIntersection, {
            root: null,
            threshold: 0.5
        });

        visibilityObserver.value = new IntersectionObserver(
            (entries) => {
                entries.forEach(entry => {
                    const idx = parseInt(entry.target.getAttribute('data-page-index'));
                    if (entry.isIntersecting) {
                        mountedPageIndices.add(idx);
                    } else {
                        mountedPageIndices.delete(idx);
                    }
                });
            },
            { root: null, rootMargin: '1000px 0px', threshold: 0 }
        );

        nextTick(() => {
            const els = containerRef.value?.querySelectorAll('.page-wrapper');
            els?.forEach((el, i) => {
                el.setAttribute('data-page-index', i);
                observer.value.observe(el);
                visibilityObserver.value.observe(el);
            });
        });
    };

    // Fonction unique pour gérer la visibilité de tous les boutons flottants
    const showButtonsWithTimer = () => {
        showFloatingButtons.value = true;
        emit('buttonsVisibilityChange', true);
        // Réinitialiser le timer à chaque fois
        clearTimeout(buttonsTimer);
        buttonsTimer = setTimeout(() => {
            showFloatingButtons.value = false;
            emit('buttonsVisibilityChange', false);
        }, 3000); // 3 secondes
    };

    const hideButtonsImmediately = () => {
        showFloatingButtons.value = false;
        emit('buttonsVisibilityChange', false);
        clearTimeout(buttonsTimer);
    };

    // Fonction exposée pour réinitialiser le timer depuis l'extérieur
    const resetButtonsTimer = () => {
        if (showFloatingButtons.value) {
            clearTimeout(buttonsTimer);
            buttonsTimer = setTimeout(() => {
                showFloatingButtons.value = false;
                emit('buttonsVisibilityChange', false);
            }, 3000);
        } else {
            showButtonsWithTimer();
        }
    };

    // Gestion du scroll pour tous les boutons flottants et le header
    const handleScroll = () => {
        let scrollTop = 0;

        // Vérifier le scroll sur le conteneur direct
        if (containerRef.value && containerRef.value.scrollTop > 0) {
            scrollTop = containerRef.value.scrollTop;
        } else {
            // Vérifier le scroll sur les conteneurs parents
            let currentElement = containerRef.value?.parentElement;
            while (currentElement && scrollTop === 0) {
                if (currentElement.scrollTop > 0) {
                    scrollTop = currentElement.scrollTop;
                    break;
                }
                currentElement = currentElement.parentElement;
            }

            // Vérifier le scroll sur la fenêtre
            if (scrollTop === 0) {
                scrollTop = window.scrollY;
            }
        }

        // Détecter la direction du scroll
        if (scrollTop > lastScrollTop) {
            scrollDirection = 'down';
        } else if (scrollTop < lastScrollTop) {
            scrollDirection = 'up';
        }

        // Gestion du header auto-hide (header : seulement si largeur < 1200px, toolbar : toujours)
        headerStore.updateScrollDirection(scrollTop);

        // Gestion de la visibilité des boutons flottants (même condition pour tous)
        // Afficher si on scroll et qu'on est à plus de 300px
        if (scrollTop > 300) {
            showButtonsWithTimer();
        } else if (scrollTop <= 100) {
            // Masquer immédiatement si on est en haut de page
            hideButtonsImmediately();
        }

        // Sauvegarder la position actuelle pour la prochaine comparaison
        lastScrollTop = scrollTop;
    };

    // Fonction pour revenir en haut de la page
    const scrollToTop = () => {
        // Réinitialiser le timer lors du clic
        resetButtonsTimer();

        // Stratégie 1: Scroll sur le conteneur direct
        if (containerRef.value) {
            if (containerRef.value.scrollTop > 0) {
                containerRef.value.scrollTo({
                    top: 0,
                    behavior: 'smooth'
                });
                return;
            }
        }

        // Stratégie 2: Chercher le conteneur parent avec scroll
        let currentElement = containerRef.value?.parentElement;
        while (currentElement) {
            const styles = window.getComputedStyle(currentElement);
            if (styles.overflowY === 'auto' || styles.overflowY === 'scroll' || currentElement.scrollTop > 0) {
                currentElement.scrollTo({
                    top: 0,
                    behavior: 'smooth'
                });
                return;
            }
            currentElement = currentElement.parentElement;
        }

        // Stratégie 3: Scroll sur la fenêtre entière
        window.scrollTo({
            top: 0,
            behavior: 'smooth'
        });
    };

    // Exposer la fonction pour le parent
    defineExpose({
        resetButtonsTimer,
        showButtonsWithTimer
    });

    watch(
        () => props.pages,
        () => {
            mountedPageIndices.clear();
            setupObservers();
        },
        { immediate: true }
    );

    // Gestion du redimensionnement de la fenêtre
    const handleResize = () => {
        const newWidth = window.innerWidth;
        windowWidth.value = newWidth;

        // Activer/désactiver l'auto-hide selon la largeur
        if (newWidth < 1200) {
            headerStore.enableAutoHide();
        } else {
            headerStore.disableAutoHide();
        }
    };

    onMounted(() => {
        setupObservers();

        // Activer l'auto-hide du header si la largeur < 1200px
        if (windowWidth.value < 1200) {
            headerStore.enableAutoHide();
        }

        // Ajouter l'écouteur de scroll sur le conteneur
        if (containerRef.value) {
            containerRef.value.addEventListener('scroll', handleScroll, { passive: true });
        }

        // Ajouter l'écouteur de scroll sur la fenêtre
        window.addEventListener('scroll', handleScroll, { passive: true });

        // Ajouter l'écouteur de redimensionnement
        window.addEventListener('resize', handleResize, { passive: true });
    });

    onUnmounted(() => {
        observer.value?.disconnect();
        visibilityObserver.value?.disconnect();

        // Désactiver l'auto-hide du header en quittant
        headerStore.disableAutoHide();

        // Nettoyer les timers
        clearTimeout(buttonsTimer);

        // Nettoyer l'écouteur de scroll du conteneur
        if (containerRef.value) {
            containerRef.value.removeEventListener('scroll', handleScroll);
        }

        // Nettoyer l'écouteur de scroll de la fenêtre
        window.removeEventListener('scroll', handleScroll);

        // Nettoyer l'écouteur de redimensionnement
        window.removeEventListener('resize', handleResize);
    });
</script>

<style lang="postcss" scoped>
    .infinite-reader {
        @apply flex-1 flex flex-col items-center overflow-y-auto relative min-h-0;
        /* Réduction du padding sur mobile */
        @apply py-2 sm:py-8;
        scroll-behavior: smooth;
    }

    .page-wrapper {
        @apply w-full flex justify-center;
        @apply mb-2 sm:mb-4 px-1 sm:px-4;
    }

    .page-placeholder {
        @apply w-full;
        max-width: 1200px;
        min-height: 400px;
    }

    .loading,
    .error {
        @apply flex items-center justify-center min-h-[400px];
        /* Largeur adaptative selon la taille d'écran */
        width: 95vw; /* Mobile : 95% de la largeur */
    }

    @screen sm {
        .loading,
        .error {
            width: 80vw; /* Tablette : 80% de la largeur */
        }
    }

    @screen lg {
        .loading,
        .error {
            width: 70vw; /* Desktop : 70% de la largeur */
        }
    }

    .error {
        @apply text-red-500 text-xl bg-red-500/10 rounded-lg;
    }

</style>
