export default class Carousel {
  constructor (element) {
    this.element = element;
    this.itemClassName = 'carousel__photo';
    this.items = this.element.querySelectorAll(`.${this.itemClassName}`);
    this.totalItems = this.items.length;
    this.slide = 0;
    this.moving = true;

    this.start();
  }

  setInitialClasses () {
    this.items[0].classList.add('active');
    this.items[1].classList.add('next');
  }

  attachEventListeners () {
    const next = this.element.querySelector('.carousel__button--next');
    const prev = this.element.querySelector('.carousel__button--prev');

    next.addEventListener('click', this.moveNext.bind(this));
    prev.addEventListener('click', this.movePrev.bind(this));
  }

  moveCarouselTo (slide) {
    // Check if carousel is moving, if not, allow interaction
    if (!this.moving) {
      // temporarily disable interactivity
      this.disableInteraction();
      // Update the 'old' adjacent slides with 'new' ones
      let newPrevious = slide - 1,
        newNext = slide + 1,
        oldPrevious = slide - 2,
        oldNext = slide + 2;
      // Test if carousel has more than three items
      if ((this.totalItems - 1) > 2) {
        // Checks and updates if the new slides are out of bounds
        if (newPrevious <= 0) {
          oldPrevious = (this.totalItems - 1);
        } else if (newNext >= (this.totalItems - 1)) {
          oldNext = 0;
        }
        // Checks and updates if slide is at the beginning/end
        if (slide === 0) {
          newPrevious = (this.totalItems - 1);
          oldPrevious = (this.totalItems - 2);
          oldNext = (slide + 1);
        } else if (slide === (this.totalItems - 1)) {
          newPrevious = (slide - 1);
          newNext = 0;
          oldNext = 1;
        }
        // Now we've worked out where we are and where we're going, 
        // by adding/removing classes we'll trigger the transitions.
        // Reset old next/prev elements to default classes
        this.items[oldPrevious].className = this.itemClassName;
        this.items[oldNext].className = this.itemClassName; // Add new classes
        this.items[newPrevious].className = this.itemClassName + ' prev';
        this.items[slide].className = this.itemClassName + ' active';
        this.items[newNext].className = this.itemClassName + ' next';
      }
    }
  }

  moveNext () {
    // Check if moving
    if (!this.moving) {
      // If it's the last slide, reset to 0, else +1
      if (this.slide === (this.totalItems - 1)) {
        this.slide = 0;
      } else {
        this.slide++;
      }
      // Move carousel to updated slide
      this.moveCarouselTo(this.slide);
    }
  }

  movePrev () {
    // Check if moving
    if (!this.moving) {
      // If it's the first slide, set as the last slide, else -1
      if (this.slide === 0) {
        this.slide = (this.totalItems - 1);
      } else {
        this.slide--;
      }
      // Move carousel to updated slide
      this.moveCarouselTo(this.slide);
    }
  }

  disableInteraction () {
    // Set 'moving' to true for the same duration as our transition.
    // (0.5s = 500ms)
    this.moving = true;
    // setTimeout runs its function once after the given time
    setTimeout(() => {
      this.moving = false
    }, 500);
  }

  start () {
    this.setInitialClasses();
    this.attachEventListeners();
    // Set moving to false so that the carousel becomes interactive
    this.moving = false;
  }
}
