"use strict";
function aiomatic_uniq_fast(a) 
{
    var seen = {};
    var out = [];
    var len = a.length;
    var j = 0;
    for(var i = 0; i < len; i++) {
        var item = a[i];
        var jsit = JSON.stringify(item);
        if(seen[jsit] !== 1) {
              seen[jsit] = 1;
              out[j++] = item;
        }
    }
    return out;
}
(function() {
    let menu = [];
    tinymce.create("tinymce.plugins.aiomatic_editor", {
        init : function(ed, url) { 
            if ("object" == typeof aiomatic && "object" == typeof aiomatic.prompts)
            {
                for (let operation in aiomatic.prompts) 
                {
                    let prompt = aiomatic.prompts[operation];
                    let icon = 'text';
                    let thumb = 'toc';
                    if(prompt[1] == 'image')
                    {
                        icon = 'format-image';
                        thumb = 'image';
                    }
                    menu.push({
                        text: operation,
                        classes: 'aiomatic-classic-button',
                        icon: thumb,
                        onclick: async function () {
                            ed = tinymce.activeEditor;
                            let selectedText = ed.selection.getContent({format: 'text'});
                            let send_prompt = prompt[0].replace('%%selected_text%%', selectedText);
                            if(send_prompt.includes('%%'))
                            {
                                var pid = document.getElementById('post_ID');
                                if(pid !== undefined && pid !== null && pid != '')
                                {
                                    var postId = pid.value;
                                    const ajaxurl = aiomatic.ajaxurl;
                                    const nonce = aiomatic.nonce;
                                    const xdata = new FormData();
                                    xdata.append( 'postId', postId );
                                    xdata.append( 'nonce', nonce );
                                    xdata.append( 'send_prompt', send_prompt );
                                    xdata.append( 'action', 'aiomatic_shortcode_replacer' );
                                    const response = await fetch(ajaxurl, {
                                        method: 'POST',
                                        body: xdata
                                    }).catch(async error => {
                                        console.log('An exception occurred: ' + error.text());
                                    })

                                    if (!response.ok) 
                                    {
                                        console.log('An error occurred: ' + response.text());
                                    }
                                    else
                                    {
                                        const ret = await response.json();
                                        if (ret.message !== undefined) {
                                            console.log('A general error occurred: ' + response.text());
                                        }
                                        else
                                        {
                                            send_prompt = ret.data.content;
                                        }
                                    }
                                }
                            }
                            let dom = tinymce.activeEditor.dom;
                            let $ = tinymce.dom.DomQuery;
        
                            const loadingSpinnerId = await aiomatic_classic_addAutocompleteContainer(aiomatic.placement, ed);
        
                            ed.selection.collapse();
                            let spinner = dom.select('#' + loadingSpinnerId);
        
                            let autocompletedText = '';
                            try {
                                if(icon == 'text')
                                {
                                    autocompletedText = await aiomatic_classic_doAutocompleteRequest(send_prompt);
                                    if(autocompletedText === undefined)
                                    {
                                        throw new Error('Failed to generate text!');
                                    }
                                    autocompletedText = autocompletedText.replace(/\n/g, '<br/>');
                                }
                                else
                                {
                                    if(icon == 'format-image')
                                    {
                                        autocompletedText = await aiomatic_classic_doImageRequest(send_prompt);
                                        if(autocompletedText === undefined)
                                        {
                                            throw new Error('Failed to generate text!');
                                        }
                                    }
                                }
                            } catch (error) {
                                $(spinner).remove();
                                alert('An API error occurred with the following response body: \n\n' + error.message);
                                return;
                            }
        
                            $(spinner).removeAttr('class');
                            $(spinner).removeAttr('id');
        
                            $(spinner).html(autocompletedText);
        
                            ed.undoManager.add();
                        }
                    });
                }
                var uniqueMenu = aiomatic_uniq_fast(menu);
                uniqueMenu.forEach((item, index) => {
                    item.id = `menuitem-${index}`;
                });
                ed.addButton("aiomatic", {
                    type: 'menubutton',
                    title : "Aimogen Content Wizard",
                    tooltip: 'Aimogen Content Wizard',
                    image: aiomatic.xicon,
                    icon: false,
                    menu: uniqueMenu
                });
            }
        },
        createControl : function(n, cm) {
            return null;
        },
        getInfo : function() {
            return {
                longname : "Aimogen Buttons",
                author : "CodeRevolution",
                version : "1.0"
            };
        }
    });
    tinymce.PluginManager.add("aiomatic_editor", tinymce.plugins.aiomatic_editor);
})();

