#include parsing.js
#include utility.js
#include ext/eeprom.js

const MszMessagesReply = function(element) {
    if(!(element instanceof Element))
        throw 'element must be an Element';

    const form = element.querySelector('.js-messages-reply-form');
    const bodyElem = form.querySelector('.js-messages-reply-body');
    const actsElem = form.querySelector('.js-messages-reply-actions');
    const parserSelect = form.querySelector('.js-messages-reply-parser');
    const saveBtn = form.querySelector('.js-messages-reply-save');
    const sendBtn = form.querySelector('.js-messages-reply-send');
    const warnElem = form.querySelector('.js-reply-form-warning');
    const warnText = warnElem instanceof Element ? warnElem.querySelector('.js-reply-form-warning-text') : undefined;

    let submitHandler;
    form.addEventListener('submit', ev => {
        ev.preventDefault();

        if(typeof submitHandler === 'function') {
            const fields = Array.from(form.elements);
            const result = {};

            for(const field of fields) {
                if((field instanceof HTMLButtonElement || (field instanceof HTMLInputElement && field.type === 'submit')) && ev.submitter !== field)
                    continue;

                if(typeof field.name === 'string' && field.name.length > 0)
                    result[field.name] = field.value;
            }

            submitHandler(result);
        }
    });

    bodyElem.addEventListener('keydown', ev => {
        if((ev.code === 'Enter' || ev.code === 'NumpadEnter') && ev.ctrlKey && !ev.altKey && !ev.metaKey) {
            ev.preventDefault();

            if(ev.shiftKey)
                saveBtn.click();
            else
                sendBtn.click();
        }
    });

    const switchButtons = parser => {
        $removeChildren(actsElem);

        const tags = MszParsing.getTagsFor(parser);
        actsElem.hidden = tags.length < 1;
        for(const tag of tags)
            actsElem.appendChild(<button class="messages-reply-action" type="button" title={tag.summary} onclick={() => $insertTags(bodyElem, tag.open, tag.close)}>
                <i class={tag.icon}/>
            </button>);
    };

    switchButtons(parserSelect.value);

    parserSelect.addEventListener('change', () => {
        switchButtons(parserSelect.value);
    });

    // this implementation is godawful but it'll do for now lol
    // need to make it easier to share the forum's implementation
    const storagePool = $meta.get('messages-storage-pool');
    if(storagePool) {
        const eepromClient = new MszEEPROM(storagePool);
        const eepromHandleFileUpload = async file => {
            const uploadTask = eepromClient.create(file);

            try {
                const fileInfo = await uploadTask.start();
                const parserMode = parseInt(parserSelect.value);
                let insertText = location.protocol + fileInfo.url;

                if(parserMode == 1) { // bbcode
                    if(fileInfo.isImage())
                        insertText = `[img]${fileInfo.url}[/img]`;
                    else if(fileInfo.isAudio())
                        insertText = `[audio]${fileInfo.url}[/audio]`;
                    else if(fileInfo.isVideo())
                        insertText = `[video]${fileInfo.url}[/video]`;
                } else if(parserMode == 2) { // markdown
                    if(fileInfo.isMedia())
                        insertText = `![](${fileInfo.url})`;
                }

                $insertTags(bodyElem, insertText, '');
                bodyElem.value = bodyElem.value.trim();
            } catch(ex) {
                let errorText = 'Upload aborted.';

                if(!ex.aborted) {
                    console.error(ex);
                    errorText = ex.toString();
                }

                await MszShowMessageBox(errorText, 'Upload Error');
            }
        };

        bodyElem.addEventListener('paste', ev => {
            if(ev.clipboardData && ev.clipboardData.files.length > 0) {
                ev.preventDefault();

                const files = ev.clipboardData.files;
                for(const file of files)
                    eepromHandleFileUpload(file);
            }
        });

        document.body.addEventListener('dragenter', ev => {
            ev.preventDefault();
            ev.stopPropagation();
        });
        document.body.addEventListener('dragover', ev => {
            ev.preventDefault();
            ev.stopPropagation();
        });
        document.body.addEventListener('dragleave', ev => {
            ev.preventDefault();
            ev.stopPropagation();
        });
        document.body.addEventListener('drop', ev => {
            ev.preventDefault();
            ev.stopPropagation();

            if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
                const files = ev.dataTransfer.files;
                for(const file of files)
                    eepromHandleFileUpload(file);
            }
        });
    }

    return {
        get element() { return element; },
        setWarning: text => {
            if(warnElem === undefined || warnText === undefined)
                return;

            if(text === undefined) {
                warnElem.hidden = true;
                warnText.textContent = '';
            } else {
                warnElem.hidden = false;
                warnText.textContent = text;
            }
        },
        setRecipient: userId => {
            for(const field of form.elements)
                if(field.name === 'recipient') {
                    field.value = userId;
                    break;
                }
        },
        getHidden: () => element.hidden,
        setHidden: state => {
            element.hidden = state;
        },
        onSubmit: handler => {
            if(typeof handler !== 'function')
                throw 'handler must be a function';

            submitHandler = handler;
        },
    };
};