<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var $block \Magento\Catalog\Block\Adminhtml\Category\Tree */
?>
<div class="categories-side-col">
    <div class="sidebar-actions">
        <?php if ($block->getRoot()) :?>
            <?= $block->getAddRootButtonHtml() ?><br/>
            <?= $block->getAddSubButtonHtml() ?>
        <?php endif; ?>
    </div>
    <div class="tree-actions">
        <?php if ($block->getRoot()) :?>
            <?php //echo $block->getCollapseButtonHtml() ?>
            <?php //echo $block->getExpandButtonHtml() ?>
            <a href="#"
               onclick="tree.collapseTree(); return false;"><?= $block->escapeHtml(__('Collapse All')) ?></a>
            <span class="separator">|</span> <a href="#"
                                                onclick="tree.expandTree(); return false;"><?= $block->escapeHtml(__('Expand All')) ?></a>
        <?php endif; ?>
    </div>
    <?php if ($block->getRoot()) :?>
    <div class="tree-holder">
        <div id="tree-div" class="tree-wrapper"></div>
    </div>
</div>

    <div data-id="information-dialog-tree" class="messages" style="display: none;">
        <div class="message message-notice">
            <div><?= $block->escapeHtml(__('This operation can take a long time')) ?></div>
        </div>
    </div>
    <script>
        var tree;
        require([
            "jquery",
            'Magento_Ui/js/modal/modal',
            "jquery/ui",
            "prototype",
            "extjs/ext-tree-checkbox",
            "mage/adminhtml/form",
            "mage/translate"
        ], function (jQuery, modal) {

            var registry = {
                data: [],

                set: function (key, value) {
                    this.data[key] = value;
                },

                get: function (key) {
                    return this.data[key];
                }
            };

            var treeRoot = '#tree-div';

            /**
             * Fix ext compatibility with prototype 1.6
             */
            Ext.lib.Event.getTarget = function (e) {
                var ee = e.browserEvent || e;
                return ee.target ? Event.element(ee) : null;
            };

            Ext.tree.TreePanel.Enhanced = function (el, config) {
                Ext.tree.TreePanel.Enhanced.superclass.constructor.call(this, el, config);
            };

            Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, {

                loadTree: function (config, firstLoad) {
                    var parameters = config['parameters'];
                    var data = config['data'];

                    this.storeId = parameters['store_id'];

                    if (this.storeId != 0 && $('add_root_category_button')) {
                        $('add_root_category_button').hide();
                    }

                    if ((typeof parameters['root_visible']) != 'undefined') {
                        this.rootVisible = parameters['root_visible'] * 1;
                    }

                    var root = new Ext.tree.TreeNode(parameters);

                    this.nodeHash = {};
                    this.setRootNode(root);
                    this.modal = modal;

                    if (firstLoad) {
                        this.addListener('click', this.categoryClick);
                        this.addListener('beforenodedrop', categoryMove.bind(this));
                    }

                    this.loader.buildCategoryTree(root, data);
                    this.el.dom.innerHTML = '';
                    // render the tree
                    this.render();
                    if (parameters['expanded']) {
                        this.expandAll();
                    } else {
                        root.expand();
                    }

                    var selectedNode = this.getNodeById(parameters['category_id']);
                    if (selectedNode) {
                        this.currentNodeId = parameters['category_id'];
                    } else {
                        if (parameters['parent'] > 0 && parameters['category_id'] === 0) {
                            this.currentNodeId = parameters['parent'];
                        }
                    }
                    this.selectCurrentNode();

                    // Temporary solution will be replaced after refactoring of tree functionality
                    jQuery('body').off('tabsactivate.tree').on('tabsactivate.tree', jQuery.proxy(function (e, ui) {
                        this.activeTab = jQuery(ui.newTab).find('a').prop('id');
                    }, this))
                },

                request: function (url, params) {
                    if (!params) {
                        if (this.activeTab) {
                            var params = {active_tab_id: this.activeTab};
                        }
                        else {
                            var params = {};
                        }
                    }
                    if (!params.form_key) {
                        params.form_key = FORM_KEY;
                    }
                    var result = new Ajax.Request(
                        url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true' ),
                        {
                            parameters: params,
                            method: 'post'
                        }
                    );

                    return result;
                },

                selectCurrentNode: function () {
                    var selectedNode = this.getNodeById(this.currentNodeId);

                    if (selectedNode) {
                        if ((typeof selectedNode.attributes.path) != 'undefined') {
                            var path = selectedNode.attributes.path;
                            if (!this.storeId) {
                                path = '0/' + path;
                            }
                            this.selectPath(path);
                        } else {
                            this.getSelectionModel().select(selectedNode);
                        }
                    }
                },

                collapseTree: function () {
                    this.collapseAll();

                    this.selectCurrentNode();

                    if (!this.collapsed) {
                        this.collapsed = true;
                        this.loader.dataUrl = '<?= $block->escapeJs($block->escapeUrl($block->getLoadTreeUrl(false))) ?>';
                        this.request(this.loader.dataUrl, false);
                    }
                },

                expandTree: function () {
                    this.expandAll();
                    if (this.collapsed) {
                        this.collapsed = false;
                        this.loader.dataUrl = '<?= $block->escapeJs($block->escapeUrl($block->getLoadTreeUrl(true))) ?>';
                        this.request(this.loader.dataUrl, false);
                    }
                },

                categoryClick: function (node, e) {
                    var url = this.buildUrl(node.id);

                    this.currentNodeId = node.id;
                    if (!this.useAjax) {
                        setLocation(url);
                        return;
                    }
                    if (this.activeTab) {
                        var params = {active_tab_id: this.activeTab};
                    }
                    updateContent(url, params);
                },

                buildUrl: function (id) {
                    var urlExt = (this.storeId ? 'store/' + this.storeId + '/' : '') + 'id/' + id + '/';

                    return parseSidUrl(this.baseUrl, urlExt);
                },

                getBaseUrl: function () {
                    return this.baseUrl;
                }
            });

            function reRenderTree(switcherParams) {
                // re-render tree by store switcher
                if (tree && switcherParams) {
                    var url;
                    if (switcherParams.useConfirm) {
                        if (!confirm("<?= $block->escapeJs(__('Please confirm site switching. All data that hasn\'t been saved will be lost.')) ?>")) {
                            return false;
                        }
                    }

                    if ($('add_root_category_button')) {
                        if (!switcherParams.scopeId) {
                            $('add_root_category_button').show();
                        }
                        else {
                            $('add_root_category_button').hide();
                        }
                    }

                    if (tree.useAjax) {
                        // retain current selected category id
                        url = tree.switchTreeUrl + switcherParams.scopeParams + 'id/' + tree.currentNodeId + '/';
                        // load from cache
                        // load from ajax
                        // add form key
                        var params = {
                            form_key: FORM_KEY
                        };
                        new Ajax.Request(url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true' ), {
                            parameters: params,
                            method: 'post',
                            onComplete: function (transport) {
                                var response;

                                try {
                                    response = JSON.parse(transport.responseText);
                                } catch (e) {
                                    console.warn('An error occured while parsing response');
                                }

                                if (!response || !response['parameters']) {
                                    return false;
                                }

                                _renderNewTree(response, switcherParams.scopeParams);
                            }
                        });
                    } else {
                        var baseUrl = '<?= $block->escapeJs($block->escapeUrl($block->getEditUrl())) ?>';
                        var urlExt = switcherParams.scopeParams + 'id/' + tree.currentNodeId + '/';
                        url = parseSidUrl(baseUrl, urlExt);
                        setLocation(url);
                    }
                }
                // render default tree
                else {
                    _renderNewTree();
                }
            }

            function _renderNewTree(config, scopeParams) {
                if (!config) {
                    var config = defaultLoadTreeParams;
                }

                if (tree) {
                    tree.purgeListeners();
                    tree.el.dom.innerHTML = '';
                }
                tree = new Ext.tree.TreePanel.Enhanced('tree-div', newTreeParams);

                tree.loadTree(config, true);

                // try to select current category
                var selectedNode = tree.getNodeById(config.parameters.category_id);
                if (selectedNode) {
                    tree.currentNodeId = config.parameters.category_id;
                }
                tree.selectCurrentNode();

                // update content area
                var url = tree.editUrl;
                if (scopeParams) {
                    url = url + scopeParams;
                }
                <?php if ($block->isClearEdit()) :?>
                if (selectedNode) {
                    url = url + 'id/' + config.parameters.category_id;
                }
                <?php endif;?>
                //updateContent(url); //commented since ajax requests replaced with http ones to load a category
                jQuery('#tree-div').find('.x-tree-node-el').first().remove();
            }

            jQuery(function () {
                categoryLoader = new Ext.tree.TreeLoader({
                    dataUrl: '<?= $block->escapeJs($block->escapeUrl($block->getLoadTreeUrl())) ?>'
                });

                categoryLoader.processResponse = function (response, parent, callback) {
                    var config = JSON.parse(response.responseText);

                    this.buildCategoryTree(parent, config);

                    if (typeof callback == "function") {
                        callback(this, parent);
                    }
                };

                categoryLoader.buildCategoryTree = function (parent, config) {
                    if (!config) return null;

                    if (parent && config && config.length) {
                        for (var i = 0; i < config.length; i++) {
                            var node;
                            var _node = Object.clone(config[i]);
                            if (_node.children && !_node.children.length) {
                                delete(_node.children);
                                node = new Ext.tree.AsyncTreeNode(_node);
                            } else {
                                node = new Ext.tree.TreeNode(config[i]);
                            }
                            parent.appendChild(node);
                            node.loader = node.getOwnerTree().loader;
                            if (_node.children) {
                                this.buildCategoryTree(node, _node.children);
                            }
                        }
                    }
                };

                categoryLoader.buildHash = function (node) {
                    var hash = {};

                    hash = this.toArray(node.attributes);

                    if (node.childNodes.length > 0 || (node.loaded == false && node.loading == false)) {
                        hash['children'] = new Array;

                        for (var i = 0, len = node.childNodes.length; i < len; i++) {
                            if (!hash['children']) {
                                hash['children'] = new Array;
                            }
                            hash['children'].push(this.buildHash(node.childNodes[i]));
                        }
                    }

                    return hash;
                };

                categoryLoader.toArray = function (attributes) {
                    var data = {form_key: FORM_KEY};
                    for (var key in attributes) {
                        var value = attributes[key];
                        data[key] = value;
                    }

                    return data;
                };

                categoryLoader.on("beforeload", function (treeLoader, node) {
                    treeLoader.baseParams.id = node.attributes.id;
                    treeLoader.baseParams.store = node.attributes.store;
                    treeLoader.baseParams.form_key = FORM_KEY;
                });

                categoryLoader.on("load", function (treeLoader, node, config) {
                    //varienWindowOnload();
                });

                scopeSwitcherHandler = reRenderTree;

                newTreeParams = {
                    animate: false,
                    loader: categoryLoader,
                    enableDD: true,
                    containerScroll: true,
                    selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
                    rootVisible: '<?= (bool)$block->getRoot()->getIsVisible() ?>',
                    useAjax: <?= $block->escapeJs($block->getUseAjax()) ?>,
                    switchTreeUrl: '<?= $block->escapeJs($block->escapeUrl($block->getSwitchTreeUrl())) ?>',
                    editUrl: '<?= $block->escapeJs($block->escapeUrl($block->getEditUrl())) ?>',
                    currentNodeId: <?= (int)$block->getCategoryId() ?>,
                    baseUrl: '<?= $block->escapeJs($block->escapeUrl($block->getEditUrl())) ?>'
                };

                defaultLoadTreeParams = {
                    parameters: {
                        text: <?= /* @noEscape */ json_encode(htmlentities($block->getRoot()->getName())) ?>,
                        draggable: false,
                        allowDrop: <?php if ($block->getRoot()->getIsVisible()) :?>true<?php else :?>false<?php endif; ?>,
                        id: <?= (int)$block->getRoot()->getId() ?>,
                        expanded: <?= (int)$block->getIsWasExpanded() ?>,
                        store_id: <?= (int)$block->getStore()->getId() ?>,
                        category_id: <?= (int)$block->getCategoryId() ?>,
                        parent: <?= (int)$block->getRequest()->getParam('parent') ?>
                    },
                    data: <?= /* @noEscape */ $block->getTreeJson() ?>
                };

                reRenderTree();
            });

            function addNew(url, isRoot) {
                if (isRoot) {
                    tree.currentNodeId = tree.root.id;
                }

                if (/store\/\d+/.test(url)) {
                    url = url.replace(/store\/\d+/, "store/" + tree.storeId);
                }
                else {
                    url += "store/" + tree.storeId + "/";
                }

                url += 'parent/' + tree.currentNodeId;
                location.href = url;
            }

            function categoryMove(obj) {
                var data = {id: obj.dropNode.id, form_key: FORM_KEY};

                data.point = obj.point;
                switch (obj.point) {
                    case 'above' :
                        data.pid = obj.target.parentNode.id;
                        data.paid = obj.dropNode.parentNode.id;
                        if (obj.target.previousSibling) {
                            data.aid = obj.target.previousSibling.id;
                        } else {
                            data.aid = 0;
                        }
                        break;
                    case 'below' :
                        data.pid = obj.target.parentNode.id;
                        data.aid = obj.target.id;
                        break;
                    case 'append' :
                        data.pid = obj.target.id;
                        data.paid = obj.dropNode.parentNode.id;
                        if (obj.target.lastChild) {
                            data.aid = obj.target.lastChild.id;
                        } else {
                            data.aid = 0;
                        }
                        break;
                    default :
                        obj.cancel = true;
                        return obj;
                }

                var pd = [];
                for (var key in data) {
                    pd.push(encodeURIComponent(key), "=", encodeURIComponent(data[key]), "&");
                }
                pd.splice(pd.length - 1, 1);

                registry.set('pd', pd.join(""));

                jQuery('[data-id="information-dialog-category"]').modal({
                    modalClass: 'confirm',
                    title:  jQuery.mage.__('Warning message'),
                    buttons: [{
                        text: 'Cancel',
                        class: 'action-secondary',
                        click: function () {
                            reRenderTree();
                            this.closeModal();
                        }
                    }, {
                        text: 'Ok',
                        class: 'action-primary',
                        click: function () {
                            (function ($) {
                                $.ajax({
                                    url: '<?= $block->escapeJs($block->escapeUrl($block->getMoveUrl())) ?>',
                                    method: 'POST',
                                    data: registry.get('pd'),
                                    showLoader: true
                                }).done(function (data) {
                                    if (data.error) {
                                        reRenderTree();
                                    } else {
                                        $(treeRoot).trigger('categoryMove.tree');
                                    }
                                    $('.page-main-actions').next('.messages').remove();
                                    $('.page-main-actions').next('#messages').remove();
                                    $('.page-main-actions').after(data.messages);
                                }).fail(function (jqXHR, textStatus) {
                                    if (window.console) {
                                        console.log(textStatus);
                                    }
                                    location.reload();
                                });
                            })(jQuery);
                            this.closeModal();
                        }
                    }]

                }).trigger('openModal');

            }

            window.addNew = addNew;

        });
    </script>
<?php endif; ?>
