<template>

    <div class="productImage" :class="[size === 'large' ? 'largeImages' : '']">


        <div class="mainImageSlider" v-if="useSlideshow">

            <Swiper
                    :effect="primarySliderOptions.effect"
                    :fadeEffect="primarySliderOptions.fadeEffect"
                    :loop="primarySliderOptions.loop"
                    :pagination="primarySliderOptions.pagination"
                    :navigation="primarySliderOptions.navigation"
                    :allowTouchMove="primarySliderOptions.allowTouchMove"
                    :thumbs="{ swiper: thumbsSwiper }"
                    ref="mainSlider"
            >

                <SwiperSlide
                        v-for="(image, index) in allImages"
                        :key="'img' + image.id"
                >

                    <div class="mainImage">

                        <image-zoom
                                :regular="image.sizes[size].displayImage"
                                :zoom="image.sizes['zoom'].displayImage"
                                :lazyload="lazyLoad"
                                :zoom-amount="2"
                                v-if="allowZoom && image.zoom"
                        >

                            <img
                                    :src="image.sizes[size].displayImage"
                                    :alt="altImage(image.alt)"
                                    :width="image.sizes[size].width"
                                    :height="image.sizes[size].height"
                                    :loading="loading"
                            >

                        </image-zoom>

                        <img
                                :src="image.sizes[size].displayImage"
                                :alt="altImage(image.alt)"
                                :width="image.sizes[size].width"
                                :height="image.sizes[size].height"
                                :loading="loading"
                                v-else
                        >

                    </div> <!-- .mainImage-->

                </SwiperSlide>

            </Swiper>

        </div> <!-- .mainImageSlider -->

        <div class="mainImage" v-else>

            <image-zoom
                    :regular="mainImage.sizes[size].displayImage"
                    :zoom="mainImage.sizes['zoom'].displayImage"
                    :lazyload="lazyLoad"
                    :zoom-amount="2"
                    v-if="allowZoom && mainImage.zoom"
            >

                <img
                        :src="mainImage.sizes[size].displayImage"
                        :alt="altImage(mainImage.alt)"
                        :width="mainImage.sizes[size].width"
                        :height="mainImage.sizes[size].height"
                        :loading="loading"
                >

            </image-zoom>

            <img
                    :src="mainImage.sizes[size].displayImage"
                    :alt="altImage(mainImage.alt)"
                    :width="mainImage.sizes[size].width"
                    :height="mainImage.sizes[size].height"
                    :loading="loading"
                    v-else
            >


        </div> <!-- .mainImage -->

        <div class="thumbnailsWrap" v-if="useThumbnails">

            <Swiper
                :spaceBetween="thumbnailSliderOptions.spaceBetween"
                :loop="thumbnailSliderOptions.loop"
                :pagination="thumbnailSliderOptions.pagination"
                :navigation="thumbnailSliderOptions.navigation"
                :slidesPerView="thumbnailSliderOptions.slidesPerView"
                :watchSlidesProgress="thumbnailSliderOptions.watchSlidesProgress"
                :breakpoints="thumbnailSliderOptions.breakpoints"
                @swiper="setThumbsSwiper"
                ref="thumbSlider">

                <SwiperSlide v-for="image in thumbImages" :key="'img' + image.id">

                    <div class="imageWrap">

                        <img :src="image.sizes.thumbs.path + image.name"
                             :alt="altImage(image.alt)"
                             width="100"
                             height="100"
                             :loading="loading"
                        >

                    </div> <!-- .imageWrap -->

                </SwiperSlide>

            </Swiper>

        </div> <!-- .thumbnailsWrap-->

        <div class="disclaimer" v-if="showDisclaimer">
            <p v-html="disclaimerText"></p>
        </div> <!-- .disclaimer -->
    </div><!-- .productImage -->

</template>

<script>

import collect from "collect.js";
import Swiper from '@site/js/components/swiper/Swiper.vue';
import SwiperSlide from '@site/js/components/swiper/SwiperSlide.vue';
import imageZoom from 'vue-image-zoomer';
import { ref } from 'vue';

