(function (window, document) {
    'use strict';

    var instances = Object.create(null);
    var assetPromise = null;
    var observer = null;
    var toolbars = [[
        'source', '|', 'undo', 'redo', '|',
        'bold', 'italic', 'underline', 'strikethrough', 'removeformat', '|',
        'forecolor', 'backcolor', '|',
        'insertorderedlist', 'insertunorderedlist', 'blockquote', '|',
        'paragraph', 'fontfamily', 'fontsize', '|',
        'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
        'link', 'unlink', '|',
        'simpleupload', 'insertimage', 'insertvideo', 'attachment', '|',
        'inserttable', 'horizontal', 'spechars', '|',
        'preview', 'fullscreen'
    ]];

    function loadScript(src) {
        return new Promise(function (resolve, reject) {
            var existing = document.querySelector('script[data-cms-ueditor-src="' + src + '"]');
            if (existing) {
                if (existing.getAttribute('data-loaded') === '1') resolve();
                else {
                    existing.addEventListener('load', resolve, { once: true });
                    existing.addEventListener('error', reject, { once: true });
                }
                return;
            }
            var script = document.createElement('script');
            script.src = src;
            script.async = false;
            script.setAttribute('data-cms-ueditor-src', src);
            script.onload = function () {
                script.setAttribute('data-loaded', '1');
                resolve();
            };
            script.onerror = function () { reject(new Error('Unable to load ' + src)); };
            document.head.appendChild(script);
        });
    }

    function hasOfficialEditor() {
        return !!(window.UE && typeof window.UE.getEditor === 'function' && window.baidu && window.UE.ui);
    }

    function ensureAssets() {
        if (hasOfficialEditor()) return Promise.resolve(window.UE);
        if (!assetPromise) {
            window.UEDITOR_HOME_URL = '/public/ueditor/';
            assetPromise = loadScript('/public/ueditor/ueditor.config.js')
                .then(function () { return loadScript('/public/ueditor/ueditor.all.min.js'); })
                .then(function () {
                    if (!hasOfficialEditor()) throw new Error('UEditor initialization failed');
                    return window.UE;
                });
        }
        return assetPromise;
    }

    function statusNode(field) {
        var wrapper = field.closest('.cms-ueditor-wrap, .product-ueditor-wrap') || field.parentNode;
        var status = wrapper.querySelector('.cms-ueditor-status');
        if (!status) {
            status = document.createElement('div');
            status.className = 'cms-ueditor-status';
            status.setAttribute('role', 'status');
            field.parentNode.insertBefore(status, field);
        }
        return status;
    }

    function setStatus(field, text, state) {
        var status = statusNode(field);
        status.textContent = text;
        status.setAttribute('data-state', state || 'loading');
    }

    function sync(id) {
        var item = instances[id];
        if (!item || !item.editor || !item.ready) return false;
        item.field.value = item.editor.getContent();
        return true;
    }

    function mount(field) {
        if (!field || field.getAttribute('data-cms-ueditor-mounted') === '1') return Promise.resolve(null);
        if (!field.id) field.id = 'cms_ueditor_' + Math.random().toString(36).slice(2, 10);
        field.setAttribute('data-cms-ueditor-mounted', '1');
        field.classList.add('cms-ueditor-fallback');
        setStatus(field, '正在加载新版 UEditor…', 'loading');

        var host = document.createElement('script');
        host.type = 'text/plain';
        host.id = field.id + '_mount';
        host.className = 'cms-ueditor-host';
        field.parentNode.insertBefore(host, field);

        return ensureAssets().then(function () {
            if (!field.isConnected || !host.isConnected) return null;
            var height = Math.max(260, parseInt(field.getAttribute('data-height') || '420', 10) || 420);
            var editor = window.UE.getEditor(host.id, {
                initialFrameWidth: '100%',
                initialFrameHeight: height,
                autoHeightEnabled: false,
                autoFloatEnabled: false,
                scaleEnabled: false,
                enableAutoSave: false,
                elementPathEnabled: false,
                wordCount: true,
                zIndex: Math.max(900, parseInt(field.getAttribute('data-z-index') || '900', 10) || 900),
                serverUrl: '/public/ueditor/php/controller.php',
                toolbars: toolbars,
                textarea: '_cms_shadow_' + field.id
            });
            instances[field.id] = { field: field, host: host, editor: editor, ready: false };
            editor.ready(function () {
                var item = instances[field.id];
                if (!item || item.editor !== editor) return;
                editor.setContent(field.value || '');
                item.ready = true;
                field.hidden = true;
                var wrapper = field.closest('.cms-ueditor-wrap, .product-ueditor-wrap');
                if (wrapper) wrapper.classList.add('is-ready');
                setStatus(field, '新版 UEditor 已就绪，提交时将自动同步内容', 'ready');
                editor.addListener('contentChange', function () { sync(field.id); });
            });
            return editor;
        }).catch(function () {
            field.removeAttribute('data-cms-ueditor-mounted');
            if (host.parentNode) host.parentNode.removeChild(host);
            field.hidden = false;
            setStatus(field, '编辑器加载失败，已切换到安全文本框模式，内容仍可正常提交', 'fallback');
            return null;
        });
    }

    function initAll(root) {
        var scope = root && root.querySelectorAll ? root : document;
        var fields = scope.querySelectorAll('textarea[data-cms-ueditor]');
        var jobs = [];
        for (var i = 0; i < fields.length; i++) jobs.push(mount(fields[i]));
        return Promise.all(jobs);
    }

    function syncAll() {
        Object.keys(instances).forEach(sync);
        return true;
    }

    function destroy(id) {
        var item = instances[id];
        if (!item) {
            var field = document.getElementById(id);
            var host = document.getElementById(id + '_mount');
            if (host && host.parentNode) host.parentNode.removeChild(host);
            if (field) {
                field.hidden = false;
                field.removeAttribute('data-cms-ueditor-mounted');
            }
            return;
        }
        sync(id);
        try { item.editor.destroy(); } catch (error) {}
        item.field.hidden = false;
        item.field.removeAttribute('data-cms-ueditor-mounted');
        delete instances[id];
    }

    window.CMSUeditor = {
        ensureAssets: ensureAssets,
        init: mount,
        initAll: initAll,
        sync: sync,
        syncAll: syncAll,
        destroy: destroy,
        getEditor: function (id) { return instances[id] ? instances[id].editor : null; }
    };

    document.addEventListener('submit', syncAll, true);
    window.addEventListener('beforeunload', syncAll);

    function boot() {
        initAll(document);
        if (!window.MutationObserver || observer) return;
        observer = new MutationObserver(function (mutations) {
            for (var i = 0; i < mutations.length; i++) {
                for (var j = 0; j < mutations[i].addedNodes.length; j++) {
                    var node = mutations[i].addedNodes[j];
                    if (node.nodeType !== 1) continue;
                    if (node.matches && node.matches('textarea[data-cms-ueditor]')) mount(node);
                    else initAll(node);
                }
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
    else boot();
})(window, document);
