$(function () {
    // List of common (expected?) image types and their file extensions. Used
    // to generate a filename, if needed.
    const mimeMap = {
        'image/avif': '.avif',
        'image/bmp': '.bmp',
        'image/gif': '.gif',
        'image/jpeg': '.jpg',
        'image/png': '.png',
        'image/svg+xml': '.svg',
        'image/tiff': '.tiff',
        'image/webp': '.webp',
    };

    function getDropzone() {
        const dropElem = document.getElementById('attachment_upload');
        if (dropElem != null && dropElem.dropzone) {
            if (dropElem.dropzonePatched != true) {
                // On success, resolve the inline promise
                dropElem.dropzone.on('success', function (file, responseText, ev) {
                    if (!('inlinePromise' in file)) {
                        // not ours, don't care
                        return;
                    }

                    const { resolve, reject } = file.inlinePromise;

                    if (!responseText || responseText.generalErrors) {
                        // smf_fileUpload will handle the error. let's just get
                        // out of here
                        reject();
                        return;
                    }

                    const response = responseText.files[0];
                    if (response.errors != null && response.errors.length > 0) {
                        reject();
                        return;
                    }

                    resolve(response);
                });
                // On error, reject the inline promise
                dropElem.dropzone.on('error', function (file, errorMessage, xhr) {
                    // just reject, we don't need to do anything
                    if ('inlinePromise' in file) {
                        file.inlinePromise.reject();
                    }
                });
                // ensure this is only run once
                dropElem.dropzonePatched = true;
            }
            return dropElem.dropzone;
        }
        return null;
    }


    sceditor.plugins.dragdrop_attach = function () {
        var editor;

        function inlineAttach(file, createPlaceholder) {
            const dropzone = getDropzone();
            if (dropzone == null) { 
                throw new Error('missing dropzone');
            }

            // Pasted inline images don't necessarily have file names :<
            if (file.name == null) {
                const ext = mimeMap[file.type];
                if (ext == null) {
                    throw new Error('Unexpected mime type ' + file.type);
                }
                file.name = 'image' + ext;
            }

            const placeholder = (editor.inSourceMode() || createPlaceholder == null)
                    ? null
                    : createPlaceholder();

            new Promise(function(resolve, reject) {
                file.inlinePromise = {
                    resolve: resolve,
                    reject: reject,
                };
                dropzone.addFile(file);
            }).then(function(response) {
                const bbcode = '[attach id=' + response.attachID + ']' + response.name + '[/attach]';
                if (placeholder) {
                    placeholder.insert(editor.fromBBCode(bbcode));
                } else {
                    editor.insertText(bbcode);
                }
            }).catch(function() {
                if (placeholder) {
                    placeholder.cancel();
                }
            });
        }

        this.signalReady = function () {
            editor = this;
            // This requires our customized sceditor.dragdrop.js, otherwise
            // we'd be in a potential race condition depending on whether
            // dragdrop or our plugin is loaded first
            this.opts.dragdrop = this.opts.dragdrop || {};
            if (this.opts.dragdrop.handleFile == null) {
                this.opts.dragdrop.handleFile = inlineAttach;
            }
        }
    }
});
