/*
** Copyright (C) 2021-2026 initMAX s.r.o.
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/

($ => {
    const theme = document.documentElement.getAttribute('color-scheme') === 'dark' ? 'ace/theme/twilight' : '';
    const ace_settings = {
        theme,
        maxLines: Infinity,
        minLines: 7,
        autoScrollEditorIntoView: true,
        enableBasicAutocompletion: true,
        enableLiveAutocompletion: true,
        showGutter: true,
        tooltipFollowsMouse: true
    }
    const fields_mode = [
        {
            mode: 'ace/mode/javascript',
            matches: /browser_script|script/
        },
        {
            mode: 'ace/mode/javascript',
            // The JavaScript preprocessing step's script box. Named
            // preprocessing[N][params][0] up to 7.2 and preprocessing[N][params_0]
            // from 7.4 (the item form became a popup and renamed its fields), so
            // match the prefix only - the multiline control exists for that step
            // alone.
            matches: /^preprocessing\[\d+\]\[params/
        }
    ]

    function watchForMultilineModals() {
        (new MutationObserver(mutations => {
            const overlay = overlays_stack.end();

            // Validate overlay opener element is set and is jQuery object.
            if (overlay && overlay.element && typeof overlay.element.get === 'function') {
                const name = overlay.element.get(0).closest('.multilineinput-control').dataset.name;

                for (const field of fields_mode) {
                    if (!field.matches.test(name)) {
                        continue;
                    }

                    for (const mutation of [...mutations]) {
                        for (const elm of [...mutation.addedNodes]) {
                            if (elm.matches && elm.matches('.multilineinput-modal')) {
                                initCodeHighlight(elm.querySelector('.multilineinput-container'), {mode: field.mode});
                            }
                        }
                    }

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

    // readyState, not a bare DOMContentLoaded listener: the v1 (6.0/6.2)
    // package injects its scripts after the document is already parsed, and a
    // listener added after the event has fired never runs.
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', watchForMultilineModals);
    }
    else {
        watchForMultilineModals();
    }

    function initCodeHighlight(container, options) {
        const textarea = container.querySelector('textarea');

        [...container.querySelectorAll('.multilineinput-line-numbers,textarea')].map(el => (el.style.display = 'none'));
        container.style = '';

        const ace_div = document.createElement('div');
        ace_div.style = 'width: 100%; height: 100%';
        ace_div.setAttribute('id', 'uxmax-ace-editor');
        container.append(ace_div);

        const editor = ace.edit('uxmax-ace-editor', {
            ...options,
            ...ace_settings,
            value: textarea.value,
            readOnly: textarea.getAttribute('readonly')
        });
        editor.session.on('change', () => {
            textarea.value = editor.getValue();
            $(textarea).trigger('change');// Update characters remaining counter.
            container.style = '';// Remove height set by 'change' handlers.
        });

        if (editor.getReadOnly()) {
            editor.renderer.$cursorLayer.element.style.display = 'none';
        }
        else {
            editor.focus();
        }
    }

})(jQuery);
