<script setup lang="ts">
    import { computed } from 'vue';
    import { Swiper, SwiperSlide } from 'swiper/vue';
    import { Pagination } from 'swiper/modules';
    import type { Swiper as SwiperInstance } from 'swiper';
    import 'swiper/css';
    import 'swiper/css/pagination';

    const props = withDefaults(
        defineProps<{
            list: unknown[];
            spaceBetween?: number;
            initialSlide?: number;
            /** `default` — карусель с авто-шириной слайда; `full` — один слайд на всю ширину */
            variant?: 'default' | 'full';
            pagination?: boolean;
            /** По умолчанию `true` для `variant="full"`. Передай `false`, если высота задаётся контейнером */
            autoHeight?: boolean;
        }>(),
        {
            list: () => [],
            spaceBetween: 0,
            initialSlide: 0,
            variant: 'default',
            pagination: false,
        },
    );

    const emit = defineEmits<{
        slideChange: [index: number];
    }>();

    const isFullWidth = computed(() => props.variant === 'full');

    const useAutoHeight = computed(() =>
        props.autoHeight !== undefined ? props.autoHeight : isFullWidth.value,
    );

    const slidesPerView = computed(() => (isFullWidth.value ? 1 : 'auto'));

    const swiperModules = computed(() => (props.pagination ? [Pagination] : []));

    const rootClass = computed(() => ({
        'ui-swiper': true,
        'ui-swiper--full': isFullWidth.value,
    }));

    const slideKey = (item: unknown, index: number): string | number => {
        if (item && typeof item === 'object') {
            const record = item as { key?: string | number; id?: string | number };
            if (record.key !== undefined && record.key !== null) {
                return record.key;
            }
            if (record.id !== undefined && record.id !== null) {
                return record.id;
            }
        }
        return index;
    };

    const onSlideChange = (swiper: SwiperInstance): void => {
        emit('slideChange', swiper.activeIndex);
    };
</script>

<template>
    <section v-if="list.length > 0" :class="rootClass">
        <Swiper
            :modules="swiperModules"
            :slides-per-view="slidesPerView"
            :space-between="spaceBetween"
            :centered-slides="false"
            :initial-slide="initialSlide"
            :pagination="pagination ? { clickable: true } : false"
            :auto-height="useAutoHeight"
            :observer="useAutoHeight"
            :observe-parents="useAutoHeight"
            class="ui-swiper__container"
            @slide-change="onSlideChange"
        >
            <SwiperSlide
                v-for="(item, index) in list"
                :key="slideKey(item, index)"
                class="ui-swiper__slide"
            >
                <slot :item="item" :index="index" />
            </SwiperSlide>
        </Swiper>
    </section>
</template>

<style scoped lang="scss">
    .ui-swiper {
        width: 100%;

        &__container {
            width: 100%;
            overflow: hidden;
        }

        &__slide {
            width: auto;
            flex-shrink: 0;
        }

        &--full {
            .ui-swiper__container {
                overflow: hidden;
            }

            .ui-swiper__slide {
                width: 100%;
            }

            :deep(.swiper) {
                width: 100%;
                overflow: hidden;
            }

            :deep(.swiper-slide) {
                width: 100%;
                padding-right: 0;
            }

            :deep(.swiper-pagination) {
                bottom: 8px;
            }

            :deep(.swiper-pagination-bullet) {
                width: 6px;
                height: 6px;
                opacity: 0.45;
                background: var(--gray-900, #2b2b2b);
            }

            :deep(.swiper-pagination-bullet-active) {
                opacity: 1;
            }
        }
    }
</style>

<style lang="scss">
    .ui-swiper:not(.ui-swiper--full) .swiper {
        width: 95vw;
        height: 100%;
        overflow: visible;
    }

    .ui-swiper:not(.ui-swiper--full) .swiper-slide {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-shrink: 0;
        max-width: 100%;
        padding-right: 10px;
    }
</style>
