import {
	animateCSSModeScroll
} from '../../shared/utils.js';
export default function slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {
	if (typeof index !== 'number' && typeof index !== 'string') {
		throw new Error(
			`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);
	}

	if (typeof index === 'string') {
		/**
		 * The `index` argument converted from `string` to `number`.
		 * @type {number}
		 */
		const indexAsNumber = parseInt(index, 10);
		/**
		 * Determines whether the `index` argument is a valid `number`
		 * after being converted from the `string` type.
		 * @type {boolean}
		 */

		const isValidNumber = isFinite(indexAsNumber);

		if (!isValidNumber) {
			throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);
		} // Knowing that the converted `index` is a valid number,
		// we can update the original argument's value.


		index = indexAsNumber;
	}

	const swiper = this;
	let slideIndex = index;
	let timer;
	if (slideIndex < 0) slideIndex = 0;
	const {
		params,
		snapGrid,
		slidesGrid,
		previousIndex,
		activeIndex,
		rtlTranslate: rtl,
		wrapperEl,
		enabled
	} = swiper;

	if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
		return false;
	}

	const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
	let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
	if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;

	if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
		swiper.emit('beforeSlideChangeStart');
	}
	const translate = -snapGrid[snapIndex]; // Update progress

	swiper.updateProgress(translate); // Normalize slideIndex

	if (params.normalizeSlideIndex) {
		for (let i = 0; i < slidesGrid.length; i += 1) {
			const normalizedTranslate = -Math.floor(translate * 100);
			const normalizedGrid = Math.floor(slidesGrid[i] * 100);
			const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
			if (typeof slidesGrid[i + 1] !== 'undefined') {
				if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (
						normalizedGridNext - normalizedGrid) / 2) {
					slideIndex = i;
				} else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
					slideIndex = i + 1;
				}
			} else if (normalizedTranslate >= normalizedGrid) {
				slideIndex = i;
			}

		}
	} // Directions locks


	if (swiper.initialized && slideIndex !== activeIndex) {
		if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
			return false;
		}

		if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
			if ((activeIndex || 0) !== slideIndex) return false;
		}
	}

	let direction;
	if (slideIndex > activeIndex) direction = 'next';
	else if (slideIndex < activeIndex) direction = 'prev';
	else direction = 'reset'; // Update Index

	if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
		swiper.updateActiveIndex(slideIndex); // Update Height

		if (params.autoHeight) {
			setTimeout(() => {
				swiper.updateAutoHeight();
			}, 0)
		}

		swiper.updateSlidesClasses();

		if (params.effect !== 'slide') {
			swiper.setTranslate(translate);
		}

		if (direction !== 'reset') {
			swiper.transitionStart(runCallbacks, direction);
			swiper.transitionEnd(runCallbacks, direction);
		}

		return false;
	}

	if (params.cssMode) {
		const isH = swiper.isHorizontal();
		const t = rtl ? translate : -translate;

		if (speed === 0) {
			const isVirtual = swiper.virtual && swiper.params.virtual.enabled;

			if (isVirtual) {
				swiper.wrapperEl.style.scrollSnapType = 'none';
				swiper._immediateVirtual = true;
			}

			wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;

			if (isVirtual) {
				requestAnimationFrame(() => {
					swiper.wrapperEl.style.scrollSnapType = '';
					swiper._swiperImmediateVirtual = false;
				});
			}
		} else {
			if (!swiper.support.smoothScroll) {
				animateCSSModeScroll({
					swiper,
					targetPosition: t,
					side: isH ? 'left' : 'top'
				});
				return true;
			}

			wrapperEl.scrollTo({
				[isH ? 'left' : 'top']: t,
				behavior: 'smooth'
			});
		}

		return true;
	}
	swiper.setTransition(speed);
	swiper.setTranslate(translate);
	swiper.updateActiveIndex(slideIndex);
	swiper.updateSlidesClasses();
	swiper.emit('beforeTransitionStart', speed, internal);
	swiper.transitionStart(runCallbacks, direction);

	if (speed === 0) {
		swiper.transitionEnd(runCallbacks, direction);
	} else if (!swiper.animating) {
		swiper.animating = true;

		if (!swiper.onSlideToWrapperTransitionEnd) {
			swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
				if (!swiper || swiper.destroyed) return;
				clearTimeout(timer)
				swiper.onSlideToWrapperTransitionEnd = null;
				delete swiper.onSlideToWrapperTransitionEnd;
				swiper.transitionEnd(runCallbacks, direction);
			};
		}
		timer = setTimeout(() => {
			if (swiper.onSlideToWrapperTransitionEnd) {
				swiper.onSlideToWrapperTransitionEnd();
			}
		}, speed)
	}

	return true;
}
