export const initAlpineWysiwyg = () => {
    // Define window.alpineWysiwyg function FIRST, before Alpine.data registration
    // This ensures it's always available even if Alpine isn't loaded yet
    window.alpineWysiwyg = function ({ initial, disabled }) {
        if (window.Alpine && typeof Alpine.data === 'function') {
            const componentData = Alpine.data('alpineWysiwyg');
            if (componentData) {
                return componentData({ initial, disabled });
            }
        }

        // Fallback - zelfde logica
        return {
            html: initial || '',
            disabled: !!disabled,
            htmlMode: false,
            _isUpdatingFromInput: false,

            $editable() {
                return this.$refs.editable;
            },

            init() {
                const initEditor = () => {
                    if (this.$editable()) {
                        const serverContent = this.$editable().innerHTML || '';
                        
                        // If server rendered content and Alpine's html is empty or different,
                        // sync from server content (handles morph case)
                        if (serverContent && !this.html) {
                            this.html = serverContent;
                        } else if (this.html) {
                            this.$editable().innerHTML = this.html;
                        }

                        this.$watch('html', (val, oldVal) => {
                            if (this._isUpdatingFromInput) return;
                            if (this.htmlMode) return;
                            if (!this.$editable()) return;

                            const currentHtml = this.$editable().innerHTML || '';
                            const newHtml = val || '';

                            if (currentHtml !== newHtml && oldVal !== undefined) {
                                const editable = this.$editable();
                                editable.contentEditable = 'false';
                                editable.innerHTML = newHtml;

                                queueMicrotask(() => {
                                    editable.contentEditable = !this.disabled ? 'true' : 'false';
                                });
                            }
                        });
                    }
                };

                this.$nextTick(() => {
                    if (this.$editable()) {
                        initEditor();
                    } else {
                        requestAnimationFrame(() => {
                            initEditor();
                        });
                    }
                });
            },

            toggleHtmlMode() {
                this.htmlMode = !this.htmlMode;
                if (!this.htmlMode) {
                    this.$nextTick(() => {
                        if (this.$editable()) {
                            this.$editable().innerHTML = this.html || '';
                        }
                    });
                }
            },

            onInput() {
                if (!this.$editable() || this.htmlMode) return;

                this._isUpdatingFromInput = true;
                this.html = this.$editable().innerHTML;
                this.$dispatch('input', this.html);

                this.$nextTick(() => {
                    this._isUpdatingFromInput = false;
                });
            },

            cmd(command) {
                if (this.disabled) return;
                document.execCommand(command, false, null);
                this.onInput();
            },

            toggleHeading(level) {
                if (this.disabled) return;
                if (level === 1) return;
                document.execCommand('formatBlock', false, 'H' + level);
                this.onInput();
            },

            setParagraph() {
                if (this.disabled) return;
                document.execCommand('formatBlock', false, 'P');
                this.onInput();
            },

            setLink() {
                if (this.disabled) return;
                const url = prompt('URL', 'https://');
                if (!url) return;
                document.execCommand('createLink', false, url);
                this.onInput();
            },

            unsetLink() {
                if (this.disabled) return;
                document.execCommand('unlink', false, null);
                this.onInput();
            },

            toggleBlockquote() {
                if (this.disabled) return;
                document.execCommand('formatBlock', false, 'blockquote');
                this.onInput();
            }
        };
    };

    const defineAlpineWysiwyg = () => {
        if (window.Alpine && typeof Alpine.data === 'function') {
            Alpine.data('alpineWysiwyg', ({ initial, disabled }) => {
                return {
                    html: initial || '',
                    disabled: !!disabled,
                    htmlMode: false,
                    _isUpdatingFromInput: false, // Vlag om te voorkomen dat watcher reageert tijdens user input

                    $editable() {
                        return this.$refs.editable;
                    },

                    init() {
                        const initEditor = () => {
                            if (this.$editable()) {
                                const serverContent = this.$editable().innerHTML || '';
                                
                                // If server rendered content and Alpine's html is empty or different,
                                // sync from server content (handles morph case)
                                if (serverContent && !this.html) {
                                    this.html = serverContent;
                                } else if (this.html) {
                                    this.$editable().innerHTML = this.html;
                                }

                                // Sync external model to editor when changed via x-model
                                // Deze watcher reageert alleen op externe wijzigingen (van buitenaf via x-model)
                                this.$watch('html', (val, oldVal) => {
                                    // Als we zelf updaten vanuit onInput, negeer
                                    if (this._isUpdatingFromInput) return;

                                    // Als we in HTML mode zijn, negeer
                                    if (this.htmlMode) return;

                                    if (!this.$editable()) return;

                                    const currentHtml = this.$editable().innerHTML || '';
                                    const newHtml = val || '';

                                    // Update als het anders is, OF als oldVal undefined is EN de editor leeg is EN er is een nieuwe waarde
                                    const shouldUpdate = (currentHtml !== newHtml && oldVal !== undefined) || 
                                                       (oldVal === undefined && !currentHtml && newHtml);
                                    
                                    if (shouldUpdate) {
                                        // Tijdelijk verwijder input listener om recursie te voorkomen
                                        const editable = this.$editable();
                                        editable.contentEditable = 'false';

                                        editable.innerHTML = newHtml;

                                        // Herstel na een microtask
                                        queueMicrotask(() => {
                                            editable.contentEditable = !this.disabled ? 'true' : 'false';
                                        });
                                    }
                                });
                            }
                        };

                        this.$nextTick(() => {
                            if (this.$editable()) {
                                initEditor();
                            } else {
                                requestAnimationFrame(() => {
                                    initEditor();
                                });
                            }
                        });
                    },

                    toggleHtmlMode() {
                        this.htmlMode = !this.htmlMode;
                        if (!this.htmlMode) {
                            this.$nextTick(() => {
                                if (this.$editable()) {
                                    this.$editable().innerHTML = this.html || '';
                                }
                            });
                        }
                    },

                    onInput() {
                        if (!this.$editable() || this.htmlMode) return;

                        // Zet vlag om watcher te blokkeren
                        this._isUpdatingFromInput = true;

                        // Update html
                        this.html = this.$editable().innerHTML;

                        // Dispatch event voor wire:model
                        this.$dispatch('input', this.html);

                        // Reset vlag na reactivity cycle
                        this.$nextTick(() => {
                            this._isUpdatingFromInput = false;
                        });
                    },

                    cmd(command) {
                        if (this.disabled) return;
                        document.execCommand(command, false, null);
                        this.onInput();
                    },

                    toggleHeading(level) {
                        if (this.disabled) return;
                        if (level === 1) return;
                        document.execCommand('formatBlock', false, 'H' + level);
                        this.onInput();
                    },

                    setParagraph() {
                        if (this.disabled) return;
                        document.execCommand('formatBlock', false, 'P');
                        this.onInput();
                    },

                    setLink() {
                        if (this.disabled) return;
                        const url = prompt('URL', 'https://');
                        if (!url) return;
                        document.execCommand('createLink', false, url);
                        this.onInput();
                    },

                    unsetLink() {
                        if (this.disabled) return;
                        document.execCommand('unlink', false, null);
                        this.onInput();
                    },

                    toggleBlockquote() {
                        if (this.disabled) return;
                        document.execCommand('formatBlock', false, 'blockquote');
                        this.onInput();
                    }
                };
            });
        }
    };

    if (window.Alpine) {
        defineAlpineWysiwyg();
    }

    document.addEventListener('alpine:init', () => {
        defineAlpineWysiwyg();
    });

    if (window.Livewire) {
        document.addEventListener('livewire:init', () => {
            defineAlpineWysiwyg();
        });

        // Re-initialize after Livewire updates to ensure new components work
        document.addEventListener('livewire:morph', () => {
            if (window.Alpine && typeof Alpine.data === 'function' && !Alpine.data('alpineWysiwyg')) {
                defineAlpineWysiwyg();
            }
            if (window.Alpine && typeof Alpine.initTree === 'function') {
                setTimeout(() => {
                    document.querySelectorAll('[x-data*="alpineWysiwyg"]').forEach(el => {
                        if (!el._x_dataStack) {
                            Alpine.initTree(el);
                        }
                    });
                }, 0);
            }
        });
    }
}
