/** @module hooks/modal */

import $ from "jquery";
import wp from "wp";

import { restoreMediaViewSelection } from "../others/mediaViews.js";
import hooks from "../util/hooks.js";

/**
 * Get the backbone controller of the modal.
 *
 * @param {object} element The DOM element
 * @returns {Controller} The backbone controller
 */
export function getModalControllerOf(element) {
    try {
        return $(element).parents(".rml-modal").data("backboneView").controller;
    } catch (e) {
        return null;
    }
}

/**
 * The sortable state gets refreshed so check if we have to destroy the
 * draggable instance.
 *
 * @returns {boolean}
 */
export function isAttachmentsBrowserSortable(element) {
    try {
        const { attachments } = element.attachmentsBrowser;
        return !attachments.$el.sortable("option", "disabled");
    } catch (e) {
        return false;
    }
}

/**
 * @returns {boolean}
 */
export function isAttachmentsGalleryEdit(attachments) {
    try {
        return (
            ["gallery-edit", "playlist-edit", "video-playlist-edit"].indexOf(attachments.options.model.get("toolbar")) >
            -1
        );
    } catch (e) {
        return false;
    }
}

if (process.env.PLUGIN_CTX === "pro") {
    /* onlypro:start */

    const appendMediaModalClass = () => {
        $(".rml-modal-container .aiot-pad > div:nth-child(2)").each(function () {
            const parent = $(this).parents(".rml-media-modal");
            const menu = parent.find(".media-frame-menu .media-menu");
            const menuHeight = menu.get(0).offsetHeight;
            const oppositeHeight = menu
                .children(":not(.rml-modal-container)")
                .get()
                .map((c) => c.offsetHeight)
                .reduce((a, b) => a + b, 0);
            if (menuHeight - oppositeHeight > 300) {
                parent.removeClass("rml-mobile-modal");
            } else {
                parent.addClass("rml-mobile-modal");
            }
        });
    };

    /**
     * When there is a new attachments browser in modal view then
     * prepare the media view for the AppTree container.
     */
    hooks.register("attachmentsBrowser/modal", function () {
        // Wait the menu, it will immmediatly created
        setTimeout(() => {
            // Check if attachments browser is visible (plugins like ACF do hide it)
            if (!this.$el.find("ul.attachments").is(":visible")) {
                return;
            }

            const { parent } = this.views;
            const { views } = parent;
            let frames = views.get(".media-frame-menu");
            if (!frames) {
                // No frames available, for example in the "replace-image" dialog
                parent.views.add(
                    ".media-frame-menu",
                    new wp.media.view.Menu({
                        controller: this.controller,
                    }),
                );
                frames = views.get(".media-frame-menu");
            }

            const [mediaMenu] = frames;
            const mediaMenuViews = mediaMenu.views.get();
            let container = mediaMenuViews && mediaMenuViews.filter((v) => v.className === "rml-modal-container");
            (container && container.length && (container = container[0])) || (container = undefined);

            if (!container) {
                // Add seperator
                mediaMenu.views.add(
                    new wp.media.View({
                        className: "separator",
                    }),
                );

                // Add ReactJS container
                container = new wp.media.View({
                    className: "rml-modal-container",
                });
                mediaMenu.views.add(container);
            }

            // Always enable the menu
            this.controller.state().set("menu", true, { silent: true });
            parent.$el.addClass("rml-media-modal").removeClass("hide-menu");

            /**
             * A modal attachments browser is created and the view for the
             * React element is ready.
             *
             * @event module:util/hooks#attachmentsBrowser/modal/dom/ready
             * @param {object} container The backbone view
             * @this wp.media.view.AttachmentsBrowser
             */
            hooks.call("attachmentsBrowser/modal/dom/ready", [container], this);

            setTimeout(appendMediaModalClass, 0);
        }, 50);
    });

    /**
     * When a tree gets initialized then check if it is a modal and
     * modify the state.
     */
    hooks.register("tree/init", function (state, { isModal }) {
        if (isModal && this.attachmentsBrowser) {
            ((state.isResizable = false), (state.isSticky = false));
            state.isStickyHeader = false;
            state.isFullWidth = true;

            // Update WP attachment sort mode and disable the draggable items
            state.isWPAttachmentsSortMode = isAttachmentsBrowserSortable(this);
            const changeOrderBy = () =>
                this.setState({
                    isWPAttachmentsSortMode: isAttachmentsBrowserSortable(this),
                });
            const { props } = this.attachmentsBrowser.collection;
            props.on("change:orderby", changeOrderBy);
            this._unsubscribeChangeOrderBy = () => props.off("change:orderby", changeOrderBy);

            // Update previously selected item if tab change is the reason to rerender
            const {
                controller: { modal },
            } = this.attachmentsBrowser;
            restoreMediaViewSelection(this, modal._rmlFolder, ({ id }) => {
                this.attachmentsBrowser.attachments._rmlInitialSetted = true;
                state.initialSelectedId = id;
            });
        }
    });

    /**
     * When a modal tree gets destroyed save the last selected folder in the modal.
     */
    hooks.register("tree/destroy", function (state, { isModal, store }) {
        if (isModal) {
            this.attachmentsBrowser.controller.modal._rmlFolder = store.selectedId;

            const { _unsubscribeChangeOrderBy } = this;
            _unsubscribeChangeOrderBy && _unsubscribeChangeOrderBy();
            this._unsubscribeChangeOrderBy = undefined;
        }
    });

    /**
     * When the window gets resized check the flexible modal containers
     * for responsiveness.
     */
    $(() =>
        $(window).resize(function () {
            appendMediaModalClass();
        }),
    );
    /* onlypro:end */
}
