#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 eepromClient = new MszEEPROM(peepApp, peepPath);
    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;
        },
    };
};