/**
 * Pinewood Pro Product Slider
 */
class PWP_Product_Slider extends MMX_Element {
	static get props() {
		return {};
	}

	styleResourceCodes = ['stylesheet'];

	products = [];

	constructor() {
		super();
		this.makeShadow();
	}

	render() {
		return /*html*/`
			<div class="pwp-product-slider-wrapper o-wrapper t-main-content-element">
				<div part="title" class="pwp-product-slider-title">
					<slot name="title"></slot>
				</div>
				${this.renderProducts()}
			</div>
		`;
	}

	afterRender() {
		const el = this.shadowRoot.querySelector(".glide")

		if (el) {
			new Glide(el, {
				type: 'carousel',
				startAt: 0,
				perView: 5,
				breakpoints: {
					900: {
						perView: 3,
					},
					720: {
						perView: 2
					}
				}
			}).mount();

			(function (document, shadowRoot) {
				'use strict';

				let purchaseForms = shadowRoot.querySelectorAll('[data-hook="purchase"]');
				let miniBasketCount = document.querySelectorAll('[data-hook~="mini-basket-count"]');
				let miniBasketAmount = document.querySelectorAll('[data-hook~="mini-basket-amount"]');

				Array.from(purchaseForms).forEach(function (purchaseForm) {
					purchaseForm.addEventListener('submit', function (evt) {
						let purchaseButton = purchaseForm.querySelector('[data-hook="add-to-cart"]');
						let purchaseButtonText = (purchaseButton.nodeName.toLowerCase() === 'input') ? purchaseButton.value : purchaseButton.textContent;
						let purchaseFormActionInput = purchaseForm.querySelector('input[name="Action"]');

						if (purchaseFormActionInput.value !== 'ADPR') {
							return;
						}

						evt.preventDefault();
						evt.stopImmediatePropagation();

						purchaseForm.action = purchaseButton.getAttribute('data-action');
						purchaseFormActionInput.value = 'ADPR';

						let data = new FormData(purchaseForm);
						let request = new XMLHttpRequest(); // Set up our HTTP request

						purchaseForm.setAttribute('data-status', 'idle');

						if (purchaseForm.getAttribute('data-status') !== 'submitting') {
							purchaseForm.setAttribute('data-status', 'submitting');
							purchaseButton.setAttribute('disabled', 'disabled');

							if (purchaseButton.nodeName.toLowerCase() === 'input') {
								purchaseButton.value = 'Processing...';
							}
							else {
								purchaseButton.textContent = 'Processing...';
							}

							// Setup our listener to process completed requests
							request.onreadystatechange = function () {
								// Only run if the request is complete
								if (request.readyState !== 4) {
									return;
								}

								// Process our return data
								if (request.status === 200) {
									// What do when the request is successful
									let response = request.response;

									let basketData = response.querySelector('[data-hook="mini-basket"]');
									let basketCount = basketData.getAttribute('data-item-count');
									let basketSubtotal = basketData.getAttribute('data-subtotal');

									if (miniBasketCount) {
										for (let mbcID = 0; mbcID < miniBasketCount.length; mbcID++) {
											miniBasketCount[mbcID].textContent = basketCount; // Update mini-basket quantity (display only)
										}
									}

									if (miniBasketAmount) {
										for (let mbaID = 0; mbaID < miniBasketAmount.length; mbaID++) {
											miniBasketAmount[mbaID].textContent = basketSubtotal; // Update mini-basket subtotal (display only)
										}
									}

									if (typeof miniBasket !== 'undefined') {
										document.querySelector('[data-hook="mini-basket"]').innerHTML = response.querySelector('[data-hook="mini-basket"]').innerHTML;

										setTimeout(function () {
											document.querySelector('[data-hook="open-mini-basket"]').click();
										}, 100);
									}

									// Re-Initialize Attribute Machine (if it is active)
									if (typeof attrMachCall !== 'undefined') {
										attrMachCall.Initialize();
									}

									// Reset button text and form status
									purchaseButton.removeAttribute('disabled');

									if (purchaseButton.nodeName.toLowerCase() === 'input') {
										purchaseButton.value = purchaseButtonText;
									}
									else {
										purchaseButton.textContent = purchaseButtonText;
									}

									purchaseForm.setAttribute('data-status', 'idle');
								}
								else {
									// What do when the request fails
									console.log('The request failed!');
									purchaseForm.setAttribute('data-status', 'idle');
								}
							};

							/**
							 * Create and send a request
							 * The first argument is the post type (GET, POST, PUT, DELETE, etc.)
							 * The second argument is the endpoint URL
							 */
							request.open(purchaseForm.method, purchaseForm.action, true);
							request.responseType = 'document';
							request.send(data);
						}
					}, false);
				});

			})(document, this.shadowRoot);
		}
	}

	styles() {
		return /*css*/``;
	}

	onDataChange() {
		this.products = [];

		if (MMX.isTruthy(this.data.products.from_individual.settings.enabled)) {
			this.loadIndividualProducts();
		}

		if (MMX.isTruthy(this.data.products.from_category.settings.enabled)) {
			this.loadProductsFromCategory();
		}

		MMX.setElementAttributes(this, {
			'data-size': this.data?.products?.image_size?.value,
			'data-image-fit': this.data?.products?.image_fit?.value
		});
	}

