/**
 * DevExtreme (esm/__internal/ui/html_editor/modules/m_imageUpload.js)
 * Version: 24.1.7-build-24272-1937
 * Build date: Sat Sep 28 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import $ from "../../../../core/renderer";
import {
    extend
} from "../../../../core/utils/extend";
import {
    isDefined
} from "../../../../core/utils/type";
import eventsEngine from "../../../../events/core/events_engine";
import {
    addNamespace
} from "../../../../events/utils/index";
import FileUploader from "../../../../ui/file_uploader";
import Quill from "devextreme-quill";
import {
    getFileUploaderBaseOptions,
    serverUpload
} from "../utils/m_image_uploader_helper";
import BaseModule from "./m_base";
const MODULE_NAMESPACE = "dxHtmlEditorImageUpload";
const HIDDEN_FILE_UPLOADER_CLASS = "dx-htmleditor-hidden-content";
let ImageUploadModule = BaseModule;
if (Quill) {
    ImageUploadModule = class extends BaseModule {
        constructor(quill, options) {
            super(quill, options);
            this.options = options;
            this._quillContainer = this.editorInstance._getQuillContainer();
            this.addCleanCallback(this.prepareCleanCallback());
            this._handleServerUpload()
        }
        _handleServerUpload() {
            const useServerUpload = isDefined(this.options.fileUploadMode) && "base64" !== this.options.fileUploadMode;
            useServerUpload ? this._enableDragAndDropUploading() : this._disableDragAndDropUploading()
        }
        _getUploaderModule() {
            if (!this._uploaderModule) {
                this._uploaderModule = this.quill.getModule("uploader")
            }
            return this._uploaderModule
        }
        _disableDragAndDropUploading() {
            var _this$_fileUploader;
            this._getUploaderModule().preventImageUploading(false);
            this._detachEvents();
            null === (_this$_fileUploader = this._fileUploader) || void 0 === _this$_fileUploader || _this$_fileUploader.dispose()
        }
        _enableDragAndDropUploading() {
            this._initFileUploader();
            this._getUploaderModule().preventImageUploading(true);
            this._attachEvents()
        }
        _initFileUploader() {
            const $container = $("<div>").addClass(HIDDEN_FILE_UPLOADER_CLASS).appendTo(this._quillContainer);
            const fileUploaderOptions = extend({}, getFileUploaderBaseOptions(), {
                uploadUrl: this.options.uploadUrl,
                onUploaded: this._onUploaded.bind(this)
            }, this.options.fileUploaderOptions);
            this._fileUploader = this.editorInstance._createComponent($container, FileUploader, fileUploaderOptions);
            return $container
        }
        _onUploaded(data) {
            const {
                index: pasteIndex
            } = this.quill.getSelection() ?? {
                index: this.quill.getLength()
            };
            serverUpload(this.options.uploadDirectory, data.file.name, this.quill, pasteIndex)
        }
        _attachEvents() {
            eventsEngine.on(this.quill.root, addNamespace("drop", MODULE_NAMESPACE), this._dropHandler.bind(this));
            eventsEngine.on(this.quill.root, addNamespace("paste", MODULE_NAMESPACE), this._pasteHandler.bind(this))
        }
        _detachEvents() {
            eventsEngine.off(this.quill.root, MODULE_NAMESPACE)
        }
        _dropHandler(e) {
            this._handleInsertImages(e, "dataTransfer")
        }
        _pasteHandler(e) {
            this._handleInsertImages(e, "clipboardData")
        }
        _handleInsertImages(e, filesField) {
            this.saveValueChangeEvent(e);
            const files = Array.from(e.originalEvent[filesField].files || []);
            const uploads = files;
            if (uploads.length) {
                e.preventDefault();
                e.stopPropagation();
                this._fileUploader.option("value", uploads);
                this._fileUploader.upload()
            }
        }
        clean() {
            this._disableDragAndDropUploading()
        }
        prepareCleanCallback() {
            return () => {
                this.clean()
            }
        }
        option(option, value) {
            switch (option) {
                case "imageUpload":
                    this.handleOptionChangeValue(value);
                    break;
                case "fileUploadMode":
                    this.options.fileUploadMode = value;
                    this._handleServerUpload();
                    break;
                case "fileUploaderOptions":
                    this._fileUploader.option(value)
            }
        }
    }
}
export default ImageUploadModule;