export default {

    name: 'productImages',

    components: {
        Swiper,
        SwiperSlide,
        imageZoom
    },

    props: {
        //Product images array or false
        images: {
            type: [Object, Array, Boolean],
            default (rawProps) {
                return false;
            }
        },
        //Enable/disable lazy loading
        lazyLoad: {
            type: [Boolean],
            default (rawProps) {
                return true;
            }
        },
        //size key to use from the "sizes" data
        size: {
            type: [String],
            default (rawProps) {
                return 'large';
            }
        },
        //Enable/disable slideshow when there are more than 1 images (Enabled regardless when showThumbs == true)
        slideshow: {
            type: [Boolean],
            default (rawProps) {
                return false;
            }
        },
        //Show thumbnail images when there is more than 1 image
        showThumbs: {
            type: [Boolean],
            default (rawProps) {
                return false;
            }
        },
        //Show slideshow arrows on main image when slideshow is used
        showArrows: {
            type: [Boolean],
            default (rawProps) {
                return false;
            }
        },
        //Allow image zoom on main image when set within admin
        allowZoom: {
            type: [Boolean],
            default (rawProps) {
                return false;
            }
        },
        //enable disable product image disclaimer
        showDisclaimer: {
            type: [Boolean],
            default (rawProps) {
                return false;
            }
        },
    },

    setup() {
        const thumbsSwiper = ref(null);

        return {
            thumbsSwiper
        };
    },

    data() {
        return {
            mainImage: false,
            allImages: false,
            sizes: {
                zoom: {
                    width: 1200,
                    height: 1200,
                    path: '/uploads/images/products/verylarge/',
                    fallback: '/sites/default/images/placeholders/no-image-items-thumb.png',
                    displayImage: ''
                },
                large: {
                    width: 500,
                    height: 500,
                    path: '/uploads/images/products/large/',
                    fallback: '/sites/default/images/placeholders/no-image-items-thumb.png',
                    displayImage: ''
                },
                cardSmall: {
                    width: 227,
                    height: 227,
                    path: '/uploads/images/products/thumbs/',
                    fallback: '/sites/default/images/placeholders/no-image-items-thumb.png',
                    displayImage: ''
                },
                cardLarge: {
                    width: 382,
                    height: 382,
                    path: '/uploads/images/products/large_box/',
                    fallback: '/sites/default/images/placeholders/no-image-items-thumb.png',
                    displayImage: ''
                },
                thumbs: {
                    width: 92,
                    height: 92,
                    path: '/uploads/images/products/thumbs/',
                    fallback: '/sites/default/images/placeholders/no-image-items-thumb.png',
                    displayImage: ''
                }
            },
            useThumbnails: false,
            useSlideshow: false,
            primarySliderOptions: {
                effect: 'fade',
                fadeEffect: {
                    crossFade: true
                },
                loop: true,
                pagination: false,
                navigation: false,
                allowTouchMove: false,
                thumbs: {
                    swiper: null
                }
            },
            thumbnailSliderOptions: {
                spaceBetween: 41,
                loop: false,
                pagination: false,
                navigation: false,
                slidesPerView: 3,
                watchSlidesProgress: true,
                breakpoints: {
                    640: {
                        slidesPerView: 3,
                        spaceBetween: 12
                    }
                }
            },
            disclaimerText: 'Images for Illustrative purposes only'
        }
    },

    created() {

        this.useSlideshow = this.slideshow;
        this.useThumbnails = this.showThumbs;

        this.buildImages();
        this.setMainImage();

        if(this.allImages.length < 2) {
            this.useThumbnails = false;
            this.useSlideshow = false;
        }

        if(this.useThumbnails) {
            this.useSlideshow = true;
        }

        this.primarySliderOptions.arrows = this.showArrows;

    },

    mounted() {
        // The thumbs swiper is now initialized via the @swiper event and setThumbsSwiper method
        // No need for manual initialization in mounted hook
    },

    methods: {

        setThumbsSwiper(swiper) {
            this.thumbsSwiper = swiper;
        },

        altImage(altText) {

            if(typeof altText != 'undefined') {

                if(altText) {
                    if (altText.length) {
                        return altText;
                    }
                }

            }

            return 'Product image';

        },

        /*
        * Format the image data values and move the default image to first in collection
        */
        buildImages() {

            const _this = this;

            let images = collect(this.images).all();

            if(!images.length) {
                images = [
                    {
                        alt: 'Product image',
                        zoom: '0',
                        default: '1',
                        name: false,
                        order: '0'
                    }
                ]
            }

            //Format
            images = images.map(img => {

                img.default = img.default == '1';
                img.zoom = img.zoom == '1';
                img.sizes = JSON.parse(JSON.stringify(_this.sizes));
                img.order = parseInt(img.order);

                Object.keys(img.sizes).forEach(function(key, index) {

                    if(img.name) {
                        img.sizes[key].displayImage = img.sizes[key].path + img.name;
                    }else{
                        img.sizes[key].displayImage = img.sizes[key].fallback;
                    }

                });

                return img;

            });

            const sortedImages = collect(images).sortBy('order');


            const defaultSorted= sortedImages.reject(value => value.default);
            const defaultImg = sortedImages.firstWhere('default', true);

            if(defaultImg) {
                defaultSorted.prepend(defaultImg);
            }

            this.allImages = defaultSorted.toArray();

        },

        /*
        * Sets the primary image that will show on cards and single image products
        */
        setMainImage() {

            this.mainImage = this.getDefaultImage();

        },

        /*
        * Retrieve the default image as set in admin or return the first if it's not set
        */
        getDefaultImage() {
            let image = collect(this.allImages).where('default', true).first();

            if(!image) {
                image = collect(this.allImages).first();
            }

            return image;
        }
    },

    computed: {

        /*
        * Set lazy loading html attribute value
        */
        loading() {
            return this.lazyLoad ? 'lazy' : 'eager';
        },

        /*
        * Pre-filter images for thumbnails to avoid v-if on slide elements
        */
        thumbImages() {
            const images = Array.isArray(this.allImages) ? this.allImages : [];
            return images.filter(img => !!img && !!img.name);
        }

    }

}