	getDefaultFilters() {
		return [
			{
				name: 'imagetypes',
				value: {
					types: [this.getImageType()],
					sizes: ['original', this.getPropValue('image-dimensions')]
				}
			},
			{
				name: 'ondemandcolumns',
				value: [
					'sale_price',
					'attributes'
				]
			}
		];
	}

	loadProductsFromCategory({ category_code, count, sort, filter } = {}) {
		category_code = category_code ?? this?.data?.products?.from_category?.category?.category_code;
		count = count ?? this?.data?.products?.from_category?.count?.value;
		sort = sort ?? this?.data?.products?.from_category?.sort?.value;
		filter = filter ?? this.getDefaultFilters();

		if (MMX.valueIsEmpty(category_code)) {
			return;
		}

		MMX.Runtime_JSON_API_Call({
			params: {
				function: 'Runtime_CategoryProductList_Load_Query',
				category_code,
				count,
				sort,
				filter
			}
		})
			.then(response => {
				this.products.push(...response.data.data);
				this.forceUpdate();
			})
			.catch(response => { });
	}

	loadIndividualProducts(products) {
		const productCodes = this.getProductCodesToLoad(products);

		if (!productCodes?.length) {
			return;
		}

		MMX.Runtime_JSON_API_Call({
			params: {
				function: 'Runtime_ProductList_Load_Query',
				filter: [
					{
						name: 'search',
						value: [
							{
								field: 'code',
								operator: 'IN',
								value: productCodes
							}
						]
					},
					...this.getDefaultFilters()
				]
			}
		})
			.then(response => {
				// Sort products by manual sort order
				response.data.data.sort((a, b) => {
					return productCodes.indexOf(a?.code) - productCodes.indexOf(b?.code);
				});

				this.products.unshift(...response.data.data);
				this.forceUpdate();
			})
			.catch(response => { });
	}

	getProductCodesToLoad(products) {
		products = products ?? this?.data?.products?.from_individual?.products?.children;

		if (!products?.length) {
			return;
		}

		return products.reduce((codes, product) => {
			const code = product?.product?.code;
			if (!MMX.valueIsEmpty(code) && codes.indexOf(code) === -1) {
				codes.push(code);
			}
			return codes;
		}, []);
	}

	renderProducts() {
		if (!this.products?.length) {
			return '';
		}

		return /*html*/`
			<div 
				class="product-slider glide"
				data-per-page="2,3,5"
				data-per-move="${this.getPropValue('per-move')}"
				data-peek="6"
				data-gap="${this.getPropValue('gap')}"
				data-size="${this.getPropValue('size')}"
				data-autoplay="${this.getPropValue('autoplay')}"
				data-delay="${this.getPropValue('delay')}"
				data-pause-on-hover="${this.getPropValue('pause-on-hover')}"
				data-arrow-style="${this.getPropValue('arrow-style')}"
				data-nav-position="${this.getPropValue('nav-position')}"
				data-sync-heights="${this.getPropValue('sync-heights')}"
				data-wrap="${this.getPropValue('wrap')}"
			>
				<div class="glide__track" data-glide-el="track">
					<ul class="glide__slides">
						${this.products.map(product => this.renderProduct(product)).join('')}
					</ul>
				</div>

				<div class="glide__arrows" data-glide-el="controls">
					<button class="glide__arrow glide__arrow--left" data-glide-dir="<">prev</button>
					<button class="glide__arrow glide__arrow--right" data-glide-dir=">">next</button>
				</div>
			</div>
		`;
	}

	getImageType() {
		return this?.data?.advanced?.settings?.image_type?.value ?? 'main';
	}