const aiomatic_createLoadingSpinner = function (selectedNode, loadingSpinnerId) {
    let spinnersrc = "data:image/gif;base64, ";
    let spinnerHtml = '';
    if (['li'].includes(selectedNode.tagName.toLowerCase())) {
        spinnerHtml = '<' + selectedNode.tagName + ' id="' + loadingSpinnerId + '" class="aiomatic-mce-loading"><img src="' + spinnersrc + '"></' + selectedNode.tagName + '>';
    } else {
        spinnerHtml = '<p id="' + loadingSpinnerId + '" class="aiomatic-mce-loading"><img src="' + spinnersrc + '"></p>';
    }

    return spinnerHtml;
}

const aiomatic_classic_doAutocompleteRequest = async function (text) {
    const ajaxurl = aiomatic.ajaxurl;
    const nonce = aiomatic.nonce;
    const xdata = new FormData();
    xdata.append( 'prompt', text );
    xdata.append( 'nonce', nonce );
    xdata.append( 'action', 'aiomatic_editor' );
    const response = await fetch(ajaxurl, {
        method: 'POST',
        body: xdata
    }).catch(async error => {
        throw new Error(await error.text());
    })

    if (!response.ok) {
        throw new Error(await response.text());
    }

    const ret = await response.json();
    if (ret.message !== undefined) {
        throw new Error(await response.text());
    }
    return ret.data.content;
}

const aiomatic_classic_doImageRequest = async function (text) {
    const ajaxurl = aiomatic.ajaxurl;
    const nonce = aiomatic.nonce;
    const xdata = new FormData();
    xdata.append( 'prompt', text );
    xdata.append( 'nonce', nonce );
    xdata.append( 'action', 'aiomatic_imager' );
    const response = await fetch(ajaxurl, {
        method: 'POST',
        body: xdata
    }).catch(async error => {
        throw new Error(await error.text());
    })

    if (!response.ok) {
        throw new Error(await response.text());
    }

    const ret = await response.json();
    if (ret.message !== undefined) {
        throw new Error(await response.text());
    }
    return ret.data.content;
}
const aiomatic_classic_addAutocompleteContainer = async function (placement, ed) {
    let $ = tinymce.dom.DomQuery;
    const loadingSpinnerId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);

    let selectionRange = ed.selection.getRng();
    if (placement === 'below') {
        let selectedNode = ed.selection.getEnd();

        let spinnerHtml = aiomatic_createLoadingSpinner(
            selectedNode,
            loadingSpinnerId,
        )
        let spinnerDom = $(spinnerHtml)[0];

        let parentNode = selectionRange.endContainer.parentNode;
        if (parentNode.tagName.toLowerCase() === 'li') {
            $(selectedNode).after(spinnerDom);
        } else if (selectedNode.textContent) {
            selectionRange.collapse(false);
            selectionRange.insertNode(spinnerDom);
            ed.selection.collapse();
        } else {
            $(selectedNode).after(spinnerDom);
        }

    } else { 
        let selectedNode = ed.selection.getStart();
        let spinnerHtml = aiomatic_createLoadingSpinner(
            selectedNode,
            loadingSpinnerId,
        )
        let spinnerDom = $(spinnerHtml)[0];

        let parentNode = selectionRange.startContainer.parentNode;
        if (parentNode.tagName.toLowerCase() === 'li') {
            $(selectedNode).before(spinnerDom);
        } else if (selectedNode.textContent) {
            selectionRange.collapse(true);
            selectionRange.insertNode(spinnerDom);
            ed.selection.collapse();
        } else {
            $(selectedNode).before(spinnerDom);
        }
    }

    ed.undoManager.add();

    return loadingSpinnerId;
}