#include parsing.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 => {
        $rc(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
    MszEEPROM.init()
        .catch(() => console.error('Failed to initialise EEPROM'))
        .then(() => {
            const eepromClient = new EEPROM(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 {
        getElement: () => 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;
        },
    };
};
