(function ($) {
    'use strict';

    let relatedModalCounter = 0;

    function checkIfInIframe() {
        return window.top !== window.self;
    }

    // create the function that will close the modal
    function dismissModal() {
        if (checkIfInIframe()) {
            const parentWindow = window.parent;
            parentWindow.dismissModal();
            return;
        }

        $('.related-modal-' + relatedModalCounter).modal('hide');

        relatedModalCounter -= 1;
    }

    // create the function that will show the modal
    function showModal(title, body, e) {
        if (checkIfInIframe()) {
            const parentWindow = window.parent;
            parentWindow.showModal(title, body, e);
            return;
        }

        relatedModalCounter += 1;

        $.showModal({
            title: title,
            body: body,
            backdrop: false,
            modalDialogClass: "modal-dialog-centered modal-lg",
            modalClass: "modal fade popupmodal show related-modal-" + relatedModalCounter,
            onDispose: function () {
                const lastModal = $("div[class*='related-modal-']").last();
                if (lastModal) {
                    lastModal.focus();
                }
            }
        });

        const modalEl = $("div[class*='related-modal-']");
        const iframeEl = modalEl.find('#related-modal-iframe');

        if (e.data.lookup === true) {
            // set current window as iframe opener because
            // the callback is called on the opener window
            iframeEl.on('load', function () {
                const iframeObj = $(this).get(0);
                const iframeWindow = iframeObj.contentWindow;
                iframeWindow.opener = window;
            });
        }
    }

    function dismissRelatedLookupModal(win, chosenId) {
        const windowName = win.name;
        const widgetName = windowName.replace(/^(change|add|delete|lookup)_/, '');
        let widgetEl;

        if (checkIfInIframe) {
            // select second to last iframe in the main parent document
            const secondLastIframe = $('iframe.related-iframe', win.parent.document).eq(-2);
            let documentContext;

            // if second to last iframe exists get its contents
            if (secondLastIframe.length) {
                documentContext = secondLastIframe.contents();

                // else get main parent document
            } else {
                documentContext = $(win.parent.document);
            }

            // find and select widget from the specified document context
            widgetEl = documentContext.find('#' + widgetName);

            // else select widget from the main document
        } else {
            widgetEl = $('#' + widgetName);
        }

        const widgetVal = widgetEl.val();
        if (widgetEl.hasClass('vManyToManyRawIdAdminField') && Boolean(widgetVal)) {
            widgetEl.val(widgetVal + ', ' + chosenId);
        } else {
            widgetEl.val(chosenId);
        }
        dismissModal();
    }

    // assign functions to global variables
    window.dismissRelatedObjectModal = dismissModal;
    window.dismissRelatedLookupPopup = dismissRelatedLookupModal;
    window.showModal = showModal;

    function presentRelatedObjectModal(e) {
        let linkEl = $(this);
        let href = (linkEl.attr('href') || '');

        if (href === '') {
            return;
        }

        // open the popup as modal
        e.preventDefault();
        e.stopImmediatePropagation();

        // remove focus from clicked link
        linkEl.blur();

        // use the clicked link id as iframe name
        // it will be available as window.name in the loaded iframe
        let iframeName = linkEl.attr('id');
        let iframeSrc = href;
        const modalTitle = linkEl.attr('title');

        if (e.data.lookup !== true) {
            // browsers stop loading nested iframes having the same src url
            // create a random parameter and append it to the src url to prevent it
            // this workaround doesn't work with related lookup url
            let iframeSrcRandom = String(Math.round(Math.random() * 999999));
            if (iframeSrc.indexOf('?') === -1) {
                iframeSrc += '?_modal=' + iframeSrcRandom;
            } else {
                iframeSrc += '&_modal=' + iframeSrcRandom;
            }
        }

        if (iframeSrc.indexOf('_popup=1') === -1) {
            if (iframeSrc.indexOf('?') === -1) {
                iframeSrc += '?_popup=1';
            } else {
                iframeSrc += '&_popup=1';
            }
        }

        // build the iframe html
        let iframeHTML = '<iframe id="related-modal-iframe" name="' + iframeName + '" src="' + iframeSrc + '" frameBorder="0" class="related-iframe"></iframe>';

        // the modal css class
        let iframeInternalModalClass = 'related-modal';

        // if the current window is inside an iframe, it means that it is already in a modal,
        // append an additional css class to the modal to offer more customization
        if (window.top !== window.self) {
            iframeInternalModalClass += ' related-modal__nested';
        }

        showModal(modalTitle, iframeHTML, e);
        return false;
    }

    function presentRelatedObjectModalOnClickOn(selector, lookup) {
        let el = $(selector);
        el.removeAttr('onclick');
        el.unbind('click');
        el.click({lookup: lookup}, presentRelatedObjectModal);
    }

    function init() {
        presentRelatedObjectModalOnClickOn('a.related-widget-wrapper-link', false);
        presentRelatedObjectModalOnClickOn('a.related-lookup', true);
        presentRelatedObjectModalOnClickOn('a.dynamic_raw_id-related-lookup', true);
    }

    $(document).ready(function () {
        init()
    });

    $(document).on('formset:added', init);

})(jQuery);
