var Wick = window.Wick || {};

import { createLoadingButton } from './utils/create-loading-button';

const Handlebars = require('hbsfy/runtime');

Handlebars.registerPartial('loader', require('../../elements/loader.hbs'));
Handlebars.registerPartial(
    'bloomreach/why-not-add-card',
    require('../../components/bloomreach/why-not-add-card.hbs')
);

const whyNotAddTemplate = require('../../components/bloomreach/why-not-add.hbs');

Wick.WhyNotAdd = {
    ADD_TO_CART_EVENT: 'addToCart',

    products: [],
    sliders: [],
    loadingButton: null,

    el: {
        widgetContainer: '[data-why-not-add-widget]',
        root: '[data-why-not-add]',
        slider: '[data-why-not-add-slider]',
        pagination: '[data-why-not-add-pagination]',
        prev: '[data-why-not-add-prev]',
        next: '[data-why-not-add-next]',
        cta: '[data-why-not-add-cta]',
        ctaIcon: '.why-not-add-card__cta-icon',
        ctaLoader: '.why-not-add-card__cta-loader',
        starOverlay: '.star-overlay',
    },

    getDisplayPrice(product) {
        return product.displayPrice || product.price || {};
    },

    getDisplayPriceExcVat(product) {
        return product.displayPriceExclusiveVat || product.priceExclusiveVat || null;
    },

    getWasPrice(product) {
        const price = Wick.WhyNotAdd.getDisplayPrice(product);
        const wasPrice = price && price.wasPrice;

        if (wasPrice && wasPrice.formattedValue) {
            return wasPrice.formattedValue;
        }

        if (wasPrice) {
            return `${price.currencySymbol || '£'}${wasPrice}`;
        }

        return '';
    },

    getExcVatWasPrice(product) {
        const price = Wick.WhyNotAdd.getDisplayPriceExcVat(product);
        const wasPrice = price && price.wasPrice;

        if (wasPrice && wasPrice.formattedValue) {
            return wasPrice.formattedValue;
        }

        if (wasPrice) {
            return `${price.currencySymbol || '£'}${wasPrice}`;
        }

        return '';
    },

    getProductImage(product) {
        const images = product.images || [];

        return (
            images.find(function (item) {
                return item.format === 'product';
            }) ||
            images.find(function (item) {
                return item.imageType === 'PRIMARY';
            }) ||
            images[0] ||
            {}
        );
    },

    isAvailableForDelivery(product) {
        const stockCode =
            product &&
            product.stock &&
            product.stock.stockLevelStatus &&
            product.stock.stockLevelStatus.code;

        const fulfilmentType =
            product.fulfilmentType ||
            product.fulfillmentType ||
            (product.fulfillmentAttributes && product.fulfillmentAttributes.type) ||
            (product.downStreamData && product.downStreamData.fulfillmentType);

        return Boolean(
            product &&
            product.purchasable !== false &&
            product.productType !== 'MasterProductModel' &&
            !product.isBaseProduct &&
            product.availabilityRestriction !== 'UNAPPROVED' &&
            stockCode !== 'outOfStock' &&
            stockCode !== 'out of stock' &&
            fulfilmentType !== 'IN_STORE_ONLY' &&
            fulfilmentType !== 'CLICK_AND_COLLECT_ONLY'
        );
    },

    normalizePayload(payloadData) {
        if (Array.isArray(payloadData)) {
            return payloadData;
        }

        if (payloadData && Array.isArray(payloadData.recommendedProducts)) {
            return payloadData.recommendedProducts;
        }

        return [];
    },

    normalizeProducts(payloadData) {
        return Wick.WhyNotAdd.normalizePayload(payloadData)
            .map(function (item) {
                return item.baseProduct || item;
            })
            .filter(Wick.WhyNotAdd.isAvailableForDelivery)
            .slice(0, 5);
    },

    getProductRenderData(product) {
        const price = Wick.WhyNotAdd.getDisplayPrice(product);
        const priceExcVat = Wick.WhyNotAdd.getDisplayPriceExcVat(product);
        const wasPriceFormatted = Wick.WhyNotAdd.getWasPrice(product);
        const excVatWasPriceFormatted = Wick.WhyNotAdd.getExcVatWasPrice(product);
        const isSwitchVat = !!(window.ACC && window.ACC.app && window.ACC.app.isVatToggleAvailable);

        return {
            ...product,
            image: Wick.WhyNotAdd.getProductImage(product),
            price,
            wasPriceFormatted,
            incVatFormattedValue: price.formattedValue || '',
            excVatFormattedValue: priceExcVat ? priceExcVat.formattedValue || '' : '',
            incVatWasPriceFormatted: wasPriceFormatted,
            excVatWasPriceFormatted,
            'switch-vat': isSwitchVat,
        };
    },

    renderWidget($container, payloadData) {
        const products = Wick.WhyNotAdd.normalizeProducts(payloadData);

        if (!products.length) {
            $container.empty().hide();
            return;
        }

        Wick.WhyNotAdd.products = products;

        $container
            .html(
                whyNotAddTemplate({
                    products: products.map(Wick.WhyNotAdd.getProductRenderData),
                })
            )
            .show();
    },

    drawRating($root) {
        const $ratingOverlay = $root.find('.rating-overlay');

        $ratingOverlay.each(function () {
            let rating = parseFloat($(this).attr('data-rating')) || 0;
            const $stars = $(this).children(Wick.WhyNotAdd.el.starOverlay);

            $stars.each(function () {
                const $star = $(this);

                if (rating >= 1) {
                    rating--;
                } else if (rating > 0) {
                    const width = Math.asin(2 * rating - 1) / Math.PI + 0.5;
                    $star.css('width', width + 'rem');
                    rating = 0;
                } else {
                    $star.css('width', '0rem');
                }
            });
        });
    },

    destroySliders() {
        Wick.WhyNotAdd.sliders.forEach(function (slider) {
            if (slider && slider.destroy) {
                slider.destroy(true, true);
            }
        });

        Wick.WhyNotAdd.sliders = [];
    },

    updatePagination(swiper) {
        const $root = $(swiper.el).closest(Wick.WhyNotAdd.el.root);
        const $pagination = $root.find(Wick.WhyNotAdd.el.pagination);
        const total = swiper.slides.length;
        const activeIndex = swiper.activeIndex;

        let html = '';

        for (let index = 0; index < total; index++) {
            html += `<span class="why-not-add__pagination-item ${
                index === activeIndex ? 'why-not-add__pagination-item--active' : ''
            }"></span>`;
        }

        $pagination.html(html);
    },

    initSliders($root) {
        Wick.WhyNotAdd.destroySliders();

        $root.find(Wick.WhyNotAdd.el.slider).each(function () {
            const $slider = $(this);
            const $root = $slider.closest(Wick.WhyNotAdd.el.root);

            const slider = new Swiper(this, {
                roundLengths: true,
                slidesPerView: 1,
                spaceBetween: 12,
                watchOverflow: true,
                navigation: {
                    nextEl: $root.find(Wick.WhyNotAdd.el.next)[0],
                    prevEl: $root.find(Wick.WhyNotAdd.el.prev)[0],
                    disabledClass: 'why-not-add__arrow--disabled',
                },
                pagination: {
                    el: $root.find(Wick.WhyNotAdd.el.pagination)[0],
                    clickable: true,
                    renderBullet(index, className) {
                        return `<span class="${className}"></span>`;
                    },
                    bulletClass: 'why-not-add__pagination-item',
                    bulletActiveClass: 'why-not-add__pagination-item--active',
                },
            });
            Wick.WhyNotAdd.sliders.push(slider);
        });
    },

    bindAddToCart($root) {
        $root.off('click.whyNotAdd', Wick.WhyNotAdd.el.cta);
        $root.on('click.whyNotAdd', Wick.WhyNotAdd.el.cta, function (event) {
            event.preventDefault();

            const $button = $(this);
            const $card = $button.closest('.why-not-add-card');
            const productCode = $card.attr('data-product-code');

            if (!productCode || Wick.WhyNotAdd.loadingButton.isLoading($button)) {
                return;
            }

            Wick.WhyNotAdd.loadingButton.start($button);

            window.dispatchEvent(
                new CustomEvent(Wick.WhyNotAdd.ADD_TO_CART_EVENT, {
                    detail: {
                        productCode,
                        quantity: 1,
                        reject: function () {
                            Wick.WhyNotAdd.loadingButton.stop($button);
                        },
                    },
                })
            );
        });
    },

    initRenderedWidget($container) {
        const $root = $container.find(Wick.WhyNotAdd.el.root);

        if (!$root.length) {
            return;
        }

        if (!Wick.WhyNotAdd.loadingButton) {
            Wick.WhyNotAdd.loadingButton = createLoadingButton({
                textSelector: Wick.WhyNotAdd.el.ctaIcon,
                loaderSelector: Wick.WhyNotAdd.el.ctaLoader,
                loadingClass: 'why-not-add-card__cta--loading',
            });
        }

        Wick.WhyNotAdd.drawRating($root);
        Wick.WhyNotAdd.initSliders($root);
        Wick.WhyNotAdd.bindAddToCart($root);
    },

    init(payloadData) {
        const $containers = $(Wick.WhyNotAdd.el.widgetContainer);

        if (!$containers.length) {
            return;
        }

        $containers.each(function () {
            const $container = $(this);

            Wick.WhyNotAdd.renderWidget($container, payloadData);
            Wick.WhyNotAdd.initRenderedWidget($container);
        });
    },
};

$(document).ready(function () {
    const payloadData =
        window.Wick &&
        Wick.FEMock &&
        Wick.FEMock.dataBloomreach &&
        Wick.FEMock.dataBloomreach.whyNotAddRecommendations;

    if (payloadData) {
        Wick.WhyNotAdd.init(payloadData);
    }
});
