import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, forwardRef, Input, Output, Component } from '@angular/core';
import * as i1 from '@ckeditor/ckeditor5-angular';
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
import { ClassicEditor, Essentials, FontColor, Paragraph, Bold, Italic, Underline, Link, List, Undo, Widget, Markdown, Mention } from 'ckeditor5';
import { Subscription, Subject } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

/**
 * Component sd-mini-editor - Editor đơn giản cho comment input
 * Sử dụng CKEditor với chế độ đơn giản (bold, italic, link)
 * Hỗ trợ mention và output format (html/markdown)
 *
 * @example
 * ```html
 * <sd-mini-editor
 *   [option]="editorOption"
 *   [(ngModel)]="content"
 *   (contentChange)="onContentChange($event)"
 * >
 * </sd-mini-editor>
 * ```
 */
class SdMiniEditor {
    /** Cấu hình option cho editor */
    option;
    /** NgModel binding - nội dung HTML/Markdown */
    value = '';
    valueChange = new EventEmitter();
    /** Event emitter khi content thay đổi */
    contentChange = new EventEmitter();
    /** Event emitter khi blur */
    blur = new EventEmitter();
    /** Event emitter khi focus */
    focus = new EventEmitter();
    /** Disabled state */
    disabled = false;
    Editor = ClassicEditor;
    #editor;
    #subscription = new Subscription();
    #contentChangeSubject = new Subject();
    // Build editor config dynamically
    get editorConfig() {
        const enableMention = this.option?.enableMention ?? false;
        const useMarkdown = this.option?.outputFormat === 'markdown';
        const plugins = [Essentials, FontColor, Paragraph, Bold, Italic, Underline, Link, List, Undo, Widget];
        // Add Markdown plugin if outputFormat is markdown
        if (useMarkdown) {
            plugins.push(Markdown);
        }
        // Add Mention plugin if enabled
        if (enableMention) {
            plugins.push(Mention);
        }
        // Build base config
        const config = {
            licenseKey: 'GPL',
            getOption: () => this.option,
            plugins,
            toolbar: {
                items: ['bold', 'italic', 'underline', '|', 'fontColor', '|', 'bulletedList', 'numberedList', '|', 'link'],
                shouldNotGroupWhenFull: true,
            },
            placeholder: this.option?.placeholder,
            link: {
                addTargetToExternalLinks: true,
                defaultProtocol: 'https://',
            },
            fontColor: {
                columns: 5,
                documentColors: 10,
                colorPicker: { format: 'hex' },
            },
        };
        // Add mention configuration if enabled
        if (enableMention && this.option?.mentionConfig?.feeds) {
            config.mention = {
                feeds: this.option.mentionConfig.feeds,
            };
        }
        return config;
    }
    constructor() {
        // Setup debounce cho content change
        this.#subscription.add(this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {
            const output = this.#convertOutput(content);
            this.value = output;
            this.#onChange(output);
            this.valueChange.emit(output);
            this.contentChange.emit(output);
            this.option?.onChange?.(output);
        }));
    }
    ngOnDestroy() {
        this.#subscription.unsubscribe();
        this.#editor?.destroy?.();
    }
    /**
     * Kiểm tra có nên enable mention plugin không
     */
    #shouldEnableMention() {
        return this.option?.enableMention ?? false;
    }
    /**
     * Xử lý khi editor ready
     */
    onReady(editor) {
        this.#editor = editor;
        // Set initial content
        if (this.value) {
            this.setContent(this.value);
        }
        // Lắng nghe sự kiện thay đổi nội dung
        editor.model.document.on('change:data', () => {
            const content = editor.getData();
            this.#contentChangeSubject.next(content);
        });
        // Lắng nghe focus/blur events
        editor.editing.view.document.on('focus', evt => {
            const domEvent = evt.domEvent;
            this.focus.emit(domEvent);
            this.option?.onFocus?.(domEvent);
        });
        editor.editing.view.document.on('blur', evt => {
            const domEvent = evt.domEvent;
            this.blur.emit(domEvent);
            this.option?.onBlur?.(domEvent);
        });
        // Lắng nghe sự kiện mention được chọn
        if (this.#shouldEnableMention()) {
            editor.commands.get('mention')?.on('execute', (_evt, data) => {
                const mentionData = data[0];
                this.option?.onMentionSelect?.(mentionData.mention);
                // Trigger content change sau khi insert mention
                const content = editor.getData();
                this.#contentChangeSubject.next(content);
            });
            // Custom downcast converter để thay đổi cấu trúc mention HTML
            editor.conversion.for('downcast').attributeToElement({
                model: 'mention',
                view: (mentionData, { writer }) => {
                    const data = mentionData;
                    const rawId = data?.id || '';
                    const marker = rawId[0];
                    const cleanId = rawId.slice(1);
                    return writer.createAttributeElement('span', {
                        class: 'ck-custom-mention',
                        'data-id': cleanId,
                        'data-marker': marker,
                        contenteditable: 'false',
                    });
                },
                converterPriority: 'highest',
            });
            // Xử lý keyboard để xóa mention 1 lần
            editor.editing.view.document.on('keydown', (evt, data) => {
                const keyEvent = data;
                // Delete (46) hoặc Backspace (8)
                if (keyEvent.keyCode === 46 || keyEvent.keyCode === 8) {
                    const model = editor.model;
                    const selection = model.document.selection;
                    const position = selection.getFirstPosition();
                    if (!position)
                        return;
                    // Tìm text node có mention attribute
                    const node = position.textNode || position.nodeBefore || position.nodeAfter;
                    if (node && node.is('$text')) {
                        const mentionAttr = node.getAttribute('mention');
                        if (mentionAttr) {
                            // Xóa toàn bộ text node chứa mention
                            model.change(writer => {
                                writer.remove(node);
                            });
                            evt.stop();
                        }
                    }
                }
            });
        }
    }
    /**
     * Convert output theo format (html hoặc markdown)
     * Khi sử dụng CKEditor Markdown plugin, getData() tự động trả về Markdown
     */
    #convertOutput(content) {
        // CKEditor Markdown plugin tự động xử lý conversion
        // Không cần manual conversion nữa
        return content;
    }
    /**
     * Set nội dung cho editor
     */
    setContent(content) {
        this.#editor?.setData?.(content);
    }
    /**
     * Get nội dung từ editor
     */
    getContent() {
        if (this.#editor) {
            const html = this.#editor.getData();
            return this.#convertOutput(html);
        }
        return '';
    }
    /**
     * Get nội dung HTML gốc (không convert)
     */
    getHtmlContent() {
        return this.#editor?.getData?.() || '';
    }
    /**
     * Focus vào editor
     */
    focusEditor() {
        this.#editor?.editing?.view?.focus?.();
    }
    /**
     * Insert mention vào vị trí con trỏ hiện tại
     */
    insertMention(item) {
        if (!this.#editor)
            return;
        const firstFeed = this.option?.mentionConfig?.feeds?.[0];
        const marker = item.marker || firstFeed?.marker || '@';
        // Sử dụng CKEditor mention command
        this.#editor.execute('mention', {
            marker,
            mention: {
                id: item.id,
                text: `${marker}${item.name}`,
            },
        });
    }
    /**
     * Get danh sách mentions trong nội dung
     */
    getMentions() {
        if (!this.#editor)
            return [];
        const mentions = [];
        const root = this.#editor.model.document.getRoot();
        if (!root)
            return mentions;
        const range = this.#editor.model.createRangeIn(root);
        for (const item of range.getItems()) {
            if (item.is('$text')) {
                const mentionAttr = item.getAttribute('mention');
                if (mentionAttr) {
                    const text = item.data;
                    const marker = text.charAt(0);
                    const name = text.substring(1);
                    const id = item.getAttribute('data-user-id');
                    mentions.push({ id, name, marker });
                }
            }
        }
        return mentions;
    }
    /**
     * ControlValueAccessor: Write value
     */
    writeValue(value) {
        this.value = value || '';
        if (this.#editor) {
            this.setContent(this.value);
        }
    }
    /**
     * ControlValueAccessor: Register change callback
     */
    registerOnChange(fn) {
        this.#onChange = fn;
    }
    /**
     * ControlValueAccessor: Register touched callback
     */
    registerOnTouched(fn) {
        this.#onTouched = fn;
    }
    /** ControlValueAccessor callbacks */
    #onChange = () => { };
    #onTouched = () => { };
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdMiniEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdMiniEditor, isStandalone: true, selector: "sd-mini-editor", inputs: { option: "option", value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange", contentChange: "contentChange", blur: "blur", focus: "focus" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => SdMiniEditor),
                multi: true,
            },
        ], ngImport: i0, template: "<div class=\"sd-mini-editor\" [style.height]=\"option.height || 'auto'\">\r\n  <ckeditor [editor]=\"Editor\" [config]=\"editorConfig\" [disabled]=\"disabled\" (ready)=\"onReady($event)\"> </ckeditor>\r\n</div>\r\n", styles: [".sd-mini-editor{display:block;width:100%}::ng-deep .ck-mentions .ck-button.ck-on{background:var(--sd-primary)!important;color:#fff!important}::ng-deep .ck-mentions .ck-button.ck-on *{color:#fff!important}:host ::ng-deep .ck-editor{--ck-content-font-size: 14px;--ck-content-line-height: 1.5}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}:host ::ng-deep .ck-custom-mention{font-weight:600;padding:0 2px;display:inline-block;pointer-events:none;-webkit-user-select:none;user-select:none;color:#2962ff}:host ::ng-deep .ck-custom-mention:before{content:attr(data-marker)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CKEditorModule }, { kind: "component", type: i1.CKEditorComponent, selector: "ckeditor", inputs: ["editor", "config", "data", "tagName", "watchdog", "editorWatchdogConfig", "disableWatchdog", "disableTwoWayDataBinding", "disabled"], outputs: ["ready", "change", "blur", "focus", "error"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdMiniEditor, decorators: [{
            type: Component,
            args: [{ selector: 'sd-mini-editor', standalone: true, imports: [CommonModule, CKEditorModule], providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => SdMiniEditor),
                            multi: true,
                        },
                    ], template: "<div class=\"sd-mini-editor\" [style.height]=\"option.height || 'auto'\">\r\n  <ckeditor [editor]=\"Editor\" [config]=\"editorConfig\" [disabled]=\"disabled\" (ready)=\"onReady($event)\"> </ckeditor>\r\n</div>\r\n", styles: [".sd-mini-editor{display:block;width:100%}::ng-deep .ck-mentions .ck-button.ck-on{background:var(--sd-primary)!important;color:#fff!important}::ng-deep .ck-mentions .ck-button.ck-on *{color:#fff!important}:host ::ng-deep .ck-editor{--ck-content-font-size: 14px;--ck-content-line-height: 1.5}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}:host ::ng-deep .ck-custom-mention{font-weight:600;padding:0 2px;display:inline-block;pointer-events:none;-webkit-user-select:none;user-select:none;color:#2962ff}:host ::ng-deep .ck-custom-mention:before{content:attr(data-marker)}\n"] }]
        }], ctorParameters: () => [], propDecorators: { option: [{
                type: Input,
                args: [{ required: true }]
            }], value: [{
                type: Input
            }], valueChange: [{
                type: Output
            }], contentChange: [{
                type: Output
            }], blur: [{
                type: Output
            }], focus: [{
                type: Output
            }], disabled: [{
                type: Input
            }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { SdMiniEditor };
//# sourceMappingURL=sd-angular-core-components-mini-editor.mjs.map
