/** @module hooks/sortable */

import $ from "jquery";

import { message } from "@devowl-wp/react-folder-tree";

import store from "../store/index.js";
import { addUrlParam, hooks, i18n, request, urlParam } from "../util/index.js";

const WP_TABLE_LIST_SELECTOR = ".wp-list-table.media tbody, .wp-list-table.attachments tbody";

/**
 * Apply an order to attachments browser without reloading the collection.
 */
export function applyToAttachmentsBrowser(attachmentsBrowser, selected, orderby = "rml", order = "ASC") {
    let filter;
    if (attachmentsBrowser && (filter = attachmentsBrowser.toolbar.get("rml_folder").filters[selected.id])) {
        const { props } = attachmentsBrowser.collection;
        const o = { silent: true };
        if (selected.contentCustomOrder === 1 || selected.forceCustomOrder) {
            filter.props.orderby = "rml";
            filter.props.order = "ASC";
            props.set({ orderby, order }, o);
        } else {
            delete filter.props.orderby;
            delete filter.props.order;
            props.set({ orderby: "date", order: "DESC" }, o);
        }
    }
}

if (process.env.PLUGIN_CTX === "pro") {
    /* onlypro:start */
    /**
     * An item gets relocated, so update the table or grid view.
     */
    hooks.register("attachment/relocate", async function (node, attachmentId, nextId, lastIdInView, next, e, ui) {
        const attachmentsBrowser = $(ui.item).parents(".attachments-browser").data("backboneView");
        ui.item.stop().fadeTo(100, 0.2);
        try {
            await request({
                location: {
                    path: `/attachments/${attachmentId}`,
                    method: "PUT",
                },
                request: {
                    folderId: node.id,
                    nextId,
                    lastId: lastIdInView,
                },
            });
            node.setter((node) => (node.contentCustomOrder = 1));
            applyToAttachmentsBrowser(attachmentsBrowser, node);
        } catch (e) {
            message.error(e.responseJSON.message);
        } finally {
            ui.item.stop().fadeTo(100, 1);
        }
    });

    /**
     * Prepare sortable in list table mode.
     */
    hooks.register("ready", () => {
        let lastIdInView;

        // Grid mode
        $(document)
            .on("sortstart", ".attachments-browser ul.attachments", function () {
                const { collection } = $(this).parents(".attachments-browser").data("backboneView");
                lastIdInView = collection.models[collection.models.length - 1].id;
            })
            .on("sortupdate", ".attachments-browser ul.attachments", function (e, ui) {
                const next = ui.item.next();
                const nextId = next.html() ? next.data("id") : false;
                const attachmentId = ui.item.data("id");
                const folder = $(this)
                    .parents(".attachments-browser")
                    .data("backboneView")
                    .controller.$RmlAppTree.getTreeItemById();

                /**
                 * (Pro only) An attachment is relocated and should be saved to the server.
                 *
                 * @event module:util/hooks#attachment/relocate
                 * @param {module:store/TreeNode~TreeNode} folder The tree node
                 * @param {int} attachmentId The attachment id
                 * @param {int} nextId The next id
                 * @param {int} lastIdInView
                 * @param {jQuery} next
                 * @this Sortable list
                 */
                hooks.call("attachment/relocate", [folder, attachmentId, nextId, lastIdInView, next, e, ui], $(this));
            });

        // List mode
        $(WP_TABLE_LIST_SELECTOR).sortable({
            disabled: true,
            appendTo: "body",
            tolerance: "pointer",
            scrollSensitivity: 50,
            placeholder: "ui-sortable-helper-wp-media-list",
            scrollSpeed: 50,
            distance: 10,
            cursor: "move",
            start: function (e, ui) {
                ui.placeholder.height(ui.helper[0].scrollHeight);

                // The last ID (grid mode is done in the backbone collection)
                lastIdInView = +$(WP_TABLE_LIST_SELECTOR)
                    .find('tr:last > .check-column > input[type="checkbox"]')
                    .val();
            },
            update: function (e, ui) {
                const next = ui.item.next();
                const nextId = next.html() ? next.find('> .check-column > input[type="checkbox"]').val() : false;
                const attachmentId = ui.item.find('> .check-column > input[type="checkbox"]').val();
                const folderId = $(".rml-container .aiot-active").data("id");

                hooks.call(
                    "attachment/relocate",
                    [store.getTreeItemById(folderId), attachmentId, nextId, lastIdInView, next, e, ui],
                    $(this),
                );
            },
        });
    });
    /* onlypro:end */
}

/**
 * Checks if a filter is active.
 *
 * @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
 */
export function isFilterActive(attachmentsBrowser) {
    if (attachmentsBrowser) {
        const filters = ["monthnum", "year", "uploadedTo", "type"];
        const { props } = attachmentsBrowser.collection;
        for (let i = 0; i < filters.length; i++) {
            if (props.get(filters[i])) {
                return true;
            }
        }
        return false;
    } else {
        // List
        return !!urlParam("attachment-filter");
    }
}

/**
 * Checks if a orderby is active.
 *
 * @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
 */
export function isOrderByActive(attachmentsBrowser, orderby = "rml", order = "ASC") {
    if (attachmentsBrowser) {
        const { props } = attachmentsBrowser.collection;
        const propOrder = props.get("order") || "DESC";
        return props.get("orderby") === orderby && propOrder.toUpperCase() === order.toUpperCase();
    } else {
        // List
        const propOrder = urlParam("order") || "DESC";
        return urlParam("orderby") === orderby && propOrder.toUpperCase() === order.toUpperCase();
    }
}

/**
 * @returns {string}
 */
export function orderUrl(href = window.location.href) {
    return addUrlParam(addUrlParam(href, "orderby", "rml"), "order", "asc");
}

/**
 * (Pro only) Toggle the sortable mode. Popup a message if custom order is not disabled, yet.
 * If custom order is enabled check the different list and grid mode behavior.
 *
 * @param {object} selected The selected node
 * @parma {boolean} mode The mode to activate
 * @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
 */
export function toggleSortable(selected, mode, attachmentsBrowser) {
    if (process.env.PLUGIN_CTX === "lite") {
        return false;
    } else {
        /* onlypro:start */
        const orderByActive =
            isOrderByActive(attachmentsBrowser) || isOrderByActive(attachmentsBrowser, "date", "DESC");
        const filterActive = isFilterActive(attachmentsBrowser);
        const redirect = !orderByActive || filterActive;

        // Redirect to the sortable mode
        if (redirect && mode) {
            if (!attachmentsBrowser) {
                const href = orderUrl();
                window.location.href = `${href}#order`;
            } else {
                // Grid mode, show popup that the filters should be deactivated
                message.error(i18n("orderFilterActive"));
            }
            return false;
        }

        // Toggle sortable
        (attachmentsBrowser ? attachmentsBrowser.attachments.$el : $(WP_TABLE_LIST_SELECTOR)).sortable(
            mode ? "enable" : "disable",
        );

        return true;
        /* onlypro:end */
    }
}
