<template>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <slot></slot>
        </div>
        <div class="swiper-button-prev" v-if="showNavigation"></div>
        <div class="swiper-button-next" v-if="showNavigation"></div>
        <div class="swiper-pagination" v-if="showPagination"></div>
    </div>
</template>

<script>
// Vue 2 compatible Swiper wrapper using Swiper 6 core
import SwiperCore, {Navigation, Pagination, Autoplay, Thumbs, EffectFade} from 'swiper';

// Enable modules globally
SwiperCore.use([Navigation, Pagination, Autoplay, Thumbs, EffectFade]);

export default {
    name: 'SwiperCompat',
    props: {
        // Commonly used props in the project
        slidesPerView: [Number, String],
        slidesPerGroup: [Number, String],
        spaceBetween: [Number, String],
        loop: {type: Boolean, default: false},
        width: [Number, String],
        effect: String,
        speed: [Number, String],
        autoplay: [Boolean, Object],
        navigation: {type: [Boolean, Object], default: false},
        pagination: {type: [Boolean, Object], default: false},
        allowTouchMove: {type: Boolean, default: true},
        breakpoints: {type: Object, default: () => ({})},
        // thumbs: expects { swiper: SwiperInstance }
        thumbs: {type: Object, default: null},
        // Additional props used in some components
        watchSlidesProgress: {type: Boolean, default: false},
        fadeEffect: {type: Object, default: null}
    },
    data() {
        return {
            swiper: null,
            slideObserver: null
        };
    },
    computed: {
        showNavigation() {
            return !!this.navigation;
        },
        showPagination() {
            return !!this.pagination;
        },
        swiperOptions() {
            const slideCount = this.$el ? this.$el.querySelectorAll('.swiper-slide').length : 0;
            const options = {
                slidesPerView: this.coerceNumber(this.slidesPerView, undefined),
                slidesPerGroup: this.coerceNumber(this.slidesPerGroup, undefined),
                spaceBetween: this.coerceNumber(this.spaceBetween, 0),
                // Disable loop automatically if there are fewer than 2 slides
                loop: slideCount >= 2 && this.loop,
                allowTouchMove: this.allowTouchMove,
                watchSlidesProgress: this.watchSlidesProgress,
                breakpoints: this.breakpoints || {},
                // Help with dynamic content and Vite HMR
                observer: true,
                observeParents: true,
                // Prevent navigation/loop logic when not enough slides
                watchOverflow: true,
            };

            if (this.width != null) options.width = this.coerceNumber(this.width, undefined);

            if (this.effect) options.effect = this.effect;

            if (this.speed != null) options.speed = this.coerceNumber(this.speed, undefined);

            // Navigation
            if (this.navigation) {
                options.navigation = Object.assign(
                    {
                        nextEl: this.$el ? this.$el.querySelector('.swiper-button-next') : '.swiper-button-next',
                        prevEl: this.$el ? this.$el.querySelector('.swiper-button-prev') : '.swiper-button-prev'
                    },
                    typeof this.navigation === 'object' ? this.navigation : {}
                );
            }

            // Pagination
            if (this.pagination) {
                options.pagination = Object.assign(
                    {
                        el: this.$el ? this.$el.querySelector('.swiper-pagination') : '.swiper-pagination',
                        clickable: true
                    },
                    typeof this.pagination === 'object' ? this.pagination : {}
                );
            }

            // Autoplay
            if (this.autoplay) {
                options.autoplay = typeof this.autoplay === 'object' ? this.autoplay : {
                    delay: 5000,
                    disableOnInteraction: false
                };
            }

            // Thumbs
            if (this.thumbs && this.thumbs.swiper) {
                options.thumbs = {swiper: this.thumbs.swiper};
            }

            // Fade Effect
            if (this.effect === 'fade') {
                options.effect = 'fade';
                if (this.fadeEffect) options.fadeEffect = this.fadeEffect;
            }

            return options;
        }
    },
    methods: {
        coerceNumber(val, fallback) {
            if (val === undefined || val === null || val === '') return fallback;
            const n = Number(val);
            return isNaN(n) ? fallback : n;
        },
        initSwiper() {
            const tryInit = (attempt = 0) => {
                this.$nextTick(() => {
                    const slides = this.$el ? this.$el.querySelectorAll('.swiper-slide') : [];
                    const count = slides ? slides.length : 0;
                    if (!count) {
                        if (attempt < 20) {
                            return setTimeout(() => tryInit(attempt + 1), 50);
                        }
                        // As a fallback, observe for slide additions and init once present
                        if (!this.slideObserver && this.$el) {
                            this.slideObserver = new MutationObserver(() => {
                                const slidesNow = this.$el.querySelectorAll('.swiper-slide');
                                if (slidesNow && slidesNow.length) {
                                    try {
                                        this.slideObserver.disconnect();
                                    } catch (e) {
                                    }
                                    this.slideObserver = null;
                                    tryInit(0);
                                }
                            });
                            this.slideObserver.observe(this.$el.querySelector('.swiper-wrapper') || this.$el, {
                                childList: true,
                                subtree: true
                            });
                        }
                        return;
                    }

                    if (this.swiper) {
                        try {
                            this.swiper.destroy(true, true);
                        } catch (e) {
                        }
                        this.swiper = null;
                    }

                    const opts = this.swiperOptions;
                    this.swiper = new SwiperCore(this.$el, opts);
                    if (this.slideObserver) {
                        try {
                            this.slideObserver.disconnect();
                        } catch (e) {
                        }
                        this.slideObserver = null;
                    }
                    this.$emit('swiper', this.swiper);
                });
            };

            tryInit();
        }
    },
    mounted() {
        this.initSwiper();
    },
    beforeDestroy() {
        if (this.swiper && this.swiper.destroy) {
            this.swiper.destroy(true, true);
        }
        this.swiper = null;
        if (this.slideObserver) {
            try {
                this.slideObserver.disconnect();
            } catch (e) {
            }
            this.slideObserver = null;
        }
    },
    watch: {
        // Re-init when core props change. Keep minimal to avoid excessive re-inits
        slidesPerView: 'initSwiper',
        slidesPerGroup: 'initSwiper',
        spaceBetween: 'initSwiper',
        loop: 'initSwiper',
        navigation: 'initSwiper',
        pagination: 'initSwiper',
        autoplay: 'initSwiper',
        breakpoints: {
            handler: 'initSwiper',
            deep: true
        },
        effect: 'initSwiper',
        speed: 'initSwiper',
        allowTouchMove: 'initSwiper',
        thumbs: {
            handler: 'initSwiper',
            deep: true
        }
    }
};
</script>

<style scoped>
/* The project already imports Swiper CSS globally. This component only provides structure. */
</style>
