var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "jquery", "jquery.fancytree", "../../Loader"], function (require, exports, jquery_1, jquery_fancytree_1, Loader_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.initListenerFormNotify = exports.scrollToElement = exports.changeTabIfNeed = void 0;
    jquery_1 = __importDefault(jquery_1);
    Loader_1 = __importDefault(Loader_1);
    class FormStructure {
        static create(props) {
            return new FormStructure(props);
        }
        constructor(props) {
            this.queueSize = [];
            this.queueFilled = [];
            this.treeData = [];
            this.openedItem = [];
            this.container = (props === null || props === void 0 ? void 0 : props.container) || document.getElementById('document-structure');
            if (props === null || props === void 0 ? void 0 : props.skeleton) {
                this.init();
            }
            if (props === null || props === void 0 ? void 0 : props.dataUrl) {
                this.getSkeleton(props === null || props === void 0 ? void 0 : props.dataUrl);
            }
        }
        init() {
            var _a, _b;
            this.tree = (0, jquery_fancytree_1.createTree)(this.container, {
                source: (_event) => {
                    return this.treeData;
                },
                activate: (_event, data) => {
                    this.showNodeParent(data.node);
                },
                init: () => {
                    var _a;
                    (_a = this.openedItem) === null || _a === void 0 ? void 0 : _a.forEach((item) => {
                        var _a;
                        (_a = this.tree) === null || _a === void 0 ? void 0 : _a.getNodeByKey(item).setExpanded(true, { noAnimation: true });
                    });
                }
            });
            this.treeData = (_a = this.skeleton) === null || _a === void 0 ? void 0 : _a.map((skeletonItem) => {
                let children = [];
                if (skeletonItem.size) {
                    if (skeletonItem.size == -1) {
                        //hide if -1
                        return;
                    }
                    children = Array.from({ length: skeletonItem.size }, (_, i) => ({
                        title: i + 1,
                        key: skeletonItem.elementSelector,
                        data: {
                            index: i + 1,
                            focus: skeletonItem.focusSelector
                        }
                    }));
                }
                else if (skeletonItem.itemNameSelector) {
                    children = (0, jquery_1.default)(skeletonItem.elementSelector)
                        .find(skeletonItem.itemNameSelector)
                        .map((_rowIndex, rowItem) => {
                        return {
                            title: rowItem.value || rowItem.innerText,
                            key: skeletonItem.elementSelector +
                                ' ' +
                                skeletonItem.itemNameSelector,
                            data: {
                                index: _rowIndex,
                                focus: skeletonItem.focusSelector
                            }
                        };
                    })
                        .get();
                }
                return {
                    title: skeletonItem.name +
                        (children.length > 0 ? ` (${children.length})` : '') +
                        (skeletonItem.filled || ''),
                    folder: skeletonItem.itemNameSelector != null,
                    key: skeletonItem.scrollspySelector,
                    children: children,
                    data: {
                        focus: skeletonItem.focusSelector
                    }
                };
            }).filter((i) => i != null);
            (_b = this.tree) === null || _b === void 0 ? void 0 : _b.reload();
            //this.tree.expandAll(true);
        }
        reInit() {
            var _a;
            this.openedItem = (_a = this.tree) === null || _a === void 0 ? void 0 : _a.rootNode.children.filter((item) => item.isExpanded()).map((item) => item.key);
            this.init();
        }
        setSkeleton(skeleton) {
            this.skeleton = skeleton;
            if (this.queueSize) {
                this.queueSize.forEach((itemQueue) => this.setElementSize(itemQueue));
                this.queueSize = [];
            }
            if (this.queueFilled) {
                this.setElementFilled(this.queueFilled);
                this.queueFilled = [];
            }
            this.init();
        }
        setSize(data) {
            if (!this.skeleton) {
                this.queueSize.push(data);
                return;
            }
            this.setElementSize(data);
            this.reInit();
        }
        setFilled(data) {
            if (!this.skeleton) {
                this.queueFilled = data;
                return;
            }
            this.setElementFilled(data);
            this.reInit();
        }
        setElementSize(data) {
            var _a;
            const item = (_a = this.skeleton) === null || _a === void 0 ? void 0 : _a.find((item) => item.code == data.code);
            if (item) {
                item.size = data.size;
            }
        }
        setElementFilled(data) {
            data.forEach((filled) => {
                var _a;
                const item = (_a = this.skeleton) === null || _a === void 0 ? void 0 : _a.find((item) => item.code == filled.code);
                if (item) {
                    item.filled = filled.label;
                }
            });
        }
        showNodeParent(node) {
            // @ts-ignore
            const index = node.data.index;
            let nodeEl = (0, jquery_1.default)(node.key);
            let el;
            const rowAttr = '[data-md-table-row]';
            if (index) {
                el = nodeEl.eq(index).closest(rowAttr);
                if (!el.length) {
                    el = nodeEl.eq(index).find(rowAttr);
                    if (!el.length) {
                        el = nodeEl.find(rowAttr);
                    }
                }
            }
            else {
                el = nodeEl;
            }
            if (!el.length) {
                throw new Error('Element to scroll not found on page (' + node.key + ')');
            }
            changeTabIfNeed(el, () => this.scrollToElement(el, node));
        }
        scrollToElement(el, activeNode) {
            el[0].scrollIntoView();
            if (activeNode.data.focus) {
                let elToFocus = (0, jquery_1.default)(activeNode.data.focus);
                if (activeNode.data.index != null) {
                    elToFocus = elToFocus.eq(activeNode.data.index);
                }
                elToFocus.trigger('focus');
            }
            setTimeout(() => {
                activeNode.setFocus(false);
                activeNode.setActive(false);
            }, 2000);
        }
        //method use in not react
        handleEvent() {
            if (this.skeleton) {
                this.skeleton
                    .filter((skeletonItem) => skeletonItem.itemNameSelector != null)
                    .forEach((skeletonItem) => {
                    const root = document.querySelector(skeletonItem.elementSelector);
                    root.addEventListener('add.md.table', () => this.reInit());
                    //root.addEventListener("reorder.md.table", () => this.init());
                    root.addEventListener('delete.md.table', () => this.reInit());
                });
            }
        }
        //method use in not react
        getSkeleton(url) {
            if (this.container) {
                const container = this.container;
                container.innerHTML = (0, Loader_1.default)();
                jquery_1.default.ajax({ url })
                    .done((data) => {
                    if (data === null || data === void 0 ? void 0 : data.ok) {
                        container.innerHTML = '';
                        this.skeleton = data.skeleton;
                        this.init();
                        this.handleEvent();
                    }
                    else {
                        container.innerHTML = 'Трапилась помилка';
                    }
                })
                    .fail(() => {
                    container.innerHTML = 'Трапилась помилка';
                });
            }
        }
    }
    exports.default = FormStructure;
    function changeTabIfNeed(el, callback) {
        if (!el.is(':visible')) {
            const id = el.closest('.tab-pane').attr('id');
            const btn = document.querySelector(`[data-bs-toggle="tab"][href="#${id}"]`);
            btn === null || btn === void 0 ? void 0 : btn.addEventListener('shown.bs.tab', () => callback(), { once: true });
            btn === null || btn === void 0 ? void 0 : btn.dispatchEvent(new Event('click'));
        }
        else {
            callback();
        }
    }
    exports.changeTabIfNeed = changeTabIfNeed;
    function scrollToElement(el) {
        let obj = el.get(0);
        const topFixed = (0, jquery_1.default)('.fixed-top').height() || 0;
        const offset = 10;
        let currenttop = 0;
        if (obj.offsetParent) {
            do {
                currenttop += obj.offsetTop;
            } while ((obj = obj.offsetParent));
        }
        const scrollTop = currenttop - topFixed - offset;
        (0, jquery_1.default)('html').animate({
            scrollTop
        }, 200);
    }
    exports.scrollToElement = scrollToElement;
    function initListenerFormNotify() {
        (0, jquery_1.default)(document).on('click', '[data-scroll]', (ev) => {
            const selector = ev.currentTarget.getAttribute('data-scroll');
            const el = (0, jquery_1.default)(selector);
            if (el.length === 0) {
                throw new Error('Element to scroll not found on page (' + selector + ')');
            }
            changeTabIfNeed(el, () => scrollToElement(el));
        });
    }
    exports.initListenerFormNotify = initListenerFormNotify;
});
