(function ($) {
    'use strict';

    var refreshTimer = null;
    var domObserver = null;
    var editorWindow = getEditorWindow();
    var editor$ = editorWindow ? (editorWindow.jQuery || $) : $;
    var metaIconMap = {
        date: { value: 'eicon-calendar', library: 'eicon' },
        modified_date: { value: 'eicon-edit', library: 'eicon' },
        author: { value: 'eicon-person', library: 'eicon' },
        categories: { value: 'eicon-folder', library: 'eicon' },
        category: { value: 'eicon-folder', library: 'eicon' },
        tags: { value: 'eicon-tags', library: 'eicon' },
        tag: { value: 'eicon-tags', library: 'eicon' },
        comments: { value: 'eicon-comments', library: 'eicon' },
        reading_time: { value: 'eicon-clock', library: 'eicon' }
    };

    function getEditorWindow() {
        var parentWindow = window.parent;

        if (!parentWindow || parentWindow === window || !parentWindow.document) {
            return null;
        }

        if (!parentWindow.document.querySelector('.elementor-panel')) {
            return null;
        }

        return parentWindow;
    }

    function getIconData(type) {
        var icon = metaIconMap[String(type || '').trim()];

        return icon ? { value: icon.value, library: icon.library } : { value: 'eicon-info-circle', library: 'eicon' };
    }

    function isCanonicalMetaIcon(iconValue) {
        var key;

        if (!iconValue) {
            return false;
        }

        for (key in metaIconMap) {
            if (Object.prototype.hasOwnProperty.call(metaIconMap, key) && metaIconMap[key].value === iconValue) {
                return true;
            }
        }

        return false;
    }

    function parseIconValue(rawValue) {
        var value = rawValue;

        if (!value) {
            return null;
        }

        if (typeof value === 'object') {
            return value;
        }

        try {
            return JSON.parse(value);
        } catch (error) {
            return null;
        }
    }

    function serializeIconValue(icon) {
        return JSON.stringify({
            value: icon.value || '',
            library: icon.library || ''
        });
    }

    function shouldSyncIcon(currentIcon, targetType) {
        var currentValue = String((currentIcon && currentIcon.value) || '').trim();
        var targetIcon = getIconData(targetType);

        if (!currentValue) {
            return true;
        }

        if (currentValue === targetIcon.value) {
            return false;
        }

        return isCanonicalMetaIcon(currentValue);
    }

    function getMetaItemsControl() {
        if (!editorWindow) {
            return editor$();
        }

        return editor$(editorWindow.document).find('.elementor-control[data-setting="meta_items"]').first();
    }

    function syncRowIcon($row) {
        var $typeField = $row.find('.elementor-control[data-setting="item_type"] select').first();
        var $iconField = $row.find('.elementor-control[data-setting="icon"] input[type="hidden"], .elementor-control[data-setting="icon"] input').first();
        var type = String($typeField.val() || '').trim();
        var currentIcon;
        var nextIcon;

        if (!$typeField.length || !$iconField.length || !type) {
            return;
        }

        currentIcon = parseIconValue($iconField.val());
        if (!shouldSyncIcon(currentIcon, type)) {
            return;
        }

        nextIcon = getIconData(type);
        if (currentIcon && currentIcon.value === nextIcon.value && currentIcon.library === nextIcon.library) {
            return;
        }

        $iconField.val(serializeIconValue(nextIcon)).trigger('input').trigger('change');
    }

    function syncCategoryStyleState() {
        var $control = getMetaItemsControl();
        var $stateField = editor$(editorWindow.document).find('.elementor-control[data-setting="has_category_item"] input[type="hidden"], .elementor-control[data-setting="has_category_item"] input').first();
        var hasCategory = false;

        if (!$stateField.length || !$control.length) {
            return;
        }

        $control.find('.elementor-repeater-row').each(function () {
            var $row = editor$(this);
            var $typeField = $row.find('.elementor-control[data-setting="item_type"] select').first();
            var type = String($typeField.val() || '').trim();

            if (type === 'categories' || type === 'category') {
                hasCategory = true;
                return false;
            }

            return true;
        });

        if (String($stateField.val() || '').trim() === (hasCategory ? 'yes' : 'no')) {
            return;
        }

        $stateField.val(hasCategory ? 'yes' : 'no').trigger('input').trigger('change');
    }

    function syncAllRows() {
        var $control = getMetaItemsControl();

        if (!$control.length) {
            return;
        }

        $control.find('.elementor-repeater-row').each(function () {
            syncRowIcon(editor$(this));
        });

        syncCategoryStyleState();
    }

    function scheduleSync(delay) {
        if (!editorWindow) {
            return;
        }

        window.clearTimeout(refreshTimer);
        refreshTimer = window.setTimeout(syncAllRows, delay || 120);
    }

    function observeEditorDom() {
        if (!editorWindow || domObserver || !editorWindow.MutationObserver || !editorWindow.document.body) {
            return;
        }

        domObserver = new editorWindow.MutationObserver(function (mutations) {
            var shouldSync = false;

            mutations.forEach(function (mutation) {
                if (shouldSync) {
                    return;
                }

                Array.prototype.forEach.call(mutation.addedNodes || [], function (node) {
                    var $node;

                    if (shouldSync || !node || node.nodeType !== 1) {
                        return;
                    }

                    $node = editor$(node);
                    if (
                        $node.is('.elementor-control[data-setting="meta_items"], .elementor-repeater-row') ||
                        $node.find('.elementor-control[data-setting="meta_items"], .elementor-repeater-row').length
                    ) {
                        shouldSync = true;
                    }
                });
            });

            if (shouldSync) {
                scheduleSync(80);
            }
        });

        domObserver.observe(editorWindow.document.body, {
            childList: true,
            subtree: true
        });
    }

    $(function () {
        if (!editorWindow) {
            return;
        }

        observeEditorDom();
        window.setTimeout(function () {
            scheduleSync(120);
        }, 200);
        window.setTimeout(function () {
            scheduleSync(120);
        }, 650);
    });

    if (editorWindow && editorWindow.elementor && editorWindow.elementor.channels && editorWindow.elementor.channels.editor) {
        editorWindow.elementor.channels.editor.on('change', function () {
            scheduleSync(120);
        });

        editorWindow.elementor.channels.editor.on('preview:loaded', function () {
            observeEditorDom();
            scheduleSync(200);
        });
    }

    if (editorWindow && editorWindow.jQuery) {
        editor$(editorWindow.document).on(
            'change input select2:select select2:clear',
            '.elementor-control[data-setting="meta_items"] .elementor-control[data-setting="item_type"] select',
            function () {
                scheduleSync(60);
            }
        );

        editor$(editorWindow.document).on(
            'click',
            '.elementor-control[data-setting="meta_items"] .elementor-repeater-add, .elementor-control[data-setting="meta_items"] .elementor-repeater-tool-duplicate',
            function () {
                scheduleSync(180);
                window.setTimeout(function () {
                    scheduleSync(320);
                }, 320);
            }
        );
    }
})(jQuery);
