(function($) {
    $(window).on('load', function () {
        $('body').append(`
          <dialog id="image-modal" class="image-modal maximised">
            <div class="dialog-content">
              <div class="dialog-header">
                 <h2 class="dialog-title"></h2>
                 <div class="dialog-header-buttons">
                    <button type="button" class="dialog-close" title="Close">
                        <i class="far fa-times fa-2x" aria-hidden="true"></i>
                    </button>
                </div>
              </div>
              <div class="dialog-body"></div>
              <div class="dialog-footer"></div>
            </div>
          </dialog>
        `);

        $(document).on('sitebuilder.initLightbox', function() {
            const modal = $("#image-modal");
            new SiteBuilderDialog(modal[0]); // Register it
            const modalBody = modal.find(".dialog-body");
            const modalTitle = modal.find(".dialog-title");
            const modalFooter = modal.find(".dialog-footer");
            const modalCloseButton = modal.find(".dialog-close");
            const modalContent = modal.find(".dialog-content");
            const leftArrow = $('<i class="image-controls left fa fa-chevron-left fa-2x"></i>');
            const rightArrow = $('<i class="image-controls right fa fa-chevron-right fa-2x"></i>');
            modalContent.append(leftArrow);
            modalContent.append(rightArrow);

            const lightBoxWrappers = $('.id7-main-content-area a[rel^=lightbox]');
            const imageArray = [];
            const modalImageArray = [];
            let currentIndex = 0;

            let modalWidth = 0;
            let modalHeight = 0;

            const widthPaddingForControls = 60;
            const heightAllowance = 150;

            //Get image srcs and data tag anchors with index values
            $.each(lightBoxWrappers, function(index, value) {
                $(value).data("imgIndex", index);
                imageArray[index] = $(value).find('img');
                modalImageArray[index] = "";
            });

            leftArrow.click(function(){
                if(!(currentIndex === 0)) {
                    currentIndex--;
                    determinePointers();
                    loadImage();
                }
            });

            rightArrow.click(function(){
                if(!(currentIndex === imageArray.length - 1)) {
                    currentIndex++;
                    determinePointers();
                    loadImage();
                }
            });

            $(document).keydown(function(event){
                switch (event.which) {
                    case 27:
                        modalCloseButton.trigger('click');
                        break;
                    case 37:
                        leftArrow.trigger('click');
                        break;
                    case 39:
                        rightArrow.trigger('click');
                        break;
                }
            });

            function determinePointers() {
                if (currentIndex > 0) { leftArrow.show(); }
                if (currentIndex < imageArray.length) { rightArrow.show() }
                if (currentIndex === 0) { leftArrow.hide(); }
                if (currentIndex === imageArray.length - 1) { rightArrow.hide(); }
            }

            lightBoxWrappers.on("click", function(event) {
                event.preventDefault();
                event.stopPropagation();

                currentIndex = $(this).data("imgIndex");

                loadImage();
                determinePointers();
                modal[0].showModal();
            });

            function loadImage() {
              // SBTWO-10448: Check image array length before continue the processing
              if (modalImageArray.length > 0) {
                //Preload surrounding images
                if (currentIndex > 0 && modalImageArray[currentIndex - 1] === "")  {
                    modalImageArray[currentIndex - 1] = new Image();
                    preloadImage(currentIndex - 1);
                }

                if (currentIndex < imageArray.length && modalImageArray[currentIndex + 1] === ""){
                    modalImageArray[currentIndex + 1] = new Image();
                    preloadImage(currentIndex + 1);
                }

                modalBody.html('<i class="fa fa-spinner fa-pulse fa-2x"></i>');
                modalTitle.html("&nbsp;");
                modalFooter.html("&nbsp;");

                //Check for already complete
                if (modalImageArray[currentIndex] !== "" && modalImageArray[currentIndex].complete) {
                    populateImageContainer();
                } else {
                    modalImageArray[currentIndex] = new Image();
                    modalImageArray[currentIndex].onload = function() {
                        populateImageContainer();
                    }
                }

                //If we are waiting for the image to load then add src after registering load listener
                preloadImage(currentIndex);
              }
            }

            function preloadImage(imageIndex) {
                if (modalImageArray[imageIndex].src === "") {

                //If image doesn't load give it some sensible dimensions and populate modal
                modalImageArray[imageIndex].onerror = function() {
                    modalImageArray[imageIndex].width = $(window).width() * 0.2;
                    modalImageArray[imageIndex].height = $(window).height() * 0.2;
                    if (imageIndex === currentIndex) { populateImageContainer(); }
                };

                // Strip any existing maxWidth or maxHeight
                const parentHref = imageArray[imageIndex].parents("a[rel^=lightbox]").attr("href");
                let url;
                if (parentHref && parentHref !== "#") {
                    url = parentHref.split("?")
                } else {
                    url = imageArray[imageIndex].attr("src").split("?");
                }

                let fixedArgs = [];
                if (url.length > 1) {
                    fixedArgs = $.grep(url[1].split("&"), function(arg){
                        return arg.split("=")[0] !== "maxWidth" && arg.split("=")[0] !== "maxHeight";
                    });
                }
                modalImageArray[imageIndex].src = url[0] + "?" + fixedArgs.join("&");
            }
        }

            function determineScaling(maxWidth, maxHeight, image) {
                const scaledDimensions = { width: maxWidth, height: maxHeight };
                const aspectRatio = image.width / image.height;

                const horizontalScaling = maxWidth / image.width;
                const verticalScaling = maxHeight / image.height;

                if (verticalScaling < horizontalScaling) {
                    scaledDimensions.width = maxHeight * aspectRatio;
                } else if (verticalScaling !== horizontalScaling) {
                    scaledDimensions.height = maxWidth / aspectRatio;
                }

                return scaledDimensions;
            }

            function populateImageContainer() {
                const mi = modalImageArray[currentIndex],
                    i = imageArray[currentIndex],
                    a = i.closest('a');

                // Choose smallest of image or screen width, take off allowance for footer, header and padding
                const maxImgWidth = Math.min(($(window).width() * 0.9) - widthPaddingForControls, mi.width);
                const maxImgHeight = Math.min(($(window).height() * 0.9) - heightAllowance, mi.height);

                // Maintain aspect ratio
                const imgScaledDimensions = determineScaling(maxImgWidth, maxImgHeight, mi);

                // Choose existing image dimension if it's bigger than the current scaled max
                modalWidth = Math.max(imgScaledDimensions.width, modalWidth);
                modalHeight = Math.max(imgScaledDimensions.height, modalHeight);

                // Make padding allowances, modalBody stretches the container height with a little room for vertical padding
                modal.css({ width: modalWidth + widthPaddingForControls });

                // Title modal using img[title] ahead of img[alt]
                // Caption modal using a[title] ahead of img[alt]
                modalTitle.text(i.attr("title") || i.attr("alt"));
                modalFooter.html(a.attr('title') || i.attr("alt"));
                modalBody.html(modalImageArray[currentIndex]);
            }
        });

        $(document).trigger('sitebuilder.initLightbox');
    });
})(jQuery);
