import $ from "jquery";
import { useCallback, useEffect } from "react";
import { createRoot } from "react-dom/client";

import { Icon, uuid } from "@devowl-wp/react-folder-tree";

import { useStores } from "../../store/stores.js";
import { __, _n } from "../../utils/i18n.js";

const CLASS_NAME_APPEND = "aiot-helper-method-append";
const CLASS_NAME_MOVE = "aiot-helper-method-move";

/**
 * Detect a single click on touch devices to trigger the click handler.
 * This must be done because jQuery Touch Punch does not support click and
 * draggable concurrently.
 */
function draggableTouchClick(e: JQuery.TouchEndEvent) {
    if (!$("body").hasClass("aiot-currently-dragging")) {
        // Check native click event
        if (e.target.click) {
            e.target.click();
        } else {
            $(e.target).trigger("click");
        }
    }
}

function usePostDraggable(disabled: boolean) {
    const {
        optionStore: {
            others: { tableCheckboxName },
        },
    } = useStores();

    const toggleAppendMove = useCallback(() => {
        // On CTRL holding add class to document body
        const keyDown = () => $("body").addClass(CLASS_NAME_APPEND);
        const keyUp = () => $("body").removeClass(CLASS_NAME_APPEND);
        $(document).on("keydown", keyDown);
        $(document).on("keyup", keyUp);

        keyUp(); // Initially reset once while start dragging

        return () => {
            $(document).off("keydown", keyDown);
            $(document).off("keyup", keyUp);
        };
    }, []);

    const makeDraggable = useCallback(() => {
        // No dragging in sort mode
        if (disabled) {
            return;
        }

        let toggleAppendMoveDispatcher: ReturnType<typeof toggleAppendMove>;

        $("#wpbody-content .wp-list-table tbody tr:not(.no-items) > :not(th)")
            .draggable({
                revert: "invalid",
                revertDuration: 0,
                appendTo: "body",
                cursorAt: { top: 0, left: 0 },
                cancel: '[contenteditable="true"],:input',
                distance: 10,
                refreshPositions: true,
                helper: () => {
                    const helperId = uuid();
                    const helper = $(`<div id="${helperId}" class="aiot-helper"></div>`);
                    const count = $(`input[name="${tableCheckboxName}"]:checked`).length || 1;
                    helper.appendTo($("body"));
                    createRoot(document.getElementById(helperId)).render(
                        <div>
                            <div className={CLASS_NAME_MOVE}>
                                <Icon type="swap" /> {_n("Move", "Move %d items", count, [count])}
                                <p>{__("Hold any key to assign to an additional category")}</p>
                            </div>
                            <div className={CLASS_NAME_APPEND}>
                                <Icon type="copy" /> {_n("Copy", "Copy %d items", count, [count])}
                                <p>{__("Release key to move")}</p>
                            </div>
                        </div>,
                    );
                    return helper;
                },
                start: () => {
                    $("body").addClass("aiot-currently-dragging");
                    toggleAppendMoveDispatcher = toggleAppendMove();

                    // FIX https://bugs.jqueryui.com/ticket/4261
                    $(document.activeElement).blur();
                },
                stop: () => {
                    $("body").removeClass("aiot-currently-dragging");
                    toggleAppendMoveDispatcher?.();
                },
            })
            .unbind("touchend", draggableTouchClick)
            .on("touchend", draggableTouchClick);
    }, [disabled, tableCheckboxName]);

    useEffect(() => {
        // Initially make draggable
        makeDraggable();
    }, []);

    return makeDraggable;
}

export { CLASS_NAME_APPEND, CLASS_NAME_MOVE, usePostDraggable };
