<link rel="stylesheet" href="~/lib/ckeditor/browser/ckeditor5.css" asp-append-version="true" />

<script type="module">
    import {
        ClassicEditor, Essentials, Paragraph, Bold, Italic, Underline, Strikethrough, Code, Subscript, Superscript, RemoveFormat, List, TodoList,
        Indent, Heading, Font, Highlight, Alignment, Link, Image, ImageToolbar, ImageCaption, ImageStyle, ImageResize, ImageUpload, MediaEmbed, CodeBlock,
        HtmlEmbed, SpecialCharacters, HorizontalLine, PageBreak, SourceEditing, FindAndReplace, SelectAll, BlockQuote, Table, TableToolbar, TextPartLanguage
    } from "/lib/ckeditor/browser/ckeditor5.js";

    class CustomImageAttributesPlugin {
        constructor(editor) {
            this.editor = editor;
        }

        init() {
            const editor = this.editor;
            const schema = editor.model.schema;

            // data-* 속성을 추가
            const attributes = ['data-name', 'data-extension', 'data-size', 'data-type', 'data-width', 'data-height'];
            schema.extend('imageBlock', {allowAttributes: attributes});
            schema.extend('imageInline', {allowAttributes: attributes});

            editor.plugins.get('ImageUploadEditing').on('uploadComplete', (evt, { data, imageElement }) => {
                editor.model.change((writer) => {
                    writer.setAttribute('data-name', data.name, imageElement);
                    writer.setAttribute('data-extension', data.extension, imageElement);
                    writer.setAttribute('data-size', data.size, imageElement);
                    writer.setAttribute('data-type', data.type, imageElement);
                });
            });

            attributes.forEach(attr => {
                editor.conversion.for('upcast').attributeToAttribute({ model: attr, view: attr });
            });

            attributes.forEach(attr => {
                editor.conversion.for('downcast').attributeToAttribute({ model: attr, view: attr });
                editor.conversion.for('editingDowncast').attributeToAttribute({ model: attr, view: attr });
            });

            const updateDataAttribute = (evt, data, conversionApi) => {
                const viewWriter = conversionApi.writer;
                const viewElement = conversionApi.mapper.toViewElement(data.item);

                if (viewElement) {
                    const imgElement = viewElement.getChild(0);
                    if (imgElement && imgElement.is('element', 'img')) {
                        viewWriter.setAttribute(data.attributeKey, data.attributeNewValue, imgElement);
                    }
                }
            };

            attributes.forEach(attribute => {
                editor.conversion.for('downcast').add(dispatcher => {
                    dispatcher.on(`attribute:${attribute}:imageBlock`, (evt, data, conversionApi) => {
                        updateDataAttribute(evt, data, conversionApi);
                    });
                });

                editor.conversion.for('editingDowncast').add(dispatcher => {
                    dispatcher.on(`attribute:${attribute}:imageInline`, (evt, data, conversionApi) => {
                        updateDataAttribute(evt, data, conversionApi);
                    });
                });
            });
        }
    }

    class CustomUploadAdapter {
        constructor(loader) {
            this.loader = loader;
        }

        upload() {
            return this.loader.file.then(file => {
                return new Promise((resolve, reject) => {
                    const reader = new FileReader();

                    reader.onload = () => {
                        resolve({
                            default: reader.result,
                            name: file.name,
                            extension: file.name.split('.').pop(),
                            size: file.size,
                            type: file.type
                        });
                    };

                    reader.onerror = error => reject(error);
                    reader.readAsDataURL(file);
                });
            });
        }

        abort() {
            console.log('업로드가 취소되었습니다.');
        }
    }

    // CKEditor 저장, 전역 변수로 해서 다른 곳에서 접근할 수 있도록 함
    window.editorInstances = window.editorInstances || new Map();

    // CKEditor 초기화
    window.initEditor = async function(domID, config = {})
    {
        const el = document.getElementById(domID);
        if (!el || window.editorInstances.has(domID)) {
            return;
        }

        return ClassicEditor
            .create(el, {
                licenseKey: 'GPL',
                extraPlugins: [CustomUploadAdapter, CustomImageAttributesPlugin],
                plugins: [
                    Essentials, Paragraph, Bold, Italic, Underline, Strikethrough, Code,
                    Subscript, Superscript, RemoveFormat, List, TodoList, Indent, Heading,
                    Font, Highlight, Alignment, Link, Image, ImageToolbar, ImageCaption,
                    ImageStyle, ImageResize, ImageUpload, MediaEmbed, CodeBlock, HtmlEmbed,
                    SpecialCharacters, HorizontalLine, PageBreak, SourceEditing,
                    FindAndReplace, SelectAll, BlockQuote, Table, TableToolbar, TextPartLanguage
                ],
                toolbar: {
                    items: [
                        'findAndReplace', 'selectAll', '|',
                        'heading', '|',
                        'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'removeFormat', '|',
                        'bulletedList', 'numberedList', 'todoList', '|',
                        'outdent', 'indent', '|',
                        'undo', 'redo', '|',
                        'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'highlight', '|',
                        'alignment', '|',
                        'link', 'insertImage', 'blockQuote', 'insertTable', 'mediaEmbed', 'codeBlock', 'htmlEmbed', '|',
                        'specialCharacters', 'horizontalLine', 'pageBreak', '|',
                        'textPartLanguage', '|',
                        'sourceEditing'
                    ],
                    shouldNotGroupWhenFull: true
                },
                list: {
                    properties: {
                        styles: true,
                        startIndex: true,
                        reversed: true
                    }
                },
                heading: {
                    options: [
                        { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
                        { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
                        { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
                        { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
                        { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },
                        { model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' },
                        { model: 'heading6', view: 'h6', title: 'Heading 6', class: 'ck-heading_heading6' }
                    ]
                },
                placeholder: '내용을 입력해주세요.',
                fontFamily: {
                    options: [
                        'default',
                        'Arial, Helvetica, sans-serif',
                        'Courier New, Courier, monospace',
                        'Georgia, serif',
                        'Lucida Sans Unicode, Lucida Grande, sans-serif',
                        'Tahoma, Geneva, sans-serif',
                        'Times New Roman, Times, serif',
                        'Trebuchet MS, Helvetica, sans-serif',
                        'Verdana, Geneva, sans-serif'
                    ],
                    supportAllValues: true
                },
                fontSize: {
                    options: [10, 12, 14, 'default', 18, 20, 22],
                    supportAllValues: true
                },
                htmlSupport: {
                    allow: [
                        {
                            name: /.*/,
                            attributes: true,
                            classes: true,
                            styles: true
                        }
                    ]
                },
                htmlEmbed: {
                    showPreviews: true
                },
                link: {
                    decorators: {
                        addTargetToExternalLinks: true,
                        defaultProtocol: 'https://',
                        toggleDownloadable: {
                            mode: 'manual',
                            label: 'Downloadable',
                            attributes: {
                                download: 'file'
                            }
                        }
                    }
                },
                image: {
                    toolbar: [
                        'imageStyle:inline', 'imageStyle:block', 'imageStyle:side', '|',
                        'toggleImageCaption', 'imageTextAlternative'
                    ]
                },
                table: {
                    contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells']
                },
                simpleUpload: {
                    uploadUrl: null
                },
                ...config
            })
            .then(editor => {
                editor.plugins.get('FileRepository').createUploadAdapter = loader => new CustomUploadAdapter(loader);

                // 에디터 저장
                window.editorInstances.set(domID, editor);
            })
            .catch(error => {
                console.error('Error initializing CKEditor:', error);
            });
    };

    // 에디터 제거
    window.destroyEditor = async function(domID) {
        const editor = window.editorInstances.get(domID);
        if (editor) {
            await editor.destroy();
            window.editorInstances.delete(domID);
        }
    };

    document.querySelectorAll('.ck-editor').forEach(e => {
        initEditor(e.id);
    });
</script>