import anime from 'animejs';

class Carousel {
    constructor(itemSelector, options = {}) {
        this.itemSelector = itemSelector;

        const defaultOptions = {
            slidesSelector: '.carousel_slide',
            coverSelector: '.carousel_slide_cover',
            imgSelector: '.carousel_slide_cover_img',
            interval: 6000,
            initIndex: 0,
            animationDuration: 2000,
            animationEasing: 'easeInOutExpo',
            counterSelector: undefined
        };

        this.options = {...defaultOptions, ...options};
        
        this.carousel = document.querySelector(this.itemSelector);
        this.slides = this.carousel.querySelectorAll(this.options.slidesSelector);
        this.covers = this.carousel.querySelectorAll(this.options.coverSelector);

        this.initSlides();
        if (this.options.counterSelector) {
            this.initCounter();
        }
        this.playCarousel();
    }

    initSlides () {
        this.slides.forEach((slide, index) => {
            slide.setAttribute('data-slide-index', index);
        });

        this.currentIndex = this.options.initIndex;
        this.currentSlide = this.slides[this.currentIndex];

        anime.set(this.slides, { zIndex: 4, translateY: '101%' });
        anime.set(this.covers, { translateY: '-101%' });
        anime.set(this.currentSlide, { zIndex: 5, translateY: '0' });
        anime.set(this.currentSlide.querySelector(this.options.coverSelector), { translateY: '0', });
        anime.set(this.currentSlide.querySelector(this.options.imgSelector), { scale: 1.2 });
    }

    initCounter () {
        this.counterContainer = document.querySelector(this.options.counterSelector);
        this.counterContainer.classList.add('carousel_counter');

        let counterTotal = document.createElement('div');
        counterTotal.classList.add('carousel_counter_total');
        counterTotal.append('/' + this.slides.length);

        this.counterList = document.createElement('ul');
        this.counterList.classList.add('carousel_counter_list');
        for (let index = 0; index < this.slides.length; index++) {
            let li = document.createElement('li');
            li.append(index + 1);
            this.counterList.appendChild(li);
        }

        this.counterContainer.appendChild(this.counterList);
        this.counterContainer.appendChild(counterTotal);

        this.updateCounter();
    }

    playCarousel () {
        let that = this;
        let oldSlide = this.currentSlide;
        this.currentIndex = this.isLastSlide() ? 0 : this.currentIndex + 1;
        this.currentSlide = this.slides[this.currentIndex];

        anime.set(oldSlide, { zIndex: 4 });
        anime.set(this.currentSlide, { translateY: '101%', zIndex: 5 });
        anime.set(this.currentSlide.querySelector(this.options.coverSelector), { translateY: '-101%' });
        anime.set(this.currentSlide.querySelector(this.options.imgSelector), { scale: 1.2 });

        var TL = anime.timeline({
            easing: this.options.animationEasing,
            duration: this.options.animationDuration,
            begin: () => {
                setTimeout(() => {
                    this.updateCounter();
                }, this.options.animationDuration * 0.25);
            },
            complete: () => {
                anime.set(oldSlide, { zIndex: 0 });
                setTimeout(() => {
                    that.playCarousel();
                }, that.options.interval);
            }
        });

        TL.add({ targets: this.currentSlide, translateY: '0%', translateZ: 0 }, 0);
        TL.add({ targets: this.currentSlide.querySelector(this.options.coverSelector), translateY: '0%', translateZ: 0 }, 0);
        TL.add({ targets: this.currentSlide.querySelector(this.options.imgSelector), scale: 1, translateZ: 0 }, 0);
    }

    updateCounter () {
        anime({
            targets: this.counterList,
            duration: 800,
            easing: 'easeInOutExpo',
            translateY: (this.currentIndex / this.slides.length * -100) + '%',
            translateZ: 0
        });
    }

    isLastSlide () {
        return this.currentIndex === this.slides.length - 1;
    }
}

export default Carousel;