</script>

<style lang="less">

    /* Swiper CSS is imported globally in app.js */

    .productImage {

        .mainImageSlider {

            .swiper-button-prev,
            .swiper-button-next {
                width: 48px;
                height: 48px;
                border-radius: 0;
                background: transparent !important;

                &:after {
                    font-size: 24px;
                    color: var(--text_color);
                    transition: color 200ms linear;
                }

                &:hover, &:focus {
                    &:after {
                        color: var(--highlight_color);
                        transition: color 200ms linear;
                    }
                }

                &:active {
                    &:after {
                        color: var(--text_color);
                        transition: color 200ms linear;
                    }
                }
            }

            .swiper-button-prev {
                justify-content: flex-start;
            }

            .swiper-button-next {
                justify-content: flex-end;
            }
        }

        .mainImage {
            position: relative;
            float: none;
            clear: both;
            width: 100%;
            height: auto;
            max-height: none;
            margin: 0;
            border-radius: 12px;
            overflow: hidden;
            background: #fff;
            aspect-ratio: 1;
            padding: 0;
            pointer-events: auto;
            border: 1px solid #D9D9D9;

            display: flex;
            align-items: center;
            justify-content: center;

            .vh--outer, .vh--holder, picture {
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
            }


            & > img {
                width: 100%;
                height: 100%;
                object-fit: cover;
                position: relative;
            }


            .vh--image.vh--abs {
                max-width: none;
                max-height: none;
            }

            .vh--loading-o {
                background: rgba(255,255,255,0.5);
            }

            .vh--close {
                top: 0;
                left: auto;
                bottom: auto;
                right: 0;
                width: 48px;
                height: 48px;
                color: var(--text_color);
                background: rgba(255,255,255,0);
                text-indent: -9999px;

                &:after {
                    content: url("data:image/svg+xml; utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' %3E%3Cpath d='M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z' fill='%231D1D1D'/%3E%3C/svg%3E");
                    color: var(--text_color);
                    text-indent: 0;
                    position: absolute;
                    width: 20px;
                    left: 50%;
                    top: 50%;
                    transform: translate(-50%,-50%);
                }
            }

            .vh--message {
                position: absolute;
                bottom: auto;
                top: 0;
                right: 0;
                background: rgba(255,255,255,0);
                color: var(--text_color);
                text-indent: -9999px;
                width: 48px;
                height: 48px;
                border-radius: 50%;
                padding: 0;
                max-width: 48px;
                max-height: 48px;

                @media @mobile {
                    top: -14px;
                    right: -14px;
                }

                .vh--icon {
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%,-50%);
                    width: 24px;
                    height: 24px;
                    max-width: 24px;
                    max-height: 24px;
                    margin: 0;

                    &:after {
                        content: url("data:image/svg+xml; utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' %3E%3Cpath d='M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z' fill='%231D1D1D'/%3E%3C/svg%3E");
                        color: var(--text_color);
                        text-indent: 0;
                        position: absolute;
                        width: 18px;
                        left: 50%;
                        top: 50%;
                        transform: translate(-50%,-50%);
                        margin-top: 1px;
                    }
                }

            }

        }

        &.largeImages {

            float: none;
            clear: both;
            width: 100%;
            margin: 0 auto;
            max-width: 611px;

            @media @product_breakpoint {
                max-width: 400px;
            }


        }

        .thumbnailsWrap {
            position: relative;
            float: none;
            clear: both;
            width: 100%;
            max-width: 100%;
            margin: 0 auto;
            padding: 39px 0 0;


            .swiper {
                max-width: 84.1%;
            }

            .swiper-wrapper {

                .swiper-slide {
                    border: none;
                    cursor: pointer;

                    &.swiper-slide-thumb-active {
                        .imageWrap {
                            &:before {
                                border-color: #797979;
                                transition: border-color 200ms;
                            }
                        }
                    }

                    &:hover, &:active {
                        &:not(.swiper-slide-thumb-active) {
                            .imageWrap {
                                &:before {
                                    border-color:transparent;
                                    transition: border-color 200ms;
                                }
                            }
                        }
                    }
                }

                .imageWrap {
                    position: relative;
                    aspect-ratio: 1.0909;
                    width: 100%;
                    height: 100%;
                    border-radius: 12px;
                    overflow: hidden;
                    padding: 0;
                    display: block;
                    background: #fff;

                    img {
                        width: 100%;
                        height: 100%;
                        position: relative;
                        backface-visibility: hidden;
                        object-fit: cover;
                        z-index: 1;
                    }

                    &:before {
                        content: "";
                        display: block;
                        position: absolute;
                        width: ~"calc(100% - 4px)";
                        height: ~"calc(100% - 4px)";
                        z-index: 2;
                        border-radius: 12px;
                        border: 2px solid;
                        border-color:#797979;
                        transition: border-color 200ms;
                    }
                }

            }
        }

        .thumbnails {
            width: ~"calc(100% + 10px)";
            margin: 0 -5px;
            padding: 0 0 -10px 0;
            text-align: center;
            float: none;
            clear: both;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: center;

            &:before, &:after {
                display: none;
            }


            li {
                float: none;
                clear: both;
                flex: 1 1 100%;
                height: auto;
                padding: 0 5px;
                margin: 0 0 41px 0;
                max-width: 144px;


                a.imageWrap {
                    width: 100%;
                    height: 100%;
                    position: relative;
                    border-radius: 12px;
                    overflow: hidden;
                    aspect-ratio: 1;
                    padding: 0;
                    display: block;
                    background: #fff;

                    img {
                        width: 100%;
                        height: 100%;
                        position: relative;
                        backface-visibility: hidden;
                        z-index: 1;
                        object-fit: cover;
                    }

                    &:after {
                        content: "";
                        display: block;
                        width: ~"calc(100% - 2px)";
                        height: ~"calc(100% - 2px)";
                        position: absolute;
                        top: 0;
                        right: 0;
                        bottom: 0;
                        left: 0;
                        border: 2px solid#797979;
                        z-index: 2;
                        border-radius: 10px;
                        transition: border-color 200ms linear;
                    }
                }

                &.active {

                    a {
                        .imageWrap {
                            &:after {
                                border-color:transparent;
                                transition: border-color 200ms linear;
                            }
                        }
                    }
                }

                a {
                    &:hover, &:active {

                        .imageWrap {
                            &:after {
                                border-color: color-mix(in srgb, var(--fade_mixin_color), #797979 50%);
                                transition: border-color 200ms linear;
                            }
                        }
                    }

                    &:focus {
                        .imageWrap {
                            &:after {
                                border-color:transparent;
                                transition: border-color 200ms linear;
                            }
                        }
                    }
                }

            }

        }

        .disclaimer {
            color: var(--text_color);
            .rems(12);
            line-height: 1.3em;
            font-weight: 400;
            padding: 24px 0 0 0;
            opacity: 0.5;
            text-align: left;


            p {
                font-size: inherit;
                line-height: inherit;
                color: inherit;
                font-weight: inherit;
                margin: 0;
            }
        }

    }

</style>