	renderProduct(product) {
		const imageType = this.getImageType();
		product.imgSrc = product.imagetypes?.[imageType]?.sizes?.[this.getPropValue('image-dimensions')]?.url ?? product?.imagetypes?.[imageType]?.sizes?.original?.url ?? '';

		return /*html*/`
			<li class="x-product-list__item glide__slide">
				<figure class="x-product-list__figure">
					
					<!-- Wish list -->
					<form class="x-product-layout-purchase" action="/wishlist" method="post" name="add">
						<input type="hidden" name="Old_Screen" value="CTGY" />
						<input type="hidden" name="Old_Search" value />
						<input type="hidden" name="Action" value="ATWL" />
						<input type="hidden" name="Product_Code" value="${product.code}" />
						<input type="hidden" name="Category_Code" value />
						<input type="hidden" name="Offset" value />
						<input type="hidden" name="AllOffset" value />
						<input type="hidden" name="CatListingOffset" value/>
						<input type="hidden" name="RelatedOffset" value />
						<input type="hidden" name="SearchOffset" value />
						<input type="hidden" name="Quantity" value="1" />
						
						<span class="wish-list-floating-item" data-mmnodisable="true">
							<span class="add-to-wish-list">
								<button type="submit" class="add-to-wishlist-g-button"><span class="u-icon-heart-empty"></span></button>
							</span>
						</span>
					</form>

					<!-- Details -->
					<picture class="x-product-list__picture">
						<a href="${product.url}">
							<img class="x-product-list__image" src="${product.imgSrc}" alt="${product.name}" loading="lazy" width="384" height="384">
						</a>
					</picture>
					<figcaption class="x-product-list__figure-caption">
						<a class="x-product-list__link" href="${product.url}">
							<span class="x-product-list__name">${product.name}</span>
						</a>

						<a href="${product.url}">
							<div class="star_container ${product.code}"></div>
						</a>

						${product.base_price > product.price ? (
							`
								<span class="x-product-list__price_set">
									<span class="x-product-list__price u-text-bold">${product.formatted_price}</span>
									<span class="x-product-list__price u-color-gray-500 u-text-medium"><s>${product.formatted_base_price}</s></span>
								</span>
							`
							) : (
							`
								<span class="x-product-list__price">${product.formatted_price}</span>
							`
						)}

						<form data-hook="purchase" action="https://www.pinewoodpro.com/cart" method="post" name="add">
							<input type="hidden" name="Screen" value="CTGY" />
							<input type="hidden" name="Old_Search" value />
							<input type="hidden" name="Action" value="ADPR" />
							<input type="hidden" name="Quantity" value="1" />
							<input type="hidden" name="Attributes" value="Yes" />
							<input type="hidden" name="Product_Code" value="${product.code}" />
							<input type="hidden" name="Current_Product_Code" value />
							<input type="hidden" name="Category_Code" value />
							<input type="hidden" name="Offset" value />
							<input type="hidden" name="AllOffset" value />
							<input type="hidden" name="CatListingOffset" value />
							<input type="hidden" name="RelatedOffset" value />
							<input type="hidden" name="SearchOffset" value />
							<div class="x-product-layout-purchase__options-button">
								<span class="u-block add-to-cart-button" onclick="document.forms.add.action = 'https:\/\/www.pinewoodpro.com\/cart'; document.forms.add.elements.Action.value = 'ADPR';">
									<input class="c-button c-button--full" data-action="https://www.pinewoodpro.com/cart?ajax=1" data-hook="add-to-cart" data-value="Add To Cart" type="submit" value="Add To Cart">
								</span>
							</div>
						</form>
					</figcaption>
				</figure>
			</li>
		`;
	}

	renderPrice(product) {
		// Price Display
		product.price_display = product.formatted_sale_price;
		if (this?.data?.advanced?.settings?.displayed_price?.value === 'base') {
			product.price_display = product.formatted_base_price;
		}
		else if (this?.data?.advanced?.settings?.displayed_price?.value === 'retail') {
			product.price_display = product.formatted_retail;
		}

		// Additional Price Display
		product.additional_price_display = '';
		if (this?.data?.advanced?.settings?.additional_price?.value === 'base') {
			product.additional_price_display = product.formatted_base_price;
		}
		else if (this?.data?.advanced?.settings?.additional_price?.value === 'retail') {
			product.additional_price_display = product.formatted_retail;
		}

		return /*html*/`
			<div class="type-product-prices">
				<span class="type-product-price">${product.price_display}</span>
				${product.additional_price_display.length && product.additional_price_display !== product.price_display ? /*html*/`<span class="type-product-additional-price">${product.additional_price_display}</span>` : ''}
			</div>
		`;
	}

	renderButton(product) {
		if (MMX.isFalsy(this?.data?.advanced?.settings?.button?.settings?.enabled)) {
			return '';
		}

		return /*html*/`
			<mmx-button
				href="${MMX.encodeEntities(this.buttonUrl(product))}"
				data-style="${this?.data?.advanced?.settings?.button?.adpr_text?.textsettings?.fields?.normal?.button_style?.value}"
				data-size="${this?.data?.advanced?.settings?.button?.adpr_text?.textsettings?.fields?.normal?.button_size?.value}"
				data-width="full"
				part="button"
				exportparts="button: button__inner"
			>
				${product?.attributes?.length ? this?.data?.advanced?.settings?.button?.prod_text?.value : this?.data?.advanced?.settings?.button?.adpr_text?.value}
			</mmx-button>`;
	}

	getBaskUrl() {
		return this.getPropValue('bask-url') ?? `/mm5/merchant.mvc?${!MMX.valueIsEmpty(window?.Store_Code) ? 'Store_Code=' + window.Store_Code + '&' : ''}Screen=BASK`;
	}

	buttonUrl(product, quantity = 1) {
		// Link to PROD page when the product has attributes
		if (product?.attributes?.length) {
			return product.url;
		}

		// Otherwise, link to BASK with the ADPR action
		let adprUrl = new URL(this.getBaskUrl(), document.baseURI);
		adprUrl.searchParams.append('Action', 'ADPR');
		adprUrl.searchParams.append('Product_Code', product.code);
		adprUrl.searchParams.append('Quantity', quantity);
		return adprUrl.toString();
	}
}

if (!customElements.get('pwp-product-slider')) {
	customElements.define('pwp-product-slider', PWP_Product_Slider);
}
