import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import Clipboard from "@ckeditor/ckeditor5-clipboard/src/clipboard";
import DOMPurify from 'dompurify';

const ALLOWED_TAGS = [
    'p', 'br',
    'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
    'strong', 'b', 'em', 'i', 'u', 's', 'del', 'strike', 'sub', 'sup',
    'blockquote', 'pre', 'code',
    'ul', 'ol', 'li',
    'a',
    'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td',
];

const ALLOWED_ATTRS = {
    'a': ['href', 'target', 'rel'],
};

// Flat union of all per-tag attrs — DOMPurify pre-filters on this before the hook runs
const ALL_ALLOWED_ATTRS = [...new Set(Object.values(ALLOWED_ATTRS).flat())];

DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
    const allowed = ALLOWED_ATTRS[node.tagName.toLowerCase()] || [];
    if (!allowed.includes(data.attrName)) {
        data.keepAttr = false;
    }
});

const PURIFY_CONFIG = {
    ALLOWED_TAGS,
    ALLOWED_ATTR: ALL_ALLOWED_ATTRS,
};

export default class CustomPasteSanitize extends Plugin {
    static get requires() {
        return [Clipboard];
    }

    static get pluginName() {
        return 'CustomPasteSanitize';
    }

    init() {
        const editor = this.editor;
        const view = editor.editing.view;
        const viewDocument = view.document;
        const clipboardPlugin = editor.plugins.get('ClipboardPipeline');

        if (!editor.config.get('aaCustomPasteSanitize')) return;

        this.listenTo(viewDocument, 'clipboardInput', (evt, data) => {
            if (editor.isReadOnly) return;

            const htmlContent = data.dataTransfer.getData('text/html');
            console.log('Pasting HTML:');
            console.log(htmlContent);

            if (!htmlContent) return;

            const cleanedHtml = this._cleanHtml(htmlContent);
            const content = editor.data.htmlProcessor.toView(cleanedHtml);
            clipboardPlugin.fire('inputTransformation', { content, dataTransfer: data.dataTransfer });
            view.scrollToTheSelection();
            evt.stop();
        }, { priority: 'highest' });
    }

    _cleanHtml(html) {
        const clean = DOMPurify.sanitize(html, PURIFY_CONFIG);
        const doc = new DOMParser().parseFromString(clean, 'text/html');

        // OpenOffice wraps li content inside p tags, so strip it
        for (const p of doc.querySelectorAll('li > p')) {
            p.replaceWith(...p.childNodes);
        }

        // convert h1 to h2
        for (const h1 of doc.querySelectorAll('h1')) {
            const h2 = doc.createElement('h2');
            h2.append(...h1.childNodes);
            h1.replaceWith(h2);
        }

        return doc.body.innerHTML;
    }
}
