// Gutenberg toolbar:
if (assi_plugin_data?.editor_type != undefined) {
    if (assi_plugin_data.editor_type == 'default') {
        (function (wp) {
            const {registerFormatType, toggleFormat, insert, replace, remove} = wp.richText;
            const {BlockControls} = wp.blockEditor;
            const {ToolbarGroup, ToolbarButton, ToolbarDropdownMenu, Dropdown, Button} = wp.components;
            const {createElement, useState, useEffect} = wp.element;
            const {select} = wp.data;

            const MyCustomButton = function (props) {
                const {isActive, onChange, value} = props;

                const [rerenderToken, setRerenderToken] = useState(0);
                useEffect(() => {
                    const handler = () => setRerenderToken(t => t + 1);
                    window.addEventListener('assistiniRerender', handler);
                    return () => window.removeEventListener('assistiniRerender', handler);
                }, []);

                function timeout(ms) {
                    return new Promise(resolve => setTimeout(resolve, ms));
                }
                async function inlineAction(value, templateId = 0) {
                    if (assi_plugin_data?.custom_ai_connection?.active == undefined || assi_plugin_data.custom_ai_connection.active == 0) {
                        if (proxyLiveData.creditsOpen <= 0) {
                            openUpgradeModal();
                            return;
                        }
                    }
                    let cValue = value; 
                    let postContent = select('core/block-editor').getBlocks().map(block => block.attributes?.content || '').join('\n');
                    let content = value.text.slice(value.start, value.end);
                    const newText = ' [AI-Assistant is thinking...] ';
                    if (value?.text && value?.text?.length > 0) {
                        if (content == undefined || content == '') {
                            let dialog = document.getElementById('ass-es-modal-notice');
                            dialog.showModal();
                            jQuery('#ass-es-modal-notice').hide();
                            jQuery('#ass-es-modal-notice').fadeIn(150);                          
                            return;
                        } else {
                            let chars = newText.split('');
                            let insertText = '';
                            for (let i = 0; i < chars.length; i++) {
                                insertText = chars[i];
                                cValue = wp.richText.insert(cValue, insertText);
                                onChange(
                                        cValue
                                        );
                                await timeout(0);
                            }
                            const startIndex = value.start;
                            const endIndex = value.start + chars.length;
                            const startText = value.text.slice(value.start, value.end);

                            const data = await jQuery.ajax({
                                url: ajaxurl,
                                type: 'POST',
                                cache: false,
                                data: {
                                    action: 'assi_editor_inline_send_prompt',
                                    template_id: templateId,
                                    content: value.text.slice(value.start, value.end),
                                    refer_post_content: postContent,
                                    assi_security_nonce: assi_plugin_data.assi_security_nonce,
                                },
                            });
                            const parsedData = JSON.parse(data);
                            if (parsedData.result == undefined || parsedData.result != true || parsedData.content == undefined || parsedData.content.length == 0) {
                                cValue = wp.richText.remove(cValue, startIndex, endIndex);
                                onChange(cValue);
                                cValue = wp.richText.insert(cValue, startText);
                                onChange(cValue);
                                showNotice('error', (parsedData.error_message != undefined ? parsedData.error_message : ''));
                                return;
                            }
                            if (parsedData?.user_data?.credits_open != undefined) {
                                proxyLiveData.creditsOpen = parsedData.user_data.credits_open;
                            }
                            let responseText = parsedData.content[0];

                            cValue = wp.richText.remove(cValue, startIndex, endIndex);
                            onChange(cValue);

                            let chars2 = [];
                            for (let i = 0; i < responseText.length; i += 5) {
                                chars2.push(responseText.slice(i, i + 5));
                            }
                            insertText = '';
                            for (let i = 0; i < chars2.length; i++) {
                                insertText += chars2[i];
                                onChange(
                                        wp.richText.insert(cValue, insertText)
                                        );
                                await timeout(50);
                            }
                        }
                    }
                }

                function openSidebar() {
                    var sidebar = document.getElementById('ass-es');
                    if (sidebar.style.width === '' || sidebar.style.width === '0px') {
                        jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
                    }
                }

                function getInlineActions() {
                    if (globalTemplates == undefined || globalTemplates.length == 0) {
                        return [{
                                title: createElement(
                                        'span',
                                        {
                                            style: {
                                                display: 'flex',
                                                justifyContent: 'space-between',
                                                alignItems: 'center',
                                                width: '100%',
                                                opacity: 0.8,
                                                cursor: 'not-allowed'
                                            }
                                        },
                                        createElement('span', {}, 'Loading...'),
                                ),
                                onClick:  () => {
                            }}];
                    }
                    let inlineTemplates = [];
                    globalTemplates.forEach(template => {
                        let disabled = (template.plan_version > assi_plugin_data.user_data.plan_id ? true : false);
                        if (template.type != undefined && template.type == TYPE_SHORTCUT) {
                            inlineTemplates.push({
                                title: createElement(
                                        'span',
                                        {
                                            style: {
                                                display: 'flex',
                                                justifyContent: 'space-between',
                                                alignItems: 'center',
                                                width: '100%',
                                                opacity: disabled ? 0.8 : 1,
                                                cursor: disabled ? 'not-allowed' : 'pointer'
                                            }
                                        },
                                        createElement('span', {}, template.header),
                                        template.plan_version > assi_plugin_data.user_data.plan_id ? createElement(
                                                'span',
                                                {
                                                    style: {
                                                        backgroundColor: '#f5365c',
                                                        color: 'white',
                                                        padding: '2px 6px',
                                                        borderRadius: '4px',
                                                        fontSize: '10px',
                                                        fontWeight: 'bold',
                                                        marginLeft: '8px'
                                                    }
                                                },
                                                template.plan_version_badge
                                                ) : null
                                        ),
                                onClick: disabled
                                        ? () => {
                                }
                                : () => {
                                    inlineAction(value, template.id);
                                }
                            });
                        }
                    });
                    inlineTemplates.push({
                        title: createElement(
                                'span',
                                {
                                    style: {
                                        display: 'flex',
                                        justifyContent: 'space-between',
                                        alignItems: 'center',
                                        width: '100%',
                                        opacity: 1,
                                        cursor: 'pointer'
                                    }
                                },
                                createElement('span', {}, __('More Functions', 'assistini'))
                        ),
                        onClick: () => { openSidebar(); }
                    });
                    return inlineTemplates;
                }

                return createElement(
                        BlockControls,
                        {},
                        createElement(
                                ToolbarGroup,
                                {},
                                createElement(
                                        ToolbarDropdownMenu,
                                        {
                                            icon: createElement(
                                                'span',
                                                {
                                                    style: {
                                                        display: 'flex',
                                                        alignItems: 'center',
                                                        gap: '5px'
                                                    }
                                                },
                                                createElement(
                                                    'img',
                                                    {
                                                        src: assi_plugin_data.plugin_path + '/assets/images/ass_sidebar_logo.png',
                                                        style: {background: 'white', width: '30px', height: '30px'}
                                                    }
                                                ),
                                                createElement(
                                                    'span',
                                                    {
                                                        style: {
                                                            fontSize: '14px',
                                                            fontWeight: '500'
                                                        }
                                                    },
                                                    __('AI Editor', 'assistini')
                                                )
                                            ),

                                            label: 'Assistini',
                                            controls: getInlineActions(),
                                        }
                                )
                                )
                        );
            };

            registerFormatType('assistini-format/output', {
                title: 'Assistini',
                tagName: 'assistini',
                className: null,
                edit: MyCustomButton,
            });

            function initCustomImagePlaceholderButton() {
                const target = document.querySelector('.interface-interface-skeleton__content');
                if (!target) {
                    return;
                }
                const observer = new MutationObserver((mutations) => {
                    for (const mutation of mutations) {
                        for (const added of mutation.addedNodes) {
                            if (!(added instanceof HTMLElement)) {
                                continue;
                            }
                            const urlInputContainer = added.querySelector('.block-editor-media-placeholder__url-input-container');
                            if (urlInputContainer) {
                                if (urlInputContainer.querySelector('.assi-custom-url-button')) {
                                    continue;
                                }
                                const btn = document.createElement('button');
                                btn.className = 'ass-wp-btn-image-add components-button is-primary';
                                btn.textContent = __('Generate with Assistini', 'assistini');
                                btn.addEventListener('click', () => {
                                    jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
                                    waitForElement('.ass-es-template-list-item[data-id="25"][data-type="editor"]', function () {
                                        jQuery('.ass-es-template-list-item[data-id="25"][data-type="editor"]').trigger('click');
                                    });
                                });
                                urlInputContainer.appendChild(btn);
                            }
                        }
                    }
                });
                observer.observe(target, { childList: true, subtree: true });
            }

            window.addEventListener('load', () => {
                setTimeout(initCustomImagePlaceholderButton, 500);
            });
        })(window.wp);
    }
}

function waitForTinyMCE() {
    if (typeof tinymce !== 'undefined' && tinymce.editors.length > 0) {
        initMyTinyMCEPlugin();
        let editor = tinymce.get('content');
        editor.on('keyup change', function () {
            let content = jQuery(editor.getContent({format: 'raw'}).replace(/<!--.*?-->/gs, '')).text().trim();
            if (content == undefined || content == '') {
                if (jQuery('#ass-es-page-template-content-check').is(':checked') == true) {
                    jQuery('#ass-es-page-template-content-check').prop('checked', false);
                    jQuery('.ass-es-page-template-content-ctn').show();
                    jQuery('.ass-es-page-template-input-ctn[data-id="additional_content"]').hide();
                }
                if (jQuery('#ass-es-page-template-content-check').prop('disabled') == false) {
                    jQuery('#ass-es-page-template-content-check').prop('disabled', true);
                }
                if (jQuery('#ass-es-page-template-content').prop('disabled') == true) {
                    jQuery('#ass-es-page-template-content').prop('disabled', false);
                }
            } else {
                if (jQuery('#ass-es-page-template-content-check').prop('disabled') == true) {
                    jQuery('#ass-es-page-template-content-check').prop('disabled', false);
                }
            }
        });
    } else {
        setTimeout(waitForTinyMCE, 100);
    }
}

function initMyTinyMCEPlugin() {
    if (tinymce.PluginManager.lookup['ass_shortcode_button'])
        return;

    tinymce.PluginManager.add('ass_shortcode_button', function (editor) {
        const items = [];

        (globalTemplates || []).forEach(template => {
            const isLocked = template.plan_version > assi_plugin_data.user_data.plan_id;
            const isValid = template.type === TYPE_SHORTCUT &&
                    !template.disabled &&
                    typeof template.id !== 'undefined';

            if (!isValid)
                return;

            items.push({
                text: template.header,
                icon: (isLocked ? 'ass_is_smart' : 'ass_is_free'),
                disabled: isLocked,
                onclick: function () {
                    setMyTinyMceAction(editor, template.id);
                }
            });
        });
        items.push({
            text: __('More Functions', 'assistini'),
            icon: 'ass_is_free',
            disabled: false,
            onclick: function () {
                openClassicSidebar();
            }
        });

        editor.addButton('ass_shortcode_button', {
            type: 'menubutton',
            icon: 'assi_shortcode_icon_classic',
            iconOnly: false,
            text: 'AI Editor',
            tooltip: 'Assistini',
            menu: items
        });
    });
    tinymce.editors.forEach(function (ed) {
        const settings = ed.settings;

        if (!settings.plugins.includes('ass_shortcode_button')) {
            settings.plugins += ' ass_shortcode_button';
        }

        if (!settings.toolbar1.includes('ass_shortcode_button')) {
            settings.toolbar1 += ' ass_shortcode_button';
        }

        ed.remove();
        tinymce.init(settings);
    });
}

function openClassicSidebar() {
    var sidebar = document.getElementById('ass-es');
    if (sidebar.style.transform === '' || sidebar.style.transform === 'translateX(100%)') {
        jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
    }
}

async function setMyTinyMceAction(editor, templateId) {
    let value = editor.selection.getContent();
    if (assi_plugin_data?.custom_ai_connection?.active == undefined || assi_plugin_data.custom_ai_connection.active == 0) {
        if (proxyLiveData.creditsOpen <= 0) {
            openUpgradeModal();
            return;
        }
    }

    if (value != undefined && value != '') {

        const message = '[AI-Assistant is thinking...]';
        await setMyTinyMceInsertTypingEffect(editor, message);

        const data = await jQuery.ajax({
            url: ajaxurl,
            type: 'POST',
            cache: false,
            data: {
                action: 'assi_editor_inline_send_prompt',
                template_id: templateId,
                refer_post_content: editor.getContent(),
                content: value,
                assi_security_nonce: assi_plugin_data.assi_security_nonce,
            },
        });
        const parsedData = JSON.parse(data);
        let content = editor.getContent();
        if (parsedData.result == undefined || parsedData.result != true || parsedData.content == undefined || parsedData.content.length == 0) {
            showNotice('error', (parsedData.error != undefined ? parsedData.error : ''));
            editor.setContent(content.replace(/<!--ass_shortcode_start-->[\s\S]*?<!--ass_shortcode_end-->/g, value));
            return;
        }
        if (parsedData?.user_data?.credits_open != undefined) {
            proxyLiveData.creditsOpen = parsedData.user_data.credits_open;
        }
        let responseText = parsedData.content[0];
        editor.setContent(content.replace(/<!--ass_shortcode_start-->[\s\S]*?<!--ass_shortcode_end-->/g, responseText));
    } else {
        let dialog = document.getElementById('ass-es-modal-notice');
        dialog.showModal();
        jQuery('#ass-es-modal-notice').hide();
        jQuery('#ass-es-modal-notice').fadeIn(150);
        return;
    }
}

async function setMyTinyMceInsertTypingEffect(editor, text, delay = 20) {
    const containerId = 'ai-insert-container-' + Date.now();
    const wrapperHtml = `
        <p>
            <!--ass_shortcode_start-->
            <span id="${containerId}"></span>
            <!--ass_shortcode_end-->
        </p>
    `;
    editor.insertContent(wrapperHtml);

    const iframe = tinymce.activeEditor.iframeElement;
    const doc = iframe?.contentDocument || iframe?.contentWindow?.document;

    if (!doc) {
        return;
    }

    const targetEl = doc.getElementById(containerId);
    if (!targetEl) {
        return;
    }
    for (let i = 0; i < text.length; i++) {
        targetEl.textContent += text[i];
        await new Promise(resolve => setTimeout(resolve, delay));
    }
}

// notifications heartbeat
let activeHeartbeats = [];
let originalHeartbeatInterval = 0;
let assHeartbeatInterval = 10;

if (typeof wp.heartbeat !== "undefined" && wp.hasOwnProperty('heartbeat')) {
    jQuery.ajax({
        url: ajaxurl,
        type: "POST",
        cache: false,
        data: {
            action: 'assi_check_open_notifications',
            type: 'editor',
            assi_security_nonce: assi_plugin_data.assi_security_nonce
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data.result != undefined && data.result == true) {
                startNotificationHeartbeat();
            }
        },
        error: function () {
            showNotice('error', '');
        }
    });
    jQuery(document).on('heartbeat-send', function (e, data) {
        data['ass_heartbeat_actions'] = activeHeartbeats;
    });
    jQuery(document).on('heartbeat-tick', function (e, data) {
        if (data.ass_heartbeat_stop != undefined && data.ass_heartbeat_stop == true) {
            stopNotificationHeartbeat();
        }
        if (data.ass_notification_update != undefined && data.ass_notification_update == true) {
            initNotifications();
            document.getElementById('ass-es-modal-notification').showModal();
            let dialog = document.getElementById('ass-es-modal-notification');
            dialog.showModal();
            jQuery('#ass-es-modal-notification').hide();
            jQuery('#ass-es-modal-notification').fadeIn(150);
        }
    });
}

// top toolbar:
const {__, _x, sprintf} = wp.i18n;

const TYPE_CHAT = 'chat';
const TYPE_USER = 'user';
const TYPE_EDITOR = 'editor';
const TYPE_SHORTCUT = 'editor_shortcut';

var userAuthorized = false;
var globalTemplates = [];
var progressInterval = null;

var liveData = {
    planId: (assi_plugin_data?.user_data?.plan_id != undefined ? assi_plugin_data.user_data.plan_id : 0),
    maxTemplates: 0,
    creditsOpen: (assi_plugin_data?.user_data?.credits_open != undefined ? assi_plugin_data.user_data.credits_open : 0),
    creditsTotal: (assi_plugin_data?.user_data?.credits_total != undefined ? assi_plugin_data.user_data.credits_total : 0),
    promoCreditsOpen: (assi_plugin_data?.user_data?.addons?.promotion?.credits_open != undefined ? assi_plugin_data.user_data.addons.promotion.credits_open : 0),
    promoCreditsTotal: (assi_plugin_data?.user_data?.addons?.promotion?.credits_total != undefined ? assi_plugin_data.user_data.addons.promotion.credits_total : 0),
    notifications: [],
    history: [],
};
const liveDataHandler = {
    set(target, property, value) {
        if (property === 'planId' && target[property] !== value) {

        }
        if (property === 'maxTemplates' && target[property] !== value) {

        }
        if (property === 'creditsOpen' && target[property] !== value) {
            target[property] = value;
            displayCredits();
        }
        if (property === 'creditsTotal' && target[property] !== value) {
            target[property] = value;
            displayCredits();
        }
        if (property === 'promoCreditsOpen' && target[property] !== value) {
            target[property] = value;
            displayCredits();
        }
        if (property === 'promoCreditsTotal' && target[property] !== value) {
            target[property] = value;
            displayCredits();
        }
        if (property === 'notifications' && target[property] !== value) {
            if (value.length > 0) {
                jQuery('.ass-es-notification-empty').hide();
                jQuery('.ass-es-notification-icon').addClass('ass-es-show-dot');
            } else {
                jQuery('.ass-es-notification-empty').show();
                jQuery('.ass-es-notification-icon').removeClass('ass-es-show-dot');
            }
        }
        if (target[property] !== value) {
            target[property] = value;
        }
        return true;
    }
};
const proxyLiveData = new Proxy(liveData, liveDataHandler);

jQuery(document).ready(function () {
    if (assi_plugin_data?.editor_type != undefined && (assi_plugin_data.editor_type == 'default' || assi_plugin_data.editor_type == 'classic')) {
        var interval = setInterval(function () {
            if (jQuery('.ass-es-toggle-btn').length <= 0) {
                if (assi_plugin_data.editor_type == 'default') {
                    jQuery('.editor-header__settings').prepend('<button class="ass-es-toggle-btn ass-es-toggle-btn-default ass-es-toggle ass-flex ass-justify-center ass-gap-5 ass-es-gradient-primary"><img class="ass-es-toggle-logo" src="' + assi_plugin_data.plugin_path + '/assets/images/ass_notification_icon.png' + '" /><span class="ass-es-toggle-btn-text">Assistini AI</span></button>');
                }
                if (assi_plugin_data.editor_type == 'classic') {
                    jQuery('<div style="display: inline-block;"><button class="ass-es-toggle-btn ass-es-toggle-btn-classic ass-es-toggle ass-flex ass-justify-center ass-gap-5 ass-es-gradient-primary"><img class="ass-es-toggle-logo" src="' + assi_plugin_data.plugin_path + '/assets/images/ass_notification_icon.png' + '" />Assistini AI</button><div>').insertBefore('.wp-header-end');
                }
            } else {
                clearInterval(interval);
                appendSidebar();
                initListeners();
                initObservers();
                displayCredits();
                checkOpenAiStatus();
                initNotifications();
                initHistory();
                getTemplates();
            }
        }, 500);
    }
});

jQuery(document).on('click', '.ass-es-toggle', function (e) {
    e.preventDefault();
    if (assi_plugin_data.editor_type == 'default') {
        let sidebar = jQuery('.ass-es-default');
        if (sidebar.width() <= 0) {
            sidebar.animate({width: '450px', minWidth: '450px'}, 100);
            if (assi_plugin_data.allow_server_connection == 'false') {
                if (assi_plugin_data.manage_options) {
                    openConsentModal('admin');
                } else {
                    openConsentModal('no_admin');
                }
            } else {
                if (jQuery('.ass-es-template-list .ass-es-template-list-item').length <= 0) {
                    getTemplates();
                }
            }
        } else {
            sidebar.css('width', '0px');
            sidebar.css('min-width', '0px');
            jQuery('.ass-es-page-template').css('transform', (assi_plugin_data.editor_type == 'default' ? 'translateX(-100%)' : 'translateX(100%)'));
        }
    } else if (assi_plugin_data.editor_type == 'classic') {
        if (assi_plugin_data.allow_server_connection == 'false' && (document.getElementById('ass-es').style.transform === 'translateX(100%)' || document.getElementById('ass-es').style.transform === '')) {
            if (assi_plugin_data.manage_options) {
                openConsentModal('admin');
                return;
            } else {
                openConsentModal('no_admin');
                return;
            }
        } else {
            if (jQuery('.ass-es-template-list .ass-es-template-list-item').length <= 0) {
                getTemplates();
            }
        }
        let sidebar = document.getElementById('ass-es');
        let transformValue = sidebar.style.transform === 'translateX(0%)' ? 'translateX(100%)' : 'translateX(0%)';
        sidebar.style.transform = transformValue;
    }
});


function waitForElement(selector, callback) {
    if (jQuery(selector).length) {
        callback();
    } else {
        setTimeout(function () {
            waitForElement(selector, callback);
        }, 50);
    }
}

jQuery(document).ready(function () {
    const param = new URLSearchParams(window.location.search).get('ass-ai-editor');
    if (param === 'open') {
        waitForElement('#ass-es', function () {
            var sidebar = document.getElementById('ass-es');
            if (sidebar.style.transform === 'translateX(100%)' || sidebar.style.transform === '') {
                jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
            }

        });
    }
});


function appendSidebar() {
    const sidebarHtml = `
    <div class="ass-es ass-flex-column" id="ass-es">
        <div class="ass-es-headline ass-flex ass-justify-between ass-align-center ass-es-gradient-primary">
            <div class="ass-flex-row ass-gap-10 ass-align-center">
                <img class="ass-es-headline-logo" src="${assi_plugin_data.plugin_path + '/assets/images/ass_notification_icon.png'}" />
                <p>Assistini</p>
            </div>
            <div class="ass-flex ass-gap-5">
                <div class="ass-es-notification-icon-ctn ass-flex ass-align-center">
                    <i class="ass-es-notification-icon bi bi-bell-fill ass-fs-17"></i>
                    <div class="ass-es-notification-dropdown" style="display:none;">
                        <div class="ass-es-notification-empty ass-flex ass-justify-center">
                            <span>Du hast keine neuen Benachrichtigungen</span>
                        </div>
                        <ul class="ass-es-notification-list ass-es-custom-scrollbar ass-m-0 ass-flex-column ass-gap-7">
                        </ul>
                    </div>
                </div>
                <button class="ass-es-close ass-es-toggle">&times;</button>
            </div>
        </div>
        <div class="ass-es-template ass-flex-column">
        <div class="ass-es-open-ai-status ass-flex-row ass-align-center ass-justify-between ass-gap-10 ass-mb-10" style="display:none;">
                <div class="ass-es-open-ai-status-header">
                    <span class="ass-fw-600 ass-fs-14">AI Status</span>
                </div>
                <div class="ass-es-open-ai-status-body ass-flex-row ass-gap-5" data-status="-1">
                    <div class="ass-es-open-ai-status-body-icon ass-es-open-ai-status-color-dark"></div>
                    <span class="ass-es-open-ai-status-body-text">${__('Loading', 'assistini')}<span>
                </div>
                <div class="ass-es-open-ai-status-body ass-flex-row ass-gap-5" data-status="0" style="display:none;">
                    <div class="ass-es-open-ai-status-body-icon ass-es-open-ai-status-color-dark"></div>
                    <span class="ass-es-open-ai-status-body-text">${__('Unknown', 'assistini')}<span>
                </div>
                <div class="ass-es-open-ai-status-body ass-flex-row ass-gap-5" data-status="1" style="display:none;">
                    <div class="ass-es-open-ai-status-body-icon ass-es-open-ai-status-color-green"></div>
                    <span class="ass-es-open-ai-status-body-text">${__('Operational', 'assistini')}<span>
                </div>
                <div class="ass-es-open-ai-status-body ass-flex-row ass-gap-5" data-status="2" style="display:none;">
                    <div class="ass-es-open-ai-status-body-icon ass-es-open-ai-status-color-yellow"></div>
                    <span class="ass-es-open-ai-status-body-text">${__('Impaired', 'assistini')}<span>
                </div>
                <div class="ass-es-open-ai-status-body ass-flex-row ass-gap-5" data-status="3" style="display:none;">
                    <div class="ass-es-open-ai-status-body-icon ass-es-open-ai-status-color-red"></div>
                    <span class="ass-es-open-ai-status-body-text">${__('Disrupted', 'assistini')}<span>
                </div>
                <div class="ass-es-open-ai-status-link ass-flex-row ass-align-center">
                    <a href="https://status.openai.com/" target="_blank" rel="noopener noreferrer">${__('Live check', 'assistini')} >></a>
                </div>
            </div>
            ${getLicenceModuleHtml()}
            <div class="ass-es-template-category ass-flex-row ass-justify-between ass-gap-10 ass-mt-10 ass-mb-10">
                <div class="ass-es-template-category-item ass-flex-row ass-align-center ass-justify-center ass-w-100 ass-active" data-category="text">
                    <span class="ass-fs-15">${__('Text', 'assistini')}</span>
                </div>
                <div class="ass-es-template-category-item ass-flex-row ass-align-center ass-justify-center ass-w-100" data-category="image">
                    <span class="ass-fs-15">${__('Image', 'assistini')}</span>
                </div>
                <div class="ass-es-template-category-item ass-flex-row ass-align-center ass-justify-center ass-w-100" data-category="audio">
                    <span class="ass-fs-15">${__('Audio', 'assistini')}</span>
                </div>
            </div>
            <div class="ass-es-template-search-ctn">
                <div class="ass-es-template-search ass-flex-row ass-gap-5">
                    <input id="ass-es-template-search-input" type="text" placeholder="${__('Search for Templates', 'assistini')}...">
                    <select class="ass-es-template-search-category ass-custom-input" style="padding-right:25px !important;">
                        <option value="all" selected>${__('All', 'assistini')}</option>
                        <option value="user">${__('My', 'assistini')}</option>
                        <option value="editor">${__('Assistini', 'assistini')}</option>
                    </select>
                </div>
            </div>
            <div class="ass-es-template-list ass-flex-column ass-es-custom-scrollbar">
            </div>
            <div class="ass-es-template-list-loader ass-flex ass-justify-center ass-mt-20">
                <div class="ass-es-basic-loader"></div>
            </div>
        </div>
        <div class="ass-es-page-template ass-es-page-template-${assi_plugin_data.editor_type} ass-flex-column ass-gap-5 ass-es-custom-scrollbar" data-template-id="0" data-is-system="false">
            <div class="ass-es-page-template-ctn ass-flex-column ass-gap-5">
                ${getLicenceModuleHtml()}
                <div class="ass-es-page-template-scroll-ctn ass-flex-column ass-gap-5 ass-es-custom-scrollbar" style="overflow-y:auto;height:100%;">
                    <div class="ass-es-page-template-header ass-es-page-template-group ass-flex ass-gap-10 ass-align-center">
                        <div class="ass-es-page-template-close-ctn ass-flex ass-align-center ass-gap-5">
                            <i class="ass-es-page-template-close bi bi-arrow-left"></i>
                        </div>
                        <span class="ass-es-page-template-title"></span>
                    </div>
                    <div class="ass-es-page-template-result-ctn ass-es-page-template-group">
                        <div class="ass-flex ass-justify-between ass-mb-10">
                            <span class="ass-fw-600 ass-fs-18">${__('Current Results', 'assistini')}</span>
                            <button class="ass-es-copy-btn" data-copy="all" style="display:none;"><i class="bi bi-copy"></i> ${__('Copy all to Clipboard', 'assistini')}</button>
                        </div>
                        <div class="ass-es-page-template-result ass-flex-column ass-gap-5">
                            <div class="ass-es-page-template-result-item" data-variant="1" style="display:none;">
                                <div class="ass-es-page-template-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-between">
                                        <span class="ass-fw-600 ass-fs-14">${__('Variant', 'assistini')} 1:</span>
                                        <button class="ass-es-copy-btn"><i class="bi bi-copy"></i> ${__('Copy to Clipboard', 'assistini')}</button>
                                    </div>
                                    <div class="ass-es-template-result-loader"></div>
                                    <span class="ass-es-page-template-result-item-text ass-fs-14" style="display:none;"></span>
                                </div>
                            </div>
                            <div class="ass-es-page-template-result-item" data-variant="2" style="display:none;">
                                <div class="ass-es-page-template-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-between">
                                        <span class="ass-fw-600 ass-fs-14">${__('Variant', 'assistini')} 2:</span>
                                        <button class="ass-es-copy-btn"><i class="bi bi-copy"></i> ${__('Copy to Clipboard', 'assistini')}</button>
                                    </div>
                                    <div class="ass-es-template-result-loader"></div>
                                    <span class="ass-es-page-template-result-item-text ass-fs-14" style="display:none;"></span>
                                </div>
                            </div>
                            <div class="ass-es-page-template-result-item" data-variant="3" style="display:none;">
                                <div class="ass-es-page-template-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-between">
                                        <span class="ass-fw-600 ass-fs-14">${__('Variant', 'assistini')} 3:</span>
                                        <button class="ass-es-copy-btn"><i class="bi bi-copy"></i> ${__('Copy to Clipboard', 'assistini')}</button>
                                    </div>
                                    <div class="ass-es-template-result-loader"></div>
                                    <span class="ass-es-page-template-result-item-text ass-fs-14" style="display:none;"></span>
                                </div>
                            </div>
                            <div class="ass-es-page-template-result-item" data-variant="4" style="display:none;">
                                <div class="ass-es-page-template-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-between">
                                        <span class="ass-fw-600 ass-fs-14">${__('Variant', 'assistini')} 4:</span>
                                        <button class="ass-es-copy-btn"><i class="bi bi-copy"></i> ${__('Copy to Clipboard', 'assistini')}</button>
                                    </div>
                                    <div class="ass-es-template-result-loader"></div>
                                    <span class="ass-es-page-template-result-item-text ass-fs-14" style="display:none;"></span>
                                </div>
                            </div>
                            <div class="ass-es-page-template-result-item" data-variant="5" style="display:none;">
                                <div class="ass-es-page-template-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-between">
                                        <span class="ass-fw-600 ass-fs-14">${__('Variant', 'assistini')} 5:</span>
                                        <button class="ass-es-copy-btn"><i class="bi bi-copy"></i> ${__('Copy to Clipboard', 'assistini')}</button>
                                    </div>
                                    <div class="ass-es-template-result-loader"></div>
                                    <span class="ass-es-page-template-result-item-text ass-fs-14" style="display:none;"></span>
                                </div>
                            </div>
                        </div>
                        <div class="ass-es-page-template-image-result ass-flex-column ass-gap-5">
                            <div class="ass-es-page-template-image-result-item" data-variant="1" style="display:none;">
                                <div class="ass-es-page-template-image-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-end">
                                        <div class="ass-flex ass-gap-5">
                                            <button class="ass-es-save-image-download-btn"><i class="bi bi-download"></i> ${__('Download', 'assistini')}</button>
                                            <button class="ass-es-save-image-to-library-btn"><i class="ass-es-save-image-to-library-btn-icon bi bi-save"></i> <span class="ass-es-save-image-to-library-btn-text">${__('Save to Library', 'assistini')}</span><div class="ass-es-template-image-save-loader" style="display:none;"></div></button>
                                        </div>
                                    </div>
                                    <div class="ass-es-template-image-result-loader ass-flex ass-justify-center ass-align-center">
                                        <div class="ass-es-circle-progress-image-text">0%</div>
                                        <div id="ass-es-circle-progress-image"></div>
                                    </div>
                                    <div class="ass-es-page-template-image-result-item-image"></div>
                                </div>
                            </div>
                        </div>
                        <div class="ass-es-page-template-audio-result ass-flex-column ass-gap-5">
                            <div class="ass-es-page-template-audio-result-item" data-variant="1" style="display:none;">
                                <div class="ass-es-page-template-audio-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-flex ass-justify-end">
                                        <div class="ass-flex ass-gap-5">
                                            <button class="ass-es-save-audio-download-btn"><i class="bi bi-download"></i> ${__('Download', 'assistini')}</button>
                                            <button class="ass-es-save-audio-to-library-btn"><i class="ass-es-save-audio-to-library-btn-icon bi bi-save"></i> <span class="ass-es-save-audio-to-library-btn-text">${__('Save to Library', 'assistini')}</span><div class="ass-es-template-audio-save-loader" style="display:none;"></div></button>
                                        </div>
                                    </div>
                                    <div class="ass-es-template-audio-result-loader ass-flex ass-justify-center ass-align-center">
                                        <div class="ass-es-circle-progress-audio-text">0%</div>
                                        <div id="ass-es-circle-progress-audio"></div>
                                    </div>
                                    <div class="ass-es-page-template-audio-result-item-audio"></div>
                                </div>
                            </div>
                        </div>
                        <div class="ass-es-page-template-timeout-result ass-flex-column ass-gap-5">
                            <div class="ass-es-page-template-timeout-result-item" style="display:none;">
                                <div class="ass-es-page-template-timeout-result-item-content ass-flex-column ass-gap-5">
                                    <div class="ass-es-alert-info ass-flex ass-gap-10 ass-align-center">
                                        <i class="bi bi-info-circle ass-fs-16"></i>
                                        <span>${__('Your request needs a bit more time. We\'ll notify you as soon as everything is ready.', 'assistini')}</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="ass-es-page-template-history-smart-ctn ass-es-page-template-group" style="display:none;">
                        <div class="ass-flex-column ass-gap-5">
                            <div class="ass-flex ass-justify-between ass-align-center">
                                <span class="ass-es-page-template-history-title ass-fw-600 ass-fs-18 ass-es-gray-50">${__('Latest Results', 'assistini')}</span>
                                <span class="ass-primary-badge ass-es-opacity-80">${__('Smart', 'assistini')}</span>
                            </div>
                        </div>
                    </div>
                    <div class="ass-es-page-template-history-ctn ass-es-page-template-group">
                        <div class="ass-flex-column ass-gap-5">
                            <div class="ass-flex ass-justify-between ass-align-center">
                                <span class="ass-es-page-template-history-title ass-fw-600 ass-fs-18">${__('Latest Results', 'assistini')}</span>
                                <i class="ass-es-page-template-history-toggle bi bi-caret-down-fill"></i>
                            </div>
                            <div class="ass-es-page-template-history-wrapper ass-flex-column" style="display:none;">
                                <div class="ass-es-page-template-history ass-flex-column"></div>
                            </div>
                        </div>
                    </div>
                    <form id="ass-es-page-template-form" class="ass-flex-column ass-gap-5">
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group" data-id="models">
                            <div class="ass-flex ass-justify-between ass-align-center">
                                <label for="ass-es-page-template-model" class="ass-fw-600 ass-fs-13">${__('Model', 'assistini')}</label>
                                <select id="ass-es-page-template-model" class="ass-es-page-template-form-input ass-custom-input" data-id="model">
                                </select>
                            </div>
                        </div>
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group ass-flex-column ass-gap-10" data-id="speaker">
                            <span class="ass-fs-18 ass-fw-600">${__('Speaker', 'assistini')}</span>
                            <div class="ass-es-page-template-speaker-controls ass-flex-column ass-gap-5">
                                <div class="ass-flex-column ass-gap-5">
                                    <div class="ass-flex-column">
                                        <label for="ass-es-page-template-speaker" class="ass-fw-600 ass-fs-13">${__('Name', 'assistini')}</label>
                                        <input type="text" id="ass-es-page-template-speaker" data-id="speaker" class="ass-es-page-template-form-input ass-custom-input ass-w-100" placeholder="${__('Name', 'assistini')}...">
                                    </div>
                                    <div class="ass-flex-column">
                                        <label for="ass-es-page-template-speaker-voice" class="ass-fw-600 ass-fs-13">${__('Voice', 'assistini')}</label>
                                        <div class="ass-flex ass-gap-5">
                                            <select id="ass-es-page-template-speaker-voice" class="ass-es-page-template-form-input ass-custom-input ass-w-100" data-id="speaker_voice"></select>
                                            <button class="ass-es-page-template-speaker-voice-play ass-btn-primary"><i class="bi bi-play-fill"></i></button>
                                        </div>
                                    </div>
                                    <button type="button" class="ass-es-page-template-speaker-add ass-btn-primary ass-mt-5">+ ${__('Add Speaker', 'assistini')}</button>
                                </div>
                            </div>
                            <ul class="ass-es-page-template-speaker-list ass-m-0">
                            </ul>
                        </div>
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group" data-id="audio_custom_content">
                            <div class="ass-flex ass-justify-between ass-align-center">
                                <div class="ass-flex-column">
                                    <span class="ass-fw-600">${__('Mode', 'assistini')}</span>
                                    <span class="ass-es-page-template-mode">${__('Create a podcast from your own podcast script', 'assistini')}</span>
                                </div>
                                <label class="ass-es-switch">
                                    <input id="ass-es-page-template-custom-content-check" type="checkbox">
                                    <span class="ass-es-switch-slider"></span>
                                </label>
                            </div>
                        </div>
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group ass-flex-column ass-gap-5" data-id="content">
                            <div class="ass-flex ass-align-center ass-justify-between">
                                <label for="ass-es-page-template-content" class="ass-fw-600 ass-fs-13">${__('Content', 'assistini')}</label>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex ass-justify-between ass-align-center" data-id="post_content">
                                <span>${__('Use Post Content', 'assistini')}</span>
                                <label class="ass-es-switch">
                                    <input id="ass-es-page-template-content-check" type="checkbox">
                                    <span class="ass-es-switch-slider"></span>
                                </label>
                            </div>
                            <div class="ass-es-page-template-content-ctn">
                                <textarea id="ass-es-page-template-content" class="ass-es-page-template-form-input ass-custom-input ass-w-100" data-id="content" placeholder="${__('Content', 'assistini')}..." rows="4"></textarea>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="additional_content" style="display:none;">
                                <label for="ass-es-page-template-content-additional" class="ass-fw-600 ass-fs-13">${__('Additional Content', 'assistini')}</label>
                                <textarea id="ass-es-page-template-content-additional" class="ass-es-page-template-form-input ass-custom-input" data-id="additional_content" placeholder="${__('Additional Content', 'assistini')}..." rows="4"></textarea>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex ass-justify-between ass-align-center" data-id="refer_post_content">
                                <span>${__('Refer to the Post Content', 'assistini')}</span>
                                <label class="ass-es-switch">
                                    <input id="ass-es-page-template-refer-content-check" type="checkbox">
                                    <span class="ass-es-switch-slider"></span>
                                </label>
                            </div>
                        </div>
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group ass-flex-column ass-gap-10" data-id="conversation">
                            <div class="ass-flex-column ass-gap-5">
                                <div class="ass-flex-column">
                                    <label for="ass-es-page-template-conversation-speaker" class="ass-fw-600 ass-fs-13">${__('Speaker', 'assistini')}</label>
                                    <select id="ass-es-page-template-conversation-speaker" disabled class="ass-es-page-template-form-input ass-custom-input ass-w-100" data-id="conversation_speaker">
                                        <option value="" disabled selected>${__('Add Speaker to create a Conversation', 'assistini')}...</option>
                                    </select>
                                </div>
                                <div class="ass-flex-column">
                                    <label for="ass-es-page-template-conversation" class="ass-fw-600 ass-fs-13">${__('Add Line', 'assistini')}</label>
                                    <textarea type="text" id="ass-es-page-template-conversation" data-id="conversation" class="ass-es-page-template-form-input ass-custom-input ass-w-100" placeholder="${__('Add Line', 'assistini')}..." rows="3" disabled></textarea>
                                </div>
                                <button type="button" class="ass-es-page-template-conversation-add ass-btn-primary ass-mt-5" disabled>+ ${__('Add to Conversation', 'assistini')}</button>
                            </div>
                            <ul class="ass-es-page-template-conversation-list"></ul>
                        </div>
                        <div class="ass-es-page-template-input-ctn ass-es-page-template-group ass-flex-column" data-id="image">
                            <div class="ass-es-page-template-image-error-ctn">
                                <div class="ass-es-page-template-image-error ass-flex ass-gap-10 ass-align-center">
                                    <i class="bi bi-exclamation-triangle"></i>
                                    <span class="ass-es-page-template-image-error-text"></span>
                                </div>
                            </div>
                            <label for="ass-es-page-template-image" data-id="0" class="ass-fw-600 ass-fs-13">${__('Image', 'assistini')}</label>
                            <div class="ass-flex ass-gap-5">
                                <input type="text" id="ass-es-page-template-image" class="ass-custom-input ass-w-100" readonly>
                                <button type="button" class="ass-es-page-template-image-upload">${__('Choose Image', 'assistini')}</button>
                            </div>
                        </div>
                        <div class="ass-es-page-template-group ass-flex-column ass-gap-5" data-group="style">
                            <div class="ass-es-page-template-input-ctn ass-flex-column ass-gap-8 ass-mt-5" data-id="custom_style" style="display:none;">
                                <div class="ass-flex ass-justify-between ass-align-center ass-mb-5">
                                    <span class="ass-fw-600 ass-fs-15">${__('Style', 'assistini')}</span>
                                    <div class="ass-flex ass-align-center ass-gap-5">
                                        <select id="ass-es-page-template-style" class="ass-es-page-template-form-input ass-custom-input" ${assi_plugin_data?.user_data?.plan_id != undefined && assi_plugin_data?.user_data?.plan_id > 1 ? '' : 'disabled'}>
                                            ${generateCustomStyleOptions()}
                                        </select>
                                        <div class="ass-flex ass-align-center ass-gap-5" ${assi_plugin_data?.user_data?.plan_id != undefined && assi_plugin_data?.user_data?.plan_id > 1 ? '' : 'style="display:none;"'}>
                                            <button type="button" class="ass-btn-primary ass-es-page-template-style-save">${__('Save', 'assistini')}</button>
                                            <button type="button" class="ass-btn-secondary ass-es-page-template-style-delete" style="display:none;">${__('Delete', 'assistini')}</button>
                                        </div>
                                        <div class="ass-flex ass-align-center ass-gap-5" ${assi_plugin_data?.user_data?.plan_id != undefined && assi_plugin_data?.user_data?.plan_id > 1 ? 'style="display:none;"' : ''}>
                                            <span class="ass-primary-badge">${__('Smart', 'assistini')}</span>
                                        </div>
                                    </div>
                                </div>
                                <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="art_style">
                                    <label for="ass-es-page-template-art-style" class="ass-fw-600 ass-fs-13">${__('Art', 'assistini')}</label>
                                    <select id="ass-es-page-template-art-style" data-id="art_style" class="ass-es-page-template-form-input ass-custom-input">
                                        ${generateArtStyleOptions()}
                                    </select>
                                </div>
                                <div class="ass-flex-column">
                                    <label for="ass-es-page-template-custom-style" class="ass-fw-600 ass-fs-13">${__('Custom', 'assistini')}</label>
                                    <textarea id="ass-es-page-template-custom-style" class="ass-es-page-template-form-input ass-custom-input" data-id="custom_style" placeholder="${__('Custom Style', 'assistini')}..." rows="4"></textarea>
                                </div>
                            </div>
                        </div>
                        <div class="ass-es-page-template-group ass-flex-column ass-gap-5">
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="number_of_results">
                                <label for="ass-es-page-template-number" class="ass-fw-600 ass-fs-13">${__('Number of Results', 'assistini')}</label>
                                <input type="number" id="ass-es-page-template-number" data-id="number_of_results" class="ass-es-page-template-form-input ass-custom-input" value="1" min="1" max="5">
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="url">
                                <label for="ass-es-page-template-url" class="ass-fw-600 ass-fs-13">${__('Url', 'assistini')}</label>
                                <input type="url" id="ass-es-page-template-url" data-id="url" class="ass-es-page-template-form-input ass-custom-input" placeholder="${__('Url', 'assistini')}...">
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="focus_keyword">
                                <label for="ass-es-page-template-focus-keyword" class="ass-fw-600 ass-fs-13">${__('Focus Keyword', 'assistini')}</label>
                                <input type="text" id="ass-es-page-template-focus-keyword" data-id="focus_keyword" class="ass-es-page-template-form-input ass-custom-input" placeholder="${__('Focus Keyword', 'assistini')}...">
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="point_of_view">
                                <label for="ass-es-page-template-pov" class="ass-fw-600 ass-fs-13">${__('Point of View', 'assistini')}</label>
                                <select id="ass-es-page-template-pov" data-id="point_of_view" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generatePovOptions()}
                                </select>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="tone">
                                <label for="ass-es-page-template-tone" class="ass-fw-600 ass-fs-13">${__('Tone', 'assistini')}</label>
                                <select id="ass-es-page-template-tone" data-id="tone" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generateToneOptions()}
                                </select>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="prompt_language">
                                <label for="ass-es-page-template-language" class="ass-fw-600 ass-fs-13">${__('Language', 'assistini')}</label>
                                <select id="ass-es-page-template-language" data-id="prompt_language" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generateLanguageOptions()}
                                </select>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="size">
                                <label for="ass-es-page-template-size" class="ass-fw-600 ass-fs-13">${__('Size', 'assistini')}</label>
                                <select id="ass-es-page-template-size" data-id="size" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generateSizeOptions()}
                                </select>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="quality">
                                <label for="ass-es-page-template-quality" class="ass-fw-600 ass-fs-13">${__('Quality', 'assistini')}</label>
                                <select id="ass-es-page-template-quality" data-id="quality" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generateQualityOptions()}
                                </select>
                            </div>
                            <div class="ass-es-page-template-input-ctn ass-flex-column" data-id="output_format">
                                <label for="ass-es-page-template-format" class="ass-fw-600 ass-fs-13">${__('Output Format', 'assistini')}</label>
                                <select id="ass-es-page-template-format" data-id="output_format" class="ass-es-page-template-form-input ass-custom-input">
                                    ${generateOutputFormatOptions()}
                                </select>
                            </div>
                        </div>
                    </form>
                    <div class="ass-es-page-template-submit-ctn">
                        <div class="ass-flex">
                            <button class="ass-es-page-template-submit-edit-btn ass-btn-primary ass-flex ass-justify-center ass-align-center ass-gap-5 ass-fs-16 ass-w-100" style="display:none;">
                                <i class="bi bi-stars"></i>
                                <span class="ass-fw-500">${__('Edit Image', 'assistini')}</span>
                            </button>
                            <button class="ass-es-page-template-submit-btn ass-btn-primary ass-flex ass-justify-center ass-align-center ass-gap-5 ass-fs-16 ass-w-100">
                                <i class="bi bi-stars"></i>
                                <span class="ass-fw-500">${__('Generate', 'assistini')}</span>
                            </button>
                        </div>
                    </div>
                    <div class="ass-mb-45"></div>
                </div>
            </div>
        </div>
        <div class="ass-es-page-error-auth ass-flex ass-justify-center ass-align-center" style="display:none;">
            <div class="ass-page-error-auth-ctn ass-flex-column ass-gap-5 ass-text-center ass-max-w-50">
                <i class="bi bi-exclamation-circle ass-fs-20 ass-text-secondary"></i>
                <span class="ass-fs-16">You need to Sign up with Assistini to use this Feature!</span>
                <button class="ass-page-error-auth-btn">Sign up for free</button>
            </div>
        </div>
        <dialog id="ass-es-modal-custom-style" class="ass-es-modal">
            <div class="ass-es-modal-header">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span>${__('Custom Style', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <div class="ass-flex-column">
                    <label for="ass-es-modal-custom-style-name" class="ass-fw-600 ass-fs-14">${__('Name', 'assistini')}:</label>
                    <input id="ass-es-modal-custom-style-name" class="ass-es-page-template-form-input ass-custom-input" type="text" placeholder="${__('Name', 'assistini')}...">
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button type="button" class="ass-btn-primary ass-es-modal-custom-style-save">
                        <span class="ass-es-modal-custom-style-save-text">${__('Save', 'assistini')}</span>
                        <div class="ass-es-modal-custom-style-loader" style="display:none;"></div>
                    </button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-upgrade" class="ass-es-modal">
            <div class="ass-es-modal-header">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span>${__('Notice', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <div class="ass-es-modal-upgrade-content" data-type="free">
                    <p class="ass-fs-15 ass-mt-0 ass-mb-0">${__('You want to create more content?<br>Please upgrade your current free version to the smart version or add further word contingents to create new content.', 'assistini')}</p>
                </div>
                <div class="ass-es-modal-upgrade-content" data-type="smart">
                    <p class="ass-fs-15 ass-mt-0 ass-mb-0">${__('You want to create more content?<br>Please add further word contingents to create new content.', 'assistini')}</p>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button type="button" class="ass-btn-primary ass-es-modal-upgrade-btn">${__('Upgrade', 'assistini')}</button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-consent" class="ass-es-modal">
            <div class="ass-es-modal-header">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span>${__('Permission required!', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <div class="ass-flex-column ass-gap-15">
                    <p class="ass-fs-15 ass-mt-0 ass-mb-0">${sprintf(__('To use the AI features and receive AI-generated responses, we require your consent to transmit the content you enter in the Assistini Content Creator to the AI server via a secure API connection. You can withdraw your consent at any time by deselecting the option. For details, please see our <a href="%s" target="_blank" rel="noopener noreferrer">privacy policy</a>.', 'assistini'), 'https://assistini.com/en/privacy-policy#wp')}</p>
                    <div class="ass-flex">
                        <div>
                            <input type="checkbox" id="ass-es-modal-consent-checkbox">
                        </div>
                        <label for="ass-es-modal-consent-checkbox" class="ass-fs-16">${__('I consent to content being sent to OpenAI (ChatGPT), Google (Gemini) and agree to the privacy policy.', 'assistini')}</label>
                    </div>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-between">
                    <button class="ass-es-modal-close ass-btn-secondary">${__('Do not allow', 'assistini')}</button>
                    <button class="ass-es-modal-consent-save-btn ass-btn-primary" disabled>${__('Save', 'assistini')}</button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-consent-rejected" class="ass-es-modal">
            <div class="ass-es-modal-header">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span>${__('Permission required!', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <p class="ass-fs-15 ass-mt-0 ass-mb-0">${sprintf(__('In order to use the AI function of Assistini, we need your consent to transmit content to OpenAI (ChatGPT) and Google (Gemini).<br><br>Please activate the option in the <a href="%s" target="_blank" rel="noopener noreferrer">Plugin Settings</a> to continue.', 'assistini'), './admin.php?page=assistini#/settings')}</p>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button class="ass-es-modal-close ass-btn-primary">${__('Got it', 'assistini')}</button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-consent-no-admin" class="ass-es-modal">
            <div class="ass-es-modal-header">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span>${__('Administrator Approval Required!', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <p class="ass-fs-15 ass-mt-0 ass-mb-0">${__('The AI functionality has not yet been enabled on this website by the administrator.<br><br>Please inform your site administrator so they can activate the AI server connection in the plugin settings.<br><br>Without this approval, the use of Assistini is not possible.', 'assistini')}</p>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button class="ass-es-modal-close ass-btn-primary">${__('Got it', 'assistini')}</button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-notification" class="ass-es-modal">
            <div class="ass-es-modal-header ass-es-gradient-primary">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span class="ass-text-white">${__('New notification!', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x ass-text-white">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <p class="ass-fs-15 ass-mt-0 ass-mb-0">${__('You have a new notification.', 'assistini')}</p>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button class="ass-es-modal-notification-show ass-btn-primary">${__('See notification', 'assistini')}</button>
                </div>
            </div>
        </dialog>
        <dialog id="ass-es-modal-notice" class="ass-es-modal">
            <div class="ass-es-modal-header ass-es-gradient-primary">
                <div class="ass-flex ass-align-center ass-justify-between ass-gap-50">
                    <span class="ass-text-white">${__('Notice', 'assistini')}</span>
                    <span class="ass-es-modal-close ass-es-modal-close-x ass-text-white">x</span>
                </div>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-body">
                <p class="ass-fs-15 ass-mt-0 ass-mb-0">${__('Content is missing. Please provide the required text.', 'assistini')}</p>
            </div>
            <hr class="ass-m-0">
            <div class="ass-es-modal-footer">
                <div class="ass-flex ass-justify-end">
                    <button class="ass-es-modal-close ass-btn-primary">${__('Got it', 'assistini')}</button>
                </div>
            </div>
        </dialog>
    </div>
    `;
    if (assi_plugin_data.editor_type == 'default') {
        jQuery('.interface-interface-skeleton__body').prepend(sidebarHtml);
        jQuery('.ass-es').addClass('ass-es-default');
    } else if (assi_plugin_data.editor_type == 'classic') {
        jQuery('body').append(sidebarHtml);
        jQuery('.ass-es').addClass('ass-es-classic');
    }
}

function getLicenceModuleHtml() {
    if (assi_plugin_data?.custom_ai_connection?.active != undefined && assi_plugin_data.custom_ai_connection.active == 1) {
        return `
            <div class="ass-es-template-licence ass-flex-column ass-gap-5">
                <div class="ass-flex ass-justify-between">
                    <span class="ass-fs-12 ass-fw-600">${__('Licence', 'assistini')}: <span class="ass-text-secondary">${assi_plugin_data?.user_data?.plan_id == 2 ? __('Smart', 'assistini') : __('Free', 'assistini')}</span></span>
                    <div class="ass-es-licence-hide-collapsed ass-flex ass-gap-5">
                        <a href="admin.php?page=assistini#/account" target="_blank" rel="noopener noreferrer">${__('Manage account', 'assistini')}</a>
                    </div>
                </div>
            </div>
        `;
    } else {
        return `
            <div class="ass-es-template-licence ass-flex-column ass-gap-5">
                <div class="ass-flex ass-justify-between">
                    <span class="ass-fs-12 ass-fw-600">${__('Licence', 'assistini')}: <span class="ass-text-secondary">${assi_plugin_data?.user_data?.plan_id == 2 ? __('Smart', 'assistini') : __('Free', 'assistini')}</span></span>
                    <div class="ass-es-licence-hide-collapsed ass-flex ass-gap-5">
                        <a href="admin.php?page=assistini#/account" target="_blank" rel="noopener noreferrer">${__('Manage account', 'assistini')}</a>
                        <div class="ass-es-licence-collapse ass-es-licence-hide-collapsed ass-flex ass-justify-center">
                            <i class="bi bi-caret-up-fill"></i>
                        </div>
                    </div>
                    <div class="ass-es-licence-show-collapsed ass-flex ass-gap-5" style="display:none;">
                        <span class="ass-self-align-end ass-fs-12 ass-fw-600">${__('Remaining', 'assistini')}: <span class="ass-es-licence-credits-open">${assi_plugin_data?.user_data?.credits_open}</span> / <span class="ass-es-licence-credits-total">${assi_plugin_data?.user_data?.credits_total}</span> ${__('(auto-renew)', 'assistini')}</span>
                        <div class="ass-es-licence-expand ass-es-licence-show-collapsed ass-flex ass-justify-center" style="display:none;">
                            <i class="bi bi-caret-down-fill"></i>
                        </div>
                    </div>
                </div>
                <div class="ass-es-licence-hide-collapsed ass-flex-column ass-gap-5">
                    <span class="ass-fs-12 ass-fw-600">${__('Your monthly word volume', 'assistini')}</span>
                    <span class="ass-self-align-end ass-fs-12 ass-fw-600">${__('Remaining', 'assistini')}: <span class="ass-es-licence-credits-open">${assi_plugin_data?.user_data?.credits_open}</span> / <span class="ass-es-licence-credits-total">${assi_plugin_data?.user_data?.credits_total}</span> ${__('(auto-renew)', 'assistini')}</span>
                    <div class="ass-licence-progress-ctn ass-flex">
                        <div class="ass-licence-progress-bar" style="width:${assi_plugin_data?.user_data?.credits_open / assi_plugin_data?.user_data?.credits_total * 100}%;"></div>
                        <div class="ass-es-licence-promo ass-licence-progress-bar-promo" style="width:0%;display:none;"></div>
                    </div>
                    <div class="ass-flex ass-justify-between ass-align-center">
                        <div class="ass-flex-column">
                            <div class="ass-flex ass-align-center ass-gap-5">
                                <div class="ass-es-licence-pin"></div>
                                <div class="ass-fs-11 ass-fw-600"><span class="ass-es-licence-pin-credits"></span> ${assi_plugin_data?.user_data?.plan_id > 1 ? __('Smart', 'assistini') : __('Free', 'assistini')} ${__('Plan', 'assistini')}</div>
                            </div>
                            <div class="ass-es-licence-promo ass-flex ass-align-center ass-gap-5" style="display:none;">
                                <div class="ass-es-licence-pin-promo"></div>
                                <div class="ass-fs-11 ass-fw-600"><span class="ass-es-licence-pin-promo-credits"></span> ${__('Welcome Bonus (30 days)', 'assistini')}</div>
                            </div>
                        </div>
                        <a target="_blank" rel="noopener noreferrer" href="https://app.assistini.com/?screen=Plan" class="ass-btn-link">${__('Need More? Upgrade now', 'assistini')}</a>
                    </div>
                </div>
            </div>
        `;
    }
}

jQuery(document).ready(function () {
    jQuery(document).on('click', '.ass-es-copy-btn', function (e) {
        e.preventDefault();
        let copyType = jQuery(this).data('copy');
        if (copyType == undefined) {
            const $btn = jQuery(this);
            const container = $btn.closest('.ass-es-page-template-result-item-content');
            const textElement = container.find('.ass-es-page-template-result-item-text');
            let textToCopy = textElement.html().trim();
            if (assi_plugin_data.editor_type == 'default') {
                textToCopy = convertHtmlToGutenbergBlocks(textToCopy);
            }
            const tempInput = jQuery('<textarea>');
            jQuery('body').append(tempInput);
            tempInput.val(textToCopy).select();
            document.execCommand('copy');
            tempInput.remove();

            let $tooltip = $btn.find('.ass-copy-tooltip');
            if ($tooltip.length === 0) {
                $tooltip = jQuery('<span class="ass-copy-tooltip">' + __('is copied!', 'assistini') + '</span>');
                $btn.append($tooltip);
            }
            $tooltip.fadeIn(150);
            setTimeout(() => {
                $tooltip.fadeOut(300);
            }, 1500);
        } else if (copyType == 'all') {
            let copyText = '';
            jQuery('.ass-es-page-template-result-item:visible').each(function () {
                let $textElement = jQuery(this).find('.ass-es-page-template-result-item-text');
                if (copyText != '') {
                    copyText += '\n\n';
                }
                copyText += $textElement.html().trim();
                if (assi_plugin_data.editor_type == 'default') {
                    copyText = convertHtmlToGutenbergBlocks(copyText);
                }
            });

            const tempInput = jQuery('<textarea>');
            jQuery('body').append(tempInput);
            tempInput.val(copyText).select();
            document.execCommand('copy');
            tempInput.remove();

            let $tooltip = jQuery(this).find('.ass-copy-tooltip');
            if ($tooltip.length === 0) {
                $tooltip = jQuery('<span class="ass-copy-tooltip">' + __('is copied!', 'assistini') + '</span>');
                jQuery(this).append($tooltip);
            }

            $tooltip.fadeIn(150);

            setTimeout(() => {
                $tooltip.fadeOut(300);
            }, 1500);
        }
    });

});


function generatePovOptions() {
    let html = '';
    if (assi_plugin_data.form_options.point_of_view != undefined && typeof assi_plugin_data.form_options.point_of_view == 'object') {
        html += `<option value="auto" ${(assi_plugin_data?.settings?.content_creator?.point_of_view != undefined && assi_plugin_data?.settings?.content_creator?.point_of_view != '' ? '' : 'selected')}>${__('Auto-detect Point of View', 'assistini')}</option>`;
        for (const key in assi_plugin_data.form_options.point_of_view) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.content_creator?.point_of_view != undefined && assi_plugin_data?.settings?.content_creator?.point_of_view != '' && assi_plugin_data?.settings?.content_creator?.point_of_view == key ? 'selected' : '')}>${assi_plugin_data.form_options.point_of_view[key]}</option>`;
        }
    }
    return html;
}

function generateToneOptions() {
    let html = '';
    if (assi_plugin_data.form_options.tone != undefined && typeof assi_plugin_data.form_options.tone == 'object') {
        html += `<option value="auto" ${(assi_plugin_data?.settings?.content_creator?.tone != undefined && assi_plugin_data?.settings?.content_creator?.tone != '' ? '' : 'selected')}>${__('Auto-detect Tone', 'assistini')}</option>`;
        for (const key in assi_plugin_data.form_options.tone) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.content_creator?.tone != undefined && assi_plugin_data?.settings?.content_creator?.tone != '' && assi_plugin_data?.settings?.content_creator?.tone == key ? 'selected' : '')}>${assi_plugin_data.form_options.tone[key]}</option>`;
        }
    }
    return html;
}

function generateLanguageOptions() {
    let html = '';
    if (assi_plugin_data.form_options.language != undefined && typeof assi_plugin_data.form_options.language == 'object') {
        html += `<option value="auto" ${(assi_plugin_data?.settings?.content_creator?.language != undefined && assi_plugin_data?.settings?.content_creator?.language != '' ? '' : 'selected')}>${__('Auto-detect Language', 'assistini')}</option>`;
        for (const key in assi_plugin_data.form_options.language) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.content_creator?.language != undefined && assi_plugin_data?.settings?.content_creator?.language != '' && assi_plugin_data?.settings?.content_creator?.language == key ? 'selected' : '')}>${assi_plugin_data.form_options.language[key]}</option>`;
        }
    }
    return html;
}

function generateSizeOptions() {
    let html = '';
    if (assi_plugin_data.form_options.size != undefined && typeof assi_plugin_data.form_options.size == 'object') {
        for (const key in assi_plugin_data.form_options.size) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.image_generator?.size != undefined && assi_plugin_data?.settings?.image_generator?.size != '' && assi_plugin_data?.settings?.image_generator?.size == key ? 'selected' : '')}>${assi_plugin_data.form_options.size[key]}</option>`;
        }
    }
    return html;
}
function generateQualityOptions() {
    let html = '';
    if (assi_plugin_data.form_options.quality != undefined && typeof assi_plugin_data.form_options.quality == 'object') {
        for (const key in assi_plugin_data.form_options.quality) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.image_generator?.quality != undefined && assi_plugin_data?.settings?.image_generator?.quality != '' && assi_plugin_data?.settings?.image_generator?.quality == key ? 'selected' : '')}>${assi_plugin_data.form_options.quality[key]}</option>`;
        }
    }
    return html;
}
function generateOutputFormatOptions() {
    let html = '';
    if (assi_plugin_data.form_options.output_format != undefined && typeof assi_plugin_data.form_options.output_format == 'object') {
        for (const key in assi_plugin_data.form_options.output_format) {
            html += `<option value="${key}" ${(assi_plugin_data?.settings?.image_generator?.output_format != undefined && assi_plugin_data?.settings?.image_generator?.output_format != '' && assi_plugin_data?.settings?.image_generator?.output_format == key ? 'selected' : '')}>${assi_plugin_data.form_options.output_format[key]}</option>`;
        }
    }
    return html;
}

function generateArtStyleOptions() {
    let html = '';
    if (assi_plugin_data.form_options.art_style != undefined && typeof assi_plugin_data.form_options.art_style == 'object') {
        for (const key in assi_plugin_data.form_options.art_style) {
            html += `<optgroup label="${key}"></optgroup>`;
            if (assi_plugin_data.form_options.art_style[key] != undefined && typeof assi_plugin_data.form_options.art_style[key] == 'object') {
                for (const key2 in assi_plugin_data.form_options.art_style[key]) {
                    html += `<option value="${key2}" ${(assi_plugin_data?.settings?.image_generator?.art_style != undefined && assi_plugin_data?.settings?.image_generator?.art_style != '' && assi_plugin_data?.settings?.image_generator?.art_style == key2 ? 'selected' : '')}>${assi_plugin_data.form_options.art_style[key][key2]}</option>`;
                }
            }
            html += `</optgroup>`;
        }
    }
    return html;
}

function generateCustomStyleOptions() {
    let html = `<option value="0">${__('Select style', 'assistini')}</option>`;
    if (assi_plugin_data.form_options.custom_styles != undefined && typeof assi_plugin_data.form_options.custom_styles == 'object') {
        for (const key in assi_plugin_data.form_options.custom_styles) {
            if (assi_plugin_data.form_options.custom_styles[key].name != undefined) {
                html += `<option value="${key}">${assi_plugin_data.form_options.custom_styles[key].name}</option>`;
            }
        }
    }
    return html;
}

function initListeners() {
    jQuery(document).on('click', function (event) {
        if (!jQuery(event.target).hasClass('ass-es-notification-icon') && jQuery(event.target).closest('.ass-es-notification-dropdown').length <= 0 && !jQuery('.ass-es-notification-dropdown').is(':hidden')) {
            jQuery('.ass-es-notification-dropdown').fadeOut(150);
        }
    });

    let mediaUploader;
    jQuery('#ass-es-template-search-input').on('input propertychange', function () {
        let type = jQuery('.ass-es-template-search-category').val();
        let category = jQuery('.ass-es-template-category-item.ass-active').attr('data-category');
        let search = jQuery(this).val();
        if (search == '') {
            jQuery('.ass-es-template-list-item').addClass('ass-es-hidden');
            if (type == 'all') {
                jQuery('.ass-es-template-list-item[data-category="' + category + '"]').removeClass('ass-es-hidden');
            } else {
                jQuery('.ass-es-template-list-item[data-type="' + type + '"][data-category="' + category + '"]').removeClass('ass-es-hidden');
            }
            return;
        }
        let filtered = null;
        if (type == 'all') {
            filtered = jQuery('.ass-es-template-list-item[data-category="' + category + '"]').filter(function () {
                return jQuery(this).find('.ass-es-template-list-item-title').text().toLowerCase().includes(search.toLowerCase());
            });
        } else {
            filtered = jQuery('.ass-es-template-list-item[data-type="' + type + '"][data-category="' + category + '"]').filter(function () {
                return jQuery(this).find('.ass-es-template-list-item-title').text().toLowerCase().includes(search.toLowerCase());
            });
        }
        jQuery('.ass-es-template-list-item').addClass('ass-es-hidden');
        filtered.removeClass('ass-es-hidden');
    });
    jQuery(document).on('change', '.ass-es-template-search-category', function () {
        let type = jQuery(this).val();
        let category = jQuery('.ass-es-template-category-item.ass-active').attr('data-category');
        jQuery('#ass-es-template-search-input').val('');
        if (type == 'all') {
            jQuery('.ass-es-template-list-item[data-category="' + category + '"]').removeClass('ass-es-hidden');
        } else {
            jQuery('.ass-es-template-list-item').addClass('ass-es-hidden');
            jQuery('.ass-es-template-list-item[data-type="' + type + '"][data-category="' + category + '"]').removeClass('ass-es-hidden');
        }
    });

    jQuery(document).on('click', '.ass-es-template-list-item', function () {
        jQuery('.ass-es-page-template-submit-edit-btn').hide();
        hideResultContainer();
        jQuery('.ass-es-copy-btn[data-copy="all"]').fadeOut(150);
        let id = parseInt(jQuery(this).attr('data-id'));
        let type = jQuery(this).attr('data-type');
        let category = jQuery(this).attr('data-category');
        if (category == 'image') {
            jQuery('#ass-es-page-template-content').attr('placeholder', __('Describe the image you\'d like to create...\n\nExample: Create a Image form with my included Content. No Text.', 'assistini'));
            jQuery('#ass-es-page-template-custom-style').attr('placeholder', __('Select or define your style...\n\nExample: Use only the font size 14px and the color red.', 'assistini'));
            if (id == 26) {
                jQuery('.ass-es-page-template-submit-btn span').text(__('Edit Image', 'assistini'));
            } else {
                jQuery('.ass-es-page-template-submit-btn span').text(__('Create Image', 'assistini'));
            }
        } else if (category == 'audio') {
            jQuery('.ass-es-page-template-submit-btn span').text(__('Create Audio', 'assistini'));
        } else {
            if (type == 'editor' && id == 35) {
                jQuery('.ass-es-page-template-submit-btn span').text(__('Ask AI', 'assistini'));
                jQuery('#ass-es-page-template-content').attr('placeholder', __('Ask anything', 'assistini') + '...');
            } else {
                jQuery('#ass-es-page-template-content').attr('placeholder', __('Content', 'assistini') + '...');
                jQuery('#ass-es-page-template-custom-style').attr('placeholder', __('Custom Style', 'assistini') + '...');
                jQuery('.ass-es-page-template-submit-btn span').text(__('Write', 'assistini'));
            }
        }
        let entry = globalTemplates.find(x => x.id == id && x.type == type);
        if (entry != undefined && entry != null) {
            jQuery('.ass-es-page-template').attr('data-template-id', entry.id).attr('data-is-system', (entry.is_system != undefined && entry.is_system == 1 ? true : false)).attr('data-type', type);
            let focusKeyword = jQuery('#ass-es-page-template-focus-keyword').val();
            let pov = jQuery('#ass-es-page-template-pov').val();
            let tone = jQuery('#ass-es-page-template-tone').val();
            let language = jQuery('#ass-es-page-template-language').val();
            jQuery('#ass-es-page-template-form')[0].reset();
            jQuery('.ass-es-page-template-speaker-list').html('');
            jQuery('.ass-es-page-template-conversation-list').html('');
            jQuery('#ass-es-page-template-focus-keyword').val(focusKeyword);
            jQuery('#ass-es-page-template-pov').val(pov);
            jQuery('#ass-es-page-template-tone').val(tone);
            jQuery('#ass-es-page-template-language option').prop('disabled', false).show();
            jQuery('#ass-es-page-template-language').val(language);
            jQuery('#ass-es-page-template-style').val('0').trigger('change');
            if (jQuery('#ass-es-page-template-content').prop('disabled')) {
                jQuery('#ass-es-page-template-content').prop('disabled', false);
            }
            jQuery('#ass-es-page-template-image').attr('data-id', 0).attr('data-url', '');
            jQuery('.ass-es-page-template-input-ctn').hide();
            if (type == TYPE_USER) {
                jQuery('.ass-es-page-template-input-ctn[data-id="post_content"]').show();
                jQuery('.ass-es-page-template-input-ctn[data-id="content"]').show();
                jQuery('.ass-es-page-template-input-ctn[data-id="point_of_view"]').show();
                jQuery('.ass-es-page-template-input-ctn[data-id="tone"]').show();
                jQuery('.ass-es-page-template-input-ctn[data-id="prompt_language"]').show();
                if (entry.point_of_view != undefined && entry.point_of_view != '') {
                    jQuery('#ass-es-page-template-pov').val(entry.point_of_view);
                }
                if (entry.tone != undefined && entry.tone != '') {
                    jQuery('#ass-es-page-template-tone').val(entry.tone);
                }
                if (entry.language != undefined && entry.language != '') {
                    jQuery('#ass-es-page-template-language').val(entry.language);
                }
            } else if (entry.option_fields != undefined && typeof entry.option_fields == 'object' && entry.option_fields.length > 0) {
                jQuery('#ass-es-page-template-format').html(generateOutputFormatOptions());
                jQuery('#ass-es-page-template-language').html(generateLanguageOptions());
                jQuery('.ass-es-page-template-group[data-group="style"]').hide();
                entry.option_fields.forEach(x => {
                    if (x != '') {
                        let show = true;
                        if (x == 'focus_keyword') {
                            if (jQuery('#ass-es-page-template-focus-keyword').val() == undefined || jQuery('#ass-es-page-template-focus-keyword').val() == '') {
                                jQuery.ajax({
                                    url: ajaxurl,
                                    type: 'POST',
                                    data: {
                                        action: 'assi_editor_post_get_focus_keyword',
                                        post_id: jQuery('#post_ID').val(),
                                        assi_security_nonce: assi_plugin_data.assi_security_nonce
                                    },
                                    success: function (data) {
                                        data = JSON.parse(data);
                                        if (data.result != undefined && data.result == true && data.focus_keyword != undefined && data.focus_keyword != '') {
                                            jQuery('#ass-es-page-template-focus-keyword').val(data.focus_keyword);
                                        }
                                    }
                                });
                            }
                        }
                        if (x == 'size') {
                            jQuery('ass-es-page-template-size').html('').html(generateSizeOptions());
                        }
                        if (x == 'models' && entry?.option_models != undefined && Object.keys(entry?.option_models).length > 0) {
                            if (Object.keys(entry?.option_models).length == 1) {
                                show = false;
                            }
                            jQuery('#ass-es-page-template-model').html('');
                            let modelsHtml = '';
                            for (const [key] of Object.entries(entry.option_models)) {
                                modelsHtml += '<option value="' + key + '">' + (assi_plugin_data?.translations?.models[key] != undefined ? assi_plugin_data.translations.models[key] : key) + '</option>';
                            }
                            jQuery('#ass-es-page-template-model').html(modelsHtml);
                            let firstEntry = Object.values(entry?.option_models)[0];
                            if (firstEntry != undefined && firstEntry.size != undefined && firstEntry.size.length > 0) {
                                jQuery('#ass-es-page-template-size').html('');
                                let sizeHtml = '<option value="auto">' + __('Auto', 'assistini') + '</option>';
                                firstEntry.size.forEach((x) => {
                                    sizeHtml += '<option value="' + x + '">' + x + '</option>';
                                });
                                jQuery('#ass-es-page-template-size').html(sizeHtml);
                            }
                            if (firstEntry != undefined && firstEntry?.voices?.male != undefined && firstEntry?.voices?.female != undefined) {
                                jQuery('#ass-es-page-template-speaker-voice').html('');
                                let voicesHtml = '<optgroup label="' + __('Male', 'assistini') + '">';
                                firstEntry.voices.male.forEach((x) => {
                                    voicesHtml += '<option value="' + x + '">' + x + '</option>';
                                })
                                voicesHtml += '</optgroup>';
                                voicesHtml += '<optgroup label="' + __('Female', 'assistini') + '">';
                                firstEntry.voices.female.forEach((x) => {
                                    voicesHtml += '<option value="' + x + '">' + x + '</option>';
                                });
                                voicesHtml += '</optgroup>';
                                jQuery('#ass-es-page-template-speaker-voice').html(voicesHtml);
                            }
                            if (firstEntry != undefined && firstEntry?.output_format != undefined ) {
                                jQuery('#ass-es-page-template-format').html('');
                                let outputFormatHtml = '';
                                firstEntry.output_format.forEach((x) => {
                                    outputFormatHtml += '<option value="' + x + '">.' + x.toUpperCase() + '</option>';
                                });
                                jQuery('#ass-es-page-template-format').html(outputFormatHtml);
                            }
                            if (firstEntry != undefined && firstEntry?.prompt_language != undefined) {
                                jQuery('#ass-es-page-template-language option').prop('disabled', true).hide();
                                firstEntry.prompt_language.forEach((x) => {
                                    jQuery('#ass-es-page-template-language option[value="' + x + '"]').prop('disabled', false).show();
                                });
                                let langValue = jQuery('#ass-es-page-template-language').val();
                                if (langValue == null || jQuery('#ass-es-page-template-language option[value="' + langValue + '"]').prop('disabled') == true) {
                                    jQuery('#ass-es-page-template-language').val('en_US');
                                }
                            }
                            if (assi_plugin_data?.custom_ai_connection?.active != undefined && assi_plugin_data.custom_ai_connection.active > 0) {
                                show = false;
                            }
                        }
                        if (show) {
                            if (x == 'art_style' || x == 'custom_style') {
                                jQuery('.ass-es-page-template-group[data-group="style"]').show();
                            }
                            jQuery('.ass-es-page-template-input-ctn[data-id="' + x + '"]').show();
                        }
                    }
                });
            }
            jQuery('.ass-es-page-template-content-ctn').show();
            jQuery('.ass-es-page-template-input-ctn[data-id="additional_content"]').hide();
            jQuery('.ass-es-page-template-title').text(entry.header);
            if (entry.text.length > 200) {
                entry.text = entry.text.substring(0, 200) + '...';
            }
            displayHistory(id, type);
        }
        jQuery('.ass-es-page-template').css('transform', 'translateX(0%)');
        setTimeout(() => {
            jQuery('.ass-es-licence-collapse').trigger('click');
        }, 150);
    });

    jQuery(document).on('click', '.ass-es-page-template-close-ctn', function () {
        jQuery('.ass-es-page-template').attr('data-template-id', 0).attr('data-is-system', false);
        jQuery('.ass-es-page-template').css('transform', (assi_plugin_data.editor_type == 'default' ? 'translateX(-100%)' : 'translateX(100%)'));
    });

    jQuery(document).on('change', '#ass-es-page-template-content-check', function () {
        if (jQuery(this).is(':checked')) {
            jQuery('#ass-es-page-template-content-additional').val(jQuery('#ass-es-page-template-content').val());
            const postContent = getWpEditorContent();
            if (postContent != null && postContent != '') {
                jQuery('#ass-es-page-template-content').prop('disabled', true);
                jQuery('.ass-es-page-template-content-ctn').hide();
                jQuery('.ass-es-page-template-input-ctn[data-id="additional_content"]').show();
                if (jQuery('.ass-es-page-template').attr('data-is-system') == 'true') {
                    if (jQuery('.ass-es-page-template').attr('data-template-id') != 34) {
                        jQuery('#ass-es-page-template-language').val('auto');
                    }
                }
            }
        } else {
            jQuery('#ass-es-page-template-content').val(jQuery('#ass-es-page-template-content-additional').val());
            jQuery('#ass-es-page-template-content').prop('disabled', false);
            console.log(jQuery('.ass-es-template').attr('data-template-id'));
            if (jQuery('.ass-es-page-template').attr('data-template-id') == 34) {
                jQuery('#ass-es-page-template-language').prop('disabled', false);
            } else {
                jQuery('#ass-es-page-template-language').val((assi_plugin_data?.settings?.content_creator?.language != undefined && assi_plugin_data?.settings?.content_creator?.language != '' ? assi_plugin_data.settings.content_creator.language : '')).prop('disabled', false);
            }
            jQuery('.ass-es-page-template-content-ctn').show();
            jQuery('.ass-es-page-template-input-ctn[data-id="additional_content"]').hide();
        }
    });

    if (assi_plugin_data.editor_type == 'default') {
        wp.data.subscribe(function () {
            const postContent = wp.data.select('core/editor').getEditedPostContent();
            let cleanContent = postContent.replace(/<!--.*?-->/gs, '');
            if (!cleanContent.trim()) {
                if (jQuery('#ass-es-page-template-content-check').is(':checked') == true) {
                    jQuery('#ass-es-page-template-content-check').prop('checked', false);
                    jQuery('.ass-es-page-template-content-ctn').show();
                    jQuery('.ass-es-page-template-input-ctn[data-id="additional_content"]').hide();
                }
                if (jQuery('#ass-es-page-template-content-check').prop('disabled') == false) {
                    jQuery('#ass-es-page-template-content-check').prop('disabled', true);
                }
                if (jQuery('#ass-es-page-template-content').prop('disabled') == true) {
                    jQuery('#ass-es-page-template-content').prop('disabled', false);
                }
            } else {
                if (jQuery('#ass-es-page-template-content-check').prop('disabled') == true) {
                    jQuery('#ass-es-page-template-content-check').prop('disabled', false);
                }
            }
        });
    }

    jQuery(document).on('click', '.ass-es-page-template-submit-btn', function (e) {
        e.preventDefault();

        let templateId = jQuery('.ass-es-page-template').attr('data-template-id');
        let isSystem = jQuery('.ass-es-page-template').attr('data-is-system');
        displayHistory(parseInt(templateId), (isSystem == 'true' ? TYPE_EDITOR : TYPE_USER));
        let content = '';
        if (jQuery('#ass-es-page-template-content-check').is(':checked')) {
            content = getWpEditorContent();
        } else {
            content = jQuery('#ass-es-page-template-content').val();
        }
        let entry = {};
        if (isSystem == 'true') {
            entry = globalTemplates.find(x => x.id == templateId && x.is_system == 1);
        } else {
            entry = globalTemplates.find(x => x.id == templateId && x.is_system == 0);
        }
        jQuery('.ass-es-page-template-scroll-ctn').animate({
            scrollTop: jQuery('.ass-es-page-template-header').outerHeight()
        }, 250);
        if (entry != undefined && entry?.category != undefined && entry.category == 'image') {
            editorGenerateImage(templateId, entry, isSystem, content);
            return;
        }
        if (entry != undefined && entry?.category != undefined && entry.category == 'audio') {
            editorGenerateAudio(templateId, entry, isSystem, content);
            return;
        }

        if (entry?.option_required != undefined && typeof entry.option_required == 'object' && entry.option_required.length > 0) {
            let returnError = false;
            entry.option_required.forEach((type) => {
                let $element = jQuery('.ass-es-page-template-form-input[data-id="' + type + '"]');
                let value = $element.val();
                if (type == 'content') {
                    value = content;
                }
                if (value == undefined || value == '') {
                    returnError = true;
                    $element.addClass('ass-es-red-border');
                    setTimeout(function () {
                        $element.removeClass('ass-es-red-border');
                    }, 2000);
                }
            });
            if (returnError == true) {
                return;
            }
        }

        let data = {
            action: 'assi_editor_send_prompt',
            template_id: templateId,
            assi_security_nonce: assi_plugin_data.assi_security_nonce,
            is_system: isSystem,
            request_id: generateRequestId()
        };

        if (entry?.option_fields != undefined && typeof entry.option_fields == 'object' && entry.option_fields.length > 0) {
            entry.option_fields.forEach((type) => {
                if (type != 'post_content') {
                    if (type == 'content') {
                        data[type] = content;
                    } else if (type == 'refer_post_content') {
                        if (jQuery('#ass-es-page-template-refer-content-check').is(':checked')) {
                            data[type] = getWpEditorContent();
                        } else {
                            data[type] = '';
                        }
                    } else {
                        data[type] = jQuery('.ass-es-page-template-form-input[data-id="' + type + '"]').val();
                    }
                }
            });
        }

        if (assi_plugin_data?.custom_ai_connection?.active == undefined || assi_plugin_data.custom_ai_connection.active == 0) {
            if (proxyLiveData.creditsOpen <= 0) {
                openUpgradeModal();
                return;
            }
        }
        jQuery.ajax({
            url: ajaxurl,
            type: 'POST',
            data: data,
            beforeSend: function () {
                showTemplateResultLoader(jQuery('#ass-es-page-template-number').val());
            },
            success: function (data) {
                data = JSON.parse(data);
                if (data != undefined && data?.result != undefined && data?.result == true && data?.content != undefined) {
                    showTemplateResult(data.content);
                    if (data?.user_data?.credits_open != undefined) {
                        proxyLiveData.creditsOpen = data.user_data.credits_open;
                    }
                    initHistory();
                } else {
                    if (data?.error != undefined && data.error == 'client_timeout') {
                        hideResultContainer();
                        showTimeoutNotice();
                        startNotificationHeartbeat();
                    } else {
                        hideResultContainer();
                        showNotice('error', (data?.error_message != undefined ? data.error_message : ''));
                    }
                }
            },
            error: function (xhr, status, error) {
                if (xhr.status == 504) {
                    jQuery.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'assi_create_notification',
                            type: 'editor',
                            category: 'text',
                            assi_security_nonce: assi_plugin_data.assi_security_nonce,
                            request_data: data
                        },
                        complete: function () {
                            startNotificationHeartbeat();
                        }
                    });
                    hideResultContainer();
                    showTimeoutNotice();
                } else {
                    jQuery('.ass-es-page-template-result-item').hide();
                    showNotice('error');    
                }
            }
        });
    });
    jQuery('.ass-es-modal-dismiss').on('click', function (e) {
        let $modalParent = jQuery(e.target).closest('.ass-es-modal');
        if ($modalParent.length > 0) {
            $modalParent.fadeOut(150);
        }
        if ($modalParent.attr('id') == 'ass-es-modal-consent') {
            jQuery('#ass-es-modal-consent-rejected').fadeIn(150);
        }
    });
    jQuery(document).on('change', '#ass-es-modal-consent-checkbox', function (e) {
        if (jQuery(this).is(':checked')) {
            jQuery('.ass-es-modal-consent-save-btn').prop('disabled', false);
        } else {
            jQuery('.ass-es-modal-consent-save-btn').prop('disabled', true);
        }
    });
    jQuery(document).on('click', '.ass-es-modal-consent-save-btn', function () {
        if (jQuery('#ass-es-modal-consent-checkbox').is(':checked')) {
            jQuery.ajax({
                url: ajaxurl,
                type: "POST",
                cache: false,
                data: {
                    'action': 'assi_settings_consent_save',
                    'consent': 'true',
                    'assi_security_nonce': assi_plugin_data.assi_security_nonce
                },
                success: function (data) {
                    data = JSON.parse(data);
                    if (data.result != undefined && data.result == true) {
                        window.location.reload();
                    } else {
                        showNotice('error', (data.error_message != undefined ? data.error_message : ''));
                    }
                },
                error: function () {
                    showNotice('error');
                }
            });
        } else {
            return;
        }
    });

    jQuery(document).on('click', '.ass-es-modal-upgrade-btn', function () {
        window.open('https://app.assistini.com/?screen=Plan', '_blank');
    });
    jQuery('#ass-es-page-template-number').on('input propertychange', function () {
        let value = parseInt(jQuery(this).val());
        if (isNaN(value) || value < 1 || value > 5) {
            jQuery('#ass-es-page-template-number').val(1);
        }
    });
    jQuery(document).on('click', '.ass-es-template-category-item', function () {
        if (jQuery(this).hasClass('ass-active')) {
            return;
        }
        let category = jQuery(this).attr('data-category');
        if (category == 'text') {
            jQuery('.ass-es-template-search-ctn').slideDown(150);
        } else {
            jQuery('.ass-es-template-search-category').val('all').trigger('change');
            jQuery('.ass-es-template-search-ctn').slideUp(150);
        }
        let type = jQuery('.ass-es-template-search-category').val();
        jQuery('.ass-es-template-category-item').removeClass('ass-active');
        jQuery(this).addClass('ass-active');
        jQuery('.ass-es-template-list-item').addClass('ass-es-hidden');
        if (type == 'all') {
            jQuery('.ass-es-template-list-item[data-category="' + category + '"]').removeClass('ass-es-hidden');
        } else {
            jQuery('.ass-es-template-list-item[data-type="' + type + '"][data-category="' + category + '"]').removeClass('ass-es-hidden');
        }
    });
    jQuery(document).on('click', '.ass-es-save-image-download-btn', function () {
        let $imageElement = jQuery(this).closest('.ass-es-page-template-image-result-item').find('.ass-es-page-template-image-result-item-image-tag');
        if ($imageElement.length > 0) {
            let imageUrl = $imageElement.attr('src');
            let imageFilename = $imageElement.attr('data-filename');
            fetch(imageUrl).then(response => response.blob()).then(blob => {
                const blobUrl = URL.createObjectURL(blob);
                let link = document.createElement('a');
                link.download = imageFilename;
                link.href = blobUrl;
                link.click();
                link.remove();
                URL.revokeObjectURL(blobUrl);
            }).catch(error => {return});
        }
    });
    jQuery(document).on('click', '.ass-es-save-image-to-library-btn', async function () {
        let $btn = jQuery(this);
        let $element = jQuery(this).closest('.ass-es-page-template-image-result-item').find('.ass-es-page-template-image-result-item-image-tag');
        if ($element.length > 0) {
            let imageData = $element.attr('src');
            let filename = $element.attr('data-filename');
            let title = $element.attr('data-title');
            let extension = $element.attr('data-extension');
            let requestId = $element.attr('data-request-id');
            if (imageData != undefined && imageData != '') {
                jQuery('.ass-es-save-image-to-library-btn-icon').hide();
                jQuery('.ass-es-save-image-to-library-btn-text').hide();
                jQuery('.ass-es-template-image-save-loader').show();
                let uploadResult = await uploadImageToLibrary(requestId, imageData, filename, title, extension);
                initNotifications();
                initHistory();
                if (uploadResult) {
                    let $tooltip = $btn.find('.ass-save-tooltip');
                    if ($tooltip.length === 0) {
                        $tooltip = jQuery('<span class="ass-save-tooltip">' + __('is saved!', 'assistini') + '</span>');
                        $btn.append($tooltip);
                    }
                    $tooltip.fadeIn(150);
                    setTimeout(() => {
                        $tooltip.fadeOut(300);
                    }, 1500);
                } else {
                    showNotice('error');
                }
                jQuery('.ass-es-template-image-save-loader').hide();
                jQuery('.ass-es-save-image-to-library-btn-icon').show();
                jQuery('.ass-es-save-image-to-library-btn-text').show();
            }
        }
    });
    jQuery(document).on('click', '.ass-es-save-audio-download-btn', function () {
        let $audioElement = jQuery(this).closest('.ass-es-page-template-audio-result-item').find('.ass-es-page-template-audio-result-item-audio-tag');
        if ($audioElement.length > 0) {
            let audioUrl = $audioElement.attr('data-src');
            let audioFilename = $audioElement.attr('data-filename');
            fetch(audioUrl).then(response => response.blob()).then(blob => {
                const blobUrl = URL.createObjectURL(blob);
                let link = document.createElement('a');
                link.download = audioFilename;
                link.href = blobUrl;
                link.click();
                link.remove();
                URL.revokeObjectURL(blobUrl);
            }).catch(error => {return});
        }
    });
    jQuery(document).on('click', '.ass-es-save-audio-to-library-btn', async function () {
        let $btn = jQuery(this);
        let $element = jQuery(this).closest('.ass-es-page-template-audio-result-item').find('.ass-es-page-template-audio-result-item-audio-tag');
        if ($element.length > 0) {
            let audioData = $element.attr('src');
            let filename = $element.attr('data-filename');
            let title = $element.attr('data-title');
            let extension = $element.attr('data-extension');
            let requestId = $element.attr('data-request-id');
            if (audioData != undefined && audioData != '') {
                jQuery('.ass-es-save-audio-to-library-btn-icon').hide();
                jQuery('.ass-es-save-audio-to-library-btn-text').hide();
                jQuery('.ass-es-template-audio-save-loader').show();
                let uploadResult = await uploadAudioToLibrary(requestId, audioData, filename, title, extension);
                initNotifications();
                initHistory();
                if (uploadResult) {
                    let $tooltip = $btn.find('.ass-save-tooltip');
                    if ($tooltip.length === 0) {
                        $tooltip = jQuery('<span class="ass-save-tooltip">' + __('is saved!', 'assistini') + '</span>');
                        $btn.append($tooltip);
                    }
                    $tooltip.fadeIn(150);
                    setTimeout(() => {
                        $tooltip.fadeOut(300);
                    }, 1500);
                } else {
                    showNotice('error');
                }
                jQuery('.ass-es-template-audio-save-loader').hide();
                jQuery('.ass-es-save-audio-to-library-btn-icon').show();
                jQuery('.ass-es-save-audio-to-library-btn-text').show();
            }
        }
    });
    jQuery(document).on('click', '.ass-es-licence-collapse', function () {
        jQuery('.ass-es-licence-hide-collapsed').slideUp(100, function () {
            setTimeout(() => {
                jQuery('.ass-es-licence-show-collapsed').slideDown(100);
            }, 50);
        });
    });
    jQuery(document).on('click', '.ass-es-licence-expand', function () {
        jQuery('.ass-es-licence-show-collapsed').slideUp(100, function () {
            setTimeout(() => {
                jQuery('.ass-es-licence-hide-collapsed').slideDown(100);
            }, 50);
        });
    });

    jQuery('.ass-es-page-template-image-upload').on('click', function (e) {
        e.preventDefault();
        if (mediaUploader) {
            mediaUploader.detach();
            mediaUploader = null;
        }
        mediaUploader = wp.media({
            title: __('Choose Image', 'assistini'),
            button: {
                text: __('Choose Image', 'assistini')
            },
            multiple: false
        });
        mediaUploader.on('select', function () {
            let error = '';
            let allowedMimeTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
            let attachment = mediaUploader.state().get('selection').first().toJSON();

            let attachmentType = attachment.type;
            let attachmentMime = attachment.mime;
            let attachmentSize = attachment.filesizeInBytes;

            if (attachmentType != 'image') {
                error = __('The selected file is not an image.', 'assistini');
            } else if (!allowedMimeTypes.includes(attachmentMime)) {
                error = __('The selected file type is not supported. Please select a JPEG, PNG, or WebP image.', 'assistini');
            } else if (attachmentSize / 1024 / 1024 > 3) {
                error = __('The selected file is too large. Please select an image less than 3MB.', 'assistini');
            }
            if (error != '') {
                jQuery('.ass-es-page-template-image-error-text').text(error);
                let $errorCtn = jQuery('.ass-es-page-template-image-error-ctn');
                $errorCtn.css('height', 'auto');
                let ctnHeight = $errorCtn.outerHeight();
                $errorCtn.css('height', 0);
                $errorCtn.animate({height: ctnHeight}, 300);
                setTimeout(() => {
                    $errorCtn.animate({height: 0}, 300);
                }, 6000);
            } else {
                jQuery('#ass-es-page-template-image').val(attachment.title).attr('data-id', attachment.id);
            }
        });
        mediaUploader.open();
    });

    jQuery(document).on('change', '#ass-es-page-template-model', function () {
        let templateId = parseInt(jQuery('.ass-es-page-template').attr('data-template-id'));
        let type = jQuery('.ass-es-page-template').attr('data-type');
        let model = jQuery(this).val();
        let entry = globalTemplates.find(x => x.id == templateId && x.type == type);
        if (entry?.option_models[model] != undefined && entry?.option_models[model].size != undefined && entry?.option_models[model].size.length > 0) {
            let sizeHtml = '<option value="auto">' + __('Auto', 'assistini') + '</option>';
            entry?.option_models[model].size.forEach(size => {
                sizeHtml += '<option value="' + size + '">' + size + '</option>';
            });
            jQuery('#ass-es-page-template-size').html(sizeHtml);
        } else {
            jQuery('#ass-es-page-template-size').html(generateSizeOptions());
        }
        
    });
    jQuery(document).on('click', '.ass-es-modal-close', function () {
        let $modalElement = jQuery(this).closest('.ass-es-modal')[0];
        if ($modalElement) {
            jQuery($modalElement).fadeOut(150, () => {
                jQuery($modalElement).show();
                $modalElement.close();
            });
            if ($modalElement.id == 'ass-es-modal-consent') {
                openConsentModal('rejected');
            }
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-style-save', function () {
        let dialog = document.getElementById('ass-es-modal-custom-style');
        let id = parseInt(jQuery('#ass-es-page-template-style').val());
        if (id > 0 && assi_plugin_data.form_options.custom_styles[id] != undefined) {
            jQuery('#ass-es-modal-custom-style-name').val(assi_plugin_data.form_options.custom_styles[id].name);
        } else {
            jQuery('#ass-es-modal-custom-style-name').val('');
        }
        dialog.showModal();
        jQuery('#ass-es-modal-custom-style').hide();
        jQuery('#ass-es-modal-custom-style').fadeIn(150);
    });
    jQuery(document).on('click', '.ass-es-modal-custom-style-save', function () {
        let id = parseInt(jQuery('#ass-es-page-template-style').val());
        let name = jQuery('#ass-es-modal-custom-style-name').val();
        let content = jQuery('#ass-es-page-template-custom-style').val();
        let art = jQuery('#ass-es-page-template-art-style').val();
        if (name != undefined && name != '' && content != undefined && content != '') {
            jQuery.ajax({
                url: ajaxurl,
                type: "POST",
                cache: false,
                data: {
                    'action': 'assi_save_custom_style',
                    'id': id,
                    'name': name,
                    'content': content,
                    'art': art,
                    'assi_security_nonce': assi_plugin_data.assi_security_nonce
                },
                beforeSend: function () {
                    jQuery('.ass-es-modal-custom-style-save').prop('disabled', true);
                    jQuery('.ass-es-modal-custom-style-save-text').hide();
                    jQuery('.ass-es-modal-custom-style-loader').show();
                },
                success: function (data) {
                    data = JSON.parse(data);
                    if (data.result != undefined && data.result == true && data.id != undefined && data.styles != undefined) {
                        assi_plugin_data.form_options.custom_styles = data.styles;
                        jQuery('#ass-es-page-template-style').html(generateCustomStyleOptions());
                        jQuery('#ass-es-page-template-style').val(data.id);
                    } else if (data.error != undefined) {
                        showNotice('error', (data.error_message != undefined ? data.error_message : ''));
                    }
                },
                error: function () {
                    showNotice('error');
                },
                complete: function () {
                    jQuery('.ass-es-modal-custom-style-loader').hide();
                    jQuery('.ass-es-modal-custom-style-save-text').show();
                    jQuery('.ass-es-modal-custom-style-save').prop('disabled', false);
                    jQuery(jQuery('#ass-es-modal-custom-style').find('.ass-es-modal-close')[0]).trigger('click');
                }
            });
        } else {
            jQuery('#ass-es-modal-custom-style-name').addClass('ass-es-red-border');
            setTimeout(function () {
                jQuery('#ass-es-modal-custom-style-name').removeClass('ass-es-red-border');
            }, 2000)
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-style-delete', function () {
        let id = parseInt(jQuery('#ass-es-page-template-style').val());
        if (id > 0 && assi_plugin_data.form_options.custom_styles[id] != undefined) {
            jQuery.ajax({
                url: ajaxurl,
                type: "POST",
                cache: false,
                data: {
                    'action': 'assi_delete_custom_style',
                    'id': id,
                    'assi_security_nonce': assi_plugin_data.assi_security_nonce
                },
                success: function (data) {
                    data = JSON.parse(data);
                    if (data.result != undefined && data.result == true && data.styles != undefined) {
                        assi_plugin_data.form_options.custom_styles = data.styles;
                        jQuery('#ass-es-page-template-style').html(generateCustomStyleOptions());
                        jQuery('#ass-es-page-template-custom-style').val('');
                        jQuery('.ass-es-page-template-style-delete').fadeOut(150);
                    } else if (data.error != undefined) {
                        showNotice('error', (data.error_message != undefined ? data.error_message : ''));
                    }
                },
                error: function () {
                    showNotice('error');
                }
            });
        }
    });
    jQuery(document).on('change', '#ass-es-page-template-style', function () {
        let id = parseInt(jQuery(this).val());
        if (id > 0 && assi_plugin_data?.form_options?.custom_styles != undefined && typeof assi_plugin_data?.form_options?.custom_styles == 'object') {
            let style = assi_plugin_data.form_options.custom_styles[id];
            if (style != undefined && style.content != undefined) {
                jQuery('#ass-es-page-template-custom-style').val(style.content);
                if (style.art != undefined && style.art != '') {
                    jQuery('#ass-es-page-template-art-style').val(style.art);
                }
            }
            jQuery('.ass-es-page-template-style-delete').fadeIn(150);
        } else {
            jQuery('.ass-es-page-template-style-delete').fadeOut(150);
            jQuery('#ass-es-page-template-custom-style').val('');
        }
    });

    jQuery(document).on('click', '.ass-es-notification-icon', function () {
        if (jQuery('.ass-es-notification-dropdown').is(':hidden')) {
            jQuery('.ass-es-notification-dropdown').fadeIn(150);
        } else {
            jQuery('.ass-es-notification-dropdown').fadeOut(150);
        }
    });
    jQuery(document).on('click', '.ass-es-notification-list-delete-icon', function () {
        let $element = jQuery(this).closest('.ass-es-notification-list-item');
        let notificationId = parseInt($element.attr('data-id'));
        jQuery.ajax({
            url: ajaxurl,
            type: "POST",
            cache: false,
            data: {
                'action': 'assi_delete_notification',
                'notification_id': notificationId,
                'assi_security_nonce': assi_plugin_data.assi_security_nonce
            }
        });
        proxyLiveData.notifications = proxyLiveData.notifications.filter(x => x.notification_id != notificationId);
        $element.css('position', 'relative').animate({
            left: '330px'
        }, 100, function () {
            $element.slideToggle(150, function () {
                $element.remove();
            });
        });
    });
    jQuery(document).on('click', '.ass-es-notification-list-item', function () {
        let id = parseInt(jQuery(this).attr('data-id'));
        let entry = proxyLiveData.notifications.find(x => x.notification_id == id);
        if (entry != undefined) {
            let templateId = entry?.notification_data?.request_data?.template_id;
            let type = entry?.notification_data?.request_data?.type;
            let category = entry?.notification_data?.request_data?.category;
            if (entry?.notification_data?.request_data?.is_system != undefined && entry.notification_data.request_data.is_system == false) {
                type = 'user';
            }
            let $element = jQuery('.ass-es-template-list-item[data-id="' + templateId + '"][data-type="' + type + '"][data-category="' + category + '"]');
            if ($element.length > 0) {
                notificationFillTemplateForm(entry?.request_id, entry.notification_data);
                let $templatePage = jQuery('.ass-es-page-template');
                if ($templatePage.attr('style') == 'transform: translateX(0%);') {
                    jQuery('.ass-es-page-template-close-ctn').trigger('click');
                    setTimeout(function () {
                        $element.trigger('click');
                    }, 200);
                } else {
                    $element.trigger('click');
                }
            }
        }
    });
    jQuery(document).on('click', '.ass-es-modal-notification-show', function () {
        if (assi_plugin_data.editor_type == 'classic') {
            let sidebar = document.getElementById('ass-es');
            if (sidebar.style.transform === 'translateX(100%)' || sidebar.style.transform === '') {
                jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
            }
        } else {
            if (jQuery('#ass-es').width() <= 0) {
                jQuery('.ass-es-toggle.ass-es-toggle-btn').trigger('click');
            }
        }
        jQuery('#ass-es-modal-notification').find('.ass-es-modal-close').trigger('click');
        setTimeout(function () {
            if (jQuery('.ass-es-notification-dropdown').is(':hidden')) {
                jQuery('.ass-es-notification-dropdown').fadeIn(150);
            }
        }, 300);
    });

    jQuery(function () {
        
    });
    jQuery(document).on('click', '.ass-es-page-template-speaker-add', function () {
        let name = jQuery('#ass-es-page-template-speaker').val().trim();
        let speaker = jQuery('#ass-es-page-template-speaker-voice').val();
        if (name == undefined || name == '') {
            return;
        }
        addSpeakerListItem(name, speaker);
        jQuery('#ass-es-page-template-speaker').val('');
        updateConversationSpeakerList();
    });
    jQuery(document).on('click', '.ass-es-page-template-conversation-add', function () {
        let speaker = jQuery('#ass-es-page-template-conversation-speaker').val().trim();
        let speakerId = jQuery('#ass-es-page-template-conversation-speaker option:selected').attr('data-id');
        let text = jQuery('#ass-es-page-template-conversation').val().trim();
        if (speaker == undefined || speaker == '' || text == undefined || text == '') {
            return;
        }
        addConversationListItem(speaker, text, speakerId);
        jQuery('#ass-es-page-template-conversation').val('');
    });
    jQuery(document).on('click', '.ass-es-page-template-speaker-list-item-delete', function () {
        jQuery(this).closest('.ass-es-page-template-speaker-list-item').remove();
        updateConversationSpeakerList();
    });
    jQuery(document).on('click', '.ass-es-page-template-conversation-list-item-delete', function () {
        jQuery(this).closest('.ass-es-page-template-conversation-list-item').remove();
    });

    let dragging = null;
    let placeholder = jQuery("<li class='ass-es-page-template-conversation-list-item ass-es-page-template-conversation-list-item-drag-placeholder'></li>");
    let offsetY = 0;

    jQuery(document).on("mousedown", ".ass-es-page-template-conversation-list-item", function (e) {
        e.preventDefault();
        if (e.target.classList.contains('ass-es-page-template-conversation-list-item-delete')) {
            return;
        }
        dragging = jQuery(this);
        offsetY = e.pageY - dragging.offset().top;

        dragging.addClass("ass-es-page-template-conversation-list-item-dragging");
        dragging.css({
            position: "absolute",
            width: dragging.width(),
            "z-index": 1000,
        });
        placeholder.height(dragging.height());
        dragging.after(placeholder);
        jQuery("body").append(dragging);
        dragging.css({
            top: e.pageY - offsetY,
            left: jQuery(".ass-es-page-template-conversation-list").offset().left
        });
    });

    jQuery(document).on("mousemove", function (e) {
        if (!dragging) return;

        dragging.css({
            top: e.pageY - offsetY,
            left: jQuery(".ass-es-page-template-conversation-list").offset().left
        });

        jQuery(".ass-es-page-template-conversation-list li:not(.placeholder)").each(function () {
            const item = jQuery(this);
            const itemMid = item.offset().top + item.outerHeight() / 2;

            if (e.pageY < itemMid) {
                placeholder.insertBefore(item);
                return false;
            } else {
                placeholder.insertAfter(item);
            }
        });
    });

    jQuery(document).on("mouseup", function () {
        if (!dragging) return;
        const targetPos = placeholder.position().top;
        dragging.animate({ top: targetPos }, 50, function () {
            dragging.removeAttr("style").removeClass("ass-es-page-template-conversation-list-item-dragging");
            placeholder.replaceWith(dragging);
            dragging = null;
        });
    });
    jQuery(document).on('change', '#ass-es-page-template-custom-content-check', function () {
        if (jQuery(this).is(':checked')) {
            jQuery('.ass-es-page-template-input-ctn[data-id="content"]').hide();
            jQuery('.ass-es-page-template-input-ctn[data-id="conversation"]').show();
        } else {
            jQuery('.ass-es-page-template-input-ctn[data-id="conversation"]').hide();
            jQuery('.ass-es-page-template-input-ctn[data-id="content"]').show();
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-speaker-voice-play', function (e) {
        e.preventDefault();
        let voice = jQuery('#ass-es-page-template-speaker-voice').val().trim().toLowerCase();
        let audio = new Audio(assi_plugin_data.plugin_path + '/assets/audio/voices/' + voice + '.wav');
        audio.play();
    });
    jQuery(document).on('click', '.ass-es-page-template-history-item', function (e) {
        if (
            jQuery(e.target).closest('.ass-es-page-template-history-variants-item').length > 0 ||
            jQuery(e.target).closest('.ass-es-page-template-history-item-action-reload').length > 0 ||
            jQuery(e.target).closest('.ass-es-page-template-history-item-action-delete').length > 0
        ) {
            return;
        }
        let $variantsElement = jQuery(this).find('.ass-es-page-template-history-variants-ctn');
        let $toggleElement = jQuery(this).find('.ass-es-page-template-history-item-toggle');
        if ($toggleElement.hasClass('ass-es-active')) {
            $toggleElement.removeClass('ass-es-active');
            $variantsElement.addClass('ass-es-overflow-hidden');
            if ($variantsElement.is(':visible')) {
                $variantsElement.slideUp(200);
            }
        } else {
            $toggleElement.addClass('ass-es-active');
            $variantsElement.removeClass('ass-es-overflow-hidden');
            if (!$variantsElement.is(':visible')) {
                $variantsElement.slideDown(200);
            }
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-history-toggle', function () {
        let $element = jQuery(this);
        if ($element.hasClass('ass-es-active')) {
            closeHistory();
        } else {
            openHistory();
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-history-item-action-reload', function () {
        let $element = jQuery(this).closest('.ass-es-page-template-history-item');
        let requestId = $element.attr('data-request-id');
        let entry = proxyLiveData.history.find(x => x.request_id == requestId);
        notificationFillTemplateForm(requestId, entry.data, false);
    });
    jQuery(document).on('click', '.ass-es-page-template-history-item-action-delete', function () {
        let $element = jQuery(this).closest('.ass-es-page-template-history-item');
        let requestId = $element.attr('data-request-id');
        $element.slideUp(200, function () {
            $element.remove();
        });
        proxyLiveData.history = proxyLiveData.history.filter(x => x.request_id != requestId);
        jQuery.ajax({
            url: ajaxurl,
            type: "POST",
            cache: false,
            data: {
                'action': 'assi_delete_history',
                'request_id': requestId,
                'assi_security_nonce': assi_plugin_data.assi_security_nonce
            }
        });
    });
    jQuery(document).on('click', '.ass-es-page-template-history-variants-item-copy', function () {
        let $element = jQuery(this);
        let $iconElement = $element.find('i');
        let $textElement = $element.find('span');
        
        let textToCopy = $element.closest('.ass-es-page-template-history-variants-item').find('.ass-es-page-template-history-variants-item-text').html().trim();
        if (assi_plugin_data.editor_type == 'default') {
            textToCopy = convertHtmlToGutenbergBlocks(textToCopy);
        }
        const tempInput = jQuery('<textarea>');
        jQuery('body').append(tempInput);
        tempInput.val(textToCopy).select();
        document.execCommand('copy');
        tempInput.remove();

        
        $element.addClass('ass-es-active');
        $iconElement.removeClass('bi-copy').addClass('bi-check-lg');
        let text = $textElement.text();
        $textElement.text(__('Copied!', 'assistini'));
        setTimeout(function () {
            $element.removeClass('ass-es-active');
            $iconElement.removeClass('bi-check-lg').addClass('bi-copy');
            $textElement.text(text);
        }, 750);
    });
    jQuery(document).on('click', '.ass-es-page-template-history-variants-item-download', function () {
        let $element = jQuery(this);
        let type = $element.attr('data-type');
        let requestId = $element.closest('.ass-es-page-template-history-item').attr('data-request-id');
        let $buttonIcon = $element.find('i');
        let $buttonText = $element.find('span');
        if (type == 'image') {
            let $imageElement = $element.closest('.ass-es-page-template-history-variants-item').find('.ass-es-page-template-history-variants-item-img');
            if ($imageElement.length > 0) {
                let imageUrl = $imageElement.attr('src');
                let imageFilename = $imageElement.attr('data-filename');
                fetch(imageUrl).then(response => response.blob()).then(blob => {
                    const blobUrl = URL.createObjectURL(blob);
                    let link = document.createElement('a');
                    link.download = imageFilename;
                    link.href = blobUrl;
                    link.click();
                    link.remove();
                    URL.revokeObjectURL(blobUrl);
                }).catch(error => {return});
            }
        }
        if (type == 'audio') {
            let $audioElement = jQuery(this).closest('.ass-es-page-template-history-variants-item').find('.ass-es-page-template-history-variants-item-audio');
            if ($audioElement.length > 0) {
                let audioUrl = $audioElement.attr('data-src');
                let audioFilename = $audioElement.attr('data-filename');
                fetch(audioUrl).then(response => response.blob()).then(blob => {
                    const blobUrl = URL.createObjectURL(blob);
                    let link = document.createElement('a');
                    link.download = audioFilename;
                    link.href = blobUrl;
                    link.click();
                    link.remove();
                    URL.revokeObjectURL(blobUrl);
                }).catch(error => {return});
            }
        }
        $element.addClass('ass-es-active');
        $buttonIcon.removeClass('bi-download').addClass('bi-check-lg');
        let tempText = $buttonText.text();
        $buttonText.text(__('Downloaded!', 'assistini'));
        setTimeout(function () {
            $element.removeClass('ass-es-active');
            $buttonIcon.removeClass('bi-check-lg').addClass('bi-download');
            $buttonText.text(tempText);
        }, 750);
    });
    jQuery(document).on('click', '.ass-es-page-template-history-variants-item-library', async function () {
        let $element = jQuery(this);
        let type = $element.attr('data-type');
        let requestId = $element.closest('.ass-es-page-template-history-item').attr('data-request-id');
        let $buttonIcon = $element.find('i');
        let $buttonText = $element.find('span');
        if (type == 'image') {
            let $imageElement = $element.closest('.ass-es-page-template-history-variants-item').find('.ass-es-page-template-history-variants-item-img');
            if ($imageElement.length > 0) {
                let imageUrl = $imageElement.attr('src');
                let imageFilename = $imageElement.attr('data-filename');
                let imageTitle = $imageElement.attr('data-title');
                let imageExtension = $imageElement.attr('data-extension');

                $element.addClass('ass-es-loading');
                let tempText = $buttonText.text();
                $buttonText.text(__('Saving...', 'assistini'));
                let imageUploadResult = await uploadImageToLibrary(requestId, imageUrl, imageFilename, imageTitle, imageExtension);
                initNotifications();
                initHistory();
                if (imageUploadResult) {
                    $element.removeClass('ass-es-loading').addClass('ass-es-active');
                    $buttonIcon.removeClass('bi-download').addClass('bi-check-lg');
                    $buttonText.text(__('Saved!', 'assistini'));
                    setTimeout(function () {
                        $element.removeClass('ass-es-active');
                        $buttonIcon.removeClass('bi-check-lg').addClass('bi-download');
                        $buttonText.text(tempText);
                    }, 750);
                } else {
                    $element.removeClass('ass-es-loading').addClass('ass-es-failed');
                    $buttonIcon.removeClass('bi-download').addClass('bi-x-lg');
                    $buttonText.text(__('Failed!', 'assistini'));
                    setTimeout(function () {
                        $element.removeClass('ass-es-failed');
                        $buttonIcon.removeClass('bi-x-lg').addClass('bi-download');
                        $buttonText.text(tempText);
                    }, 750);
                }
            }
        }
        if (type == 'audio') {
            let $audioElement = $element.closest('.ass-es-page-template-history-variants-item').find('.ass-es-page-template-history-variants-item-audio');
            if ($audioElement.length > 0) {
                let audioUrl = $audioElement.attr('data-src');
                let audioFilename = $audioElement.attr('data-filename');
                let audioTitle = $audioElement.attr('data-title');
                let audioExtension = $audioElement.attr('data-extension');
    
                $element.addClass('ass-es-loading');
                let tempText = $buttonText.text();
                $buttonText.text(__('Saving...', 'assistini'));
                let audioUploadResult = await uploadAudioToLibrary(requestId, audioUrl, audioFilename, audioTitle, audioExtension);
                initNotifications();
                initHistory();
                if (audioUploadResult) {
                    $element.removeClass('ass-es-loading').addClass('ass-es-active');
                    $buttonIcon.removeClass('bi-download').addClass('bi-check-lg');
                    $buttonText.text(__('Saved!', 'assistini'));
                    setTimeout(function () {
                        $element.removeClass('ass-es-active');
                        $buttonIcon.removeClass('bi-check-lg').addClass('bi-download');
                        $buttonText.text(tempText);
                    }, 750);
                } else {
                    $element.removeClass('ass-es-loading').addClass('ass-es-failed');
                    $buttonIcon.removeClass('bi-download').addClass('bi-x-lg');
                    $buttonText.text(__('Failed!', 'assistini'));
                    setTimeout(function () {
                        $element.removeClass('ass-es-failed');
                        $buttonIcon.removeClass('bi-x-lg').addClass('bi-download');
                        $buttonText.text(tempText);
                    }, 750);
                }
            }
        }
    });
    jQuery(document).on('click', '.ass-es-page-template-submit-edit-btn', function () {
        let postContent = jQuery('#ass-es-page-template-content-check').is(':checked');
        let content = jQuery('.ass-es-page-template-form-input[data-id="content"]').val();
        let additionalContent = jQuery('.ass-es-page-template-form-input[data-id="additional_content"]').val();
        let artStyle = jQuery('.ass-es-page-template-form-input[data-id="art_style"]').val();
        let customStyleId = jQuery('#ass-es-page-template-style').val();
        let customStyle = jQuery('.ass-es-page-template-form-input[data-id="custom_style"]').val();
        let size = jQuery('.ass-es-page-template-form-input[data-id="size"]').val();
        let quality = jQuery('.ass-es-page-template-form-input[data-id="quality"]').val();
        let outputFormat = jQuery('.ass-es-page-template-form-input[data-id="output_format"]').val();
        let model = jQuery('.ass-es-page-template-form-input[data-id="model"]').val();

        let imageUrl = jQuery('.ass-es-page-template-image-result-item-image-tag').attr('src');
        let imageFilename = jQuery('.ass-es-page-template-image-result-item-image-tag').attr('data-filename');

        let $element = jQuery('.ass-es-template-list-item[data-id="26"][data-type="editor"][data-category="image"]');
        if ($element.length > 0) {
            let $templatePage = jQuery('.ass-es-page-template');
            if ($templatePage.attr('style') == 'transform: translateX(0%);') {
                jQuery('.ass-es-page-template-close-ctn').trigger('click');
                setTimeout(function () {
                    $element.trigger('click');
                }, 200);
            } else {
                $element.trigger('click');
            }
        }
        setTimeout(function () {
            jQuery('#ass-es-page-template-image').val(imageFilename).attr('data-url', imageUrl);
            jQuery('.ass-es-page-template-form-input[data-id="model"]').val(model).trigger('change');
            jQuery('#ass-es-page-template-content-check').prop('checked', postContent).trigger('change');
            jQuery('.ass-es-page-template-form-input[data-id="content"]').val(content);
            jQuery('.ass-es-page-template-form-input[data-id="additional_content"]').val(additionalContent);
            jQuery('.ass-es-page-template-form-input[data-id="art_style"]').val(artStyle);
            jQuery('#ass-es-page-template-style').val(customStyleId).trigger('change');
            jQuery('.ass-es-page-template-form-input[data-id="custom_style"]').val(customStyle);
            jQuery('.ass-es-page-template-form-input[data-id="size"]').val(size);
            jQuery('.ass-es-page-template-form-input[data-id="quality"]').val(quality);
            jQuery('.ass-es-page-template-form-input[data-id="output_format"]').val(outputFormat);
        }, 750);
    });
}
function initObservers() {
    const targets = [
        '.ass-es-page-template-speaker-list',
        '.ass-es-page-template-conversation-list',
        '.ass-es-page-template-history'
    ];
    targets.forEach(function (target) {
        let $targetElement = jQuery(target)[0];
        if ($targetElement != undefined) {
            let observer = new MutationObserver(observerCallback);
            observer.observe($targetElement, { childList: true });
        }
    });
}

function observerCallback(mutations, observer) {
    mutations.forEach(function (mutation) {
        let target = mutation.target;
        if (target.matches('.ass-es-page-template-speaker-list') && mutation.type == 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) {
            jQuery('#ass-es-page-template-conversation-speaker').prop('disabled', true);
            jQuery('#ass-es-page-template-conversation').prop('disabled', true);
            jQuery('.ass-es-page-template-conversation-add').prop('disabled', true);
            jQuery('.ass-es-page-template-speaker-controls').show();
            let $speakerListElements = jQuery('.ass-es-page-template-speaker-list-item:not(:disabled)');
            if ($speakerListElements.length == 1) {
                if (assi_plugin_data?.user_data?.plan_id < 2) {
                    jQuery('.ass-es-page-template-speaker-add').prop('disabled', true);
                    jQuery('.ass-es-page-template-speaker-badge').show();
                } else {
                    jQuery('.ass-es-page-template-speaker-add').prop('disabled', false);
                    jQuery('.ass-es-page-template-speaker-badge').hide();
                }
                jQuery('#ass-es-page-template-conversation-speaker').prop('disabled', false);
                jQuery('#ass-es-page-template-conversation').prop('disabled', false);
                jQuery('.ass-es-page-template-conversation-add').prop('disabled', false);
            } else if ($speakerListElements.length >= 2) {
                jQuery('.ass-es-page-template-speaker-add').prop('disabled', true);
                
                jQuery('#ass-es-page-template-conversation-speaker').prop('disabled', false);
                jQuery('#ass-es-page-template-conversation').prop('disabled', false);
                jQuery('.ass-es-page-template-conversation-add').prop('disabled', false);
                jQuery('.ass-es-page-template-speaker-controls').hide();
            } else {

                jQuery('.ass-es-page-template-speaker-add').prop('disabled', false);
                jQuery('.ass-es-page-template-speaker-badge').hide();
            }
        }
        if (target.matches('.ass-es-page-template-conversation-list') && mutation.type == 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) {
            let conversationCount = jQuery('.ass-es-page-template-conversation-list-item').length;
            if (conversationCount >= 100) {
                jQuery('.ass-es-page-template-conversation-add').prop('disabled', true);
            } else {
                jQuery('.ass-es-page-template-conversation-add').prop('disabled', false);
            }
        }
        if (target.matches('.ass-es-page-template-history') && mutation.type == 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) {
            let conversationCount = jQuery('.ass-es-page-template-history-item').length;
            if (conversationCount <= 0) {
                jQuery('.ass-es-page-template-history-ctn').hide();
            }
        }
    });
}

function getTemplates() {
    jQuery.ajax({
        url: ajaxurl,
        type: "POST",
        cache: false,
        data: {
            'action': 'assi_get_templates',
            'assi_security_nonce': assi_plugin_data.assi_security_nonce
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data.result != undefined && data.result == true) {
                if (data?.user_data != undefined) {
                    proxyLiveData.creditsOpen = data.user_data?.credits_open;
                    proxyLiveData.creditsTotal = data.user_data?.credits_total;
                    proxyLiveData.promoCreditsOpen = data.user_data?.promotion?.credits_open;
                    proxyLiveData.promoCreditsTotal = data.user_data?.promotion?.credits_total;
                }
                jQuery('.ass-es-template-list').html('');
                jQuery('.ass-es-template-list-loader').hide();
                if (data.template_data != undefined && typeof data.template_data == 'object' && data.template_data.length > 0) {
                    globalTemplates = data.template_data;
                    if (assi_plugin_data.editor_type == 'classic') {
                        waitForTinyMCE();
                    }
                    data.template_data.forEach(entry => {
                        if (entry.type != undefined && entry.disabled != undefined && entry.disabled == false && (entry.type == TYPE_USER || entry.type == TYPE_EDITOR)) {
                            if (entry.plan_version > assi_plugin_data.user_data.plan_id) {
                                jQuery('.ass-es-template-list').append(`
                                <div class="ass-es-template-list-item ass-flex-row ass-justify-between ass-gap-10 ass-es-template-disabled ${entry.id == 35 && entry.type == 'editor' ? 'ass-es-border-primary' : ''}" data-id="${entry.id}" data-type="${entry.type}" data-category="${entry.category}">
                                    <div class="ass-es-template-list-item-text-ctn ass-flex-column ass-gap-5">    
                                        <span class="ass-es-template-list-item-title">${entry.header}</span>
                                        <span class="ass-es-template-list-item-info">${entry.text}</span>
                                    </div>
                                    <div class="ass-flex ass-align-center">
                                        <span class="ass-primary-badge">${entry.plan_version_badge}</span>
                                    </div>
                                </div>
                            `);
                            } else {
                                jQuery('.ass-es-template-list').append(`
                                <div class="ass-es-template-list-item ass-flex-column ass-gap-5 ${entry.id == 35 && entry.type == 'editor' ? 'ass-es-border-primary' : ''}" data-id="${entry.id}" data-type="${entry.type}" data-category="${entry.category}">
                                    <div class="ass-flex ass-gap-5">
                                        <span class="ass-es-template-list-item-title">${entry.header}</span>
                                        ${entry.id == 35 && entry.type == 'editor' ? '<span class="ass-new-badge">' + __('New', 'assistini') + '</span>' : ''}
                                    </div>
                                    <span class="ass-es-template-list-item-info">${entry.text}</span>
                                </div>
                            `);
                            }
                        }
                    });
                    jQuery('.ass-es-template-list-item').addClass('ass-es-hidden');
                    jQuery('.ass-es-template-list-item[data-category="text"]').removeClass('ass-es-hidden');
                    window.dispatchEvent(new Event('assistiniRerender'));
                }
            } else {
                showNotice('error', (data.error_message != undefined ? data.error_message : ''));
            }
        },
        error: function () {
            showNotice('error');
        }
    });
}

function showTemplateResultLoader(numberOfResults = 0) {
    if (numberOfResults > 1) {
        jQuery('.ass-es-copy-btn[data-copy="all"]').fadeIn(150);
    } else {
        jQuery('.ass-es-copy-btn[data-copy="all"]').fadeOut(150);
    }
    jQuery('.ass-es-page-template-result-ctn').show();
    jQuery('.ass-es-page-template-result-item').hide();
    jQuery('.ass-es-template-result-loader').show();
    jQuery('.ass-es-page-template-result-item-text').html('').hide();
    jQuery('.ass-es-page-template-result-item').filter(function () {
        return parseInt(jQuery(this).attr('data-variant')) <= parseInt(numberOfResults);
    }).fadeIn(150);
}
function showTemplateImageResultLoader(numberOfResults = 0) {
    jQuery('.ass-es-page-template-result-ctn').show();
    jQuery('.ass-es-page-template-image-result-item').hide();
    jQuery('.ass-es-save-image-download-btn').hide();
    jQuery('.ass-es-save-image-to-library-btn').hide();
    jQuery('.ass-es-template-image-result-loader').show();
    jQuery('.ass-es-page-template-image-result-item-image-tag').remove();
    jQuery('.ass-es-image-alert').remove();
    jQuery('.ass-es-page-template-image-result-item').filter(function () {
        return parseInt(jQuery(this).attr('data-variant')) <= parseInt(numberOfResults);
    }).fadeIn(150);
}
function showTemplateAudioResultLoader(numberOfResults = 0) {
    jQuery('.ass-es-page-template-result-ctn').show();
    jQuery('.ass-es-page-template-audio-result-item').hide();
    jQuery('.ass-es-save-audio-download-btn').hide();
    jQuery('.ass-es-save-audio-to-library-btn').hide();
    jQuery('.ass-es-template-audio-result-loader').show();
    jQuery('.ass-es-page-template-audio-result-item-audio-tag').remove();
    jQuery('.ass-es-audio-alert').remove();
    jQuery('.ass-es-page-template-audio-result-item').filter(function () {
        return parseInt(jQuery(this).attr('data-variant')) <= parseInt(numberOfResults);
    }).fadeIn(150);
}

function startProgressCircle(seconds = 45, type = 'image') {
    jQuery('#ass-es-circle-progress-' + type).circleProgress({
        value: 0,
        size: 80,
        startAngle: -Math.PI / 2,
        lineCap: 'round',
        fill: {
            gradient: ['#1b1464']
        }
    });
    jQuery('.ass-es-circle-progress-' + type + '-text').html('0%');
    let progressArray = getRandomProgressArray(seconds);
    let counter = 0;
    let percent = 0;
    progressInterval = setInterval(() => {
        if (progressArray[counter] != undefined) {
            percent += progressArray[counter] / 100;
            if (percent >= 1) percent = 1;
            jQuery('#ass-es-circle-progress-' + type).circleProgress('value', percent);
            jQuery('.ass-es-circle-progress-' + type + '-text').html(Math.round(percent * 100) + '%');
            if (percent == 1) stopProgressCircle();
            counter++;
        } else {
            stopProgressCircle();
        }
    }, 1000);
}

function getRandomProgressArray(seconds = 45, maxPercent = 99) {
    let arr = [];

    for (let i = 0; i < (seconds - 1); i++) {
        arr.push(Math.random());
    }
    let sum = arr.reduce((a, b) => a + b, 0);
    arr = arr.map(x => x / sum * maxPercent);

    arr = arr.map(x => Math.round(x));
    let diff = maxPercent - arr.reduce((a, b) => a + b, 0);
    while (diff !== 0) {
        let index = Math.floor(Math.random() * 44);
        if (diff > 0) {
            arr[index]++;
            diff--;
        } else if (diff < 0 && arr[index] > 0) {
            arr[index]--;
            diff++;
        }
    }
    return arr;
}

function stopProgressCircle() {
    clearInterval(progressInterval);
    progressInterval = null;
}

function finishProgressCircle(type = 'image') {
    if (progressInterval != null) {
        stopProgressCircle();
    }
    jQuery('#ass-es-circle-progress-' + type).circleProgress('value', 1);
    jQuery('.ass-es-circle-progress-' + type + '-text').html('100%');
}

function showTemplateResult(content, animation = true) {
    content.forEach((element, index) => {
        injectTemplateResult(index + 1, element, animation);
    });
}
function showTemplateImageResult(content, requestId = '') {
    content.forEach((element, index) => {
        injectTemplateImageResult(index + 1, element, requestId);
    });
}
function showTemplateAudioResult(content, requestId = '') {
    content.forEach((element, index) => {
        injectTemplateAudioResult(index + 1, element, requestId);
    });
}

async function injectTemplateResult(variant, content, animation = true) {
    let $element = jQuery('.ass-es-page-template-result-item[data-variant="' + variant + '"]');
    if ($element.length > 0) {
        $element.find('.ass-es-template-result-loader').hide();
        let $elementContent = $element.find('.ass-es-page-template-result-item-text');

        $elementContent.show();
        if (animation) {
            let words = [];
            for (let i = 0; i < content.length; i += 5) {
                words.push(content.slice(i, i + 5));
            }
            let tempText = '';
            for (let i = 0; i < words.length; i++) {
                tempText += words[i];
                $elementContent.html(replaceNewLine(marked.parse(tempText.replace(/<br\s*\/?>/gi, '\n'))));
                await timeout(30);
            }
        }
        $elementContent.html(replaceNewLine(marked.parse(content.replace(/<br\s*\/?>/gi, '\n'))));
    }
}
async function injectTemplateImageResult(variant, content, requestId = '') {
    let $element = jQuery('.ass-es-page-template-image-result-item[data-variant="' + variant + '"]');
    if ($element.length > 0) {

        let imageExists = await checkImage(content.image);

        if (imageExists) {
            let img = document.createElement('img');
            img.src = content.image;
            img.classList.add('ass-es-page-template-image-result-item-image-tag');
            img.setAttribute('data-filename', content.filename);
            img.setAttribute('data-title', content.title);
            img.setAttribute('data-extension', content.extension);
            img.setAttribute('data-request-id', requestId);
            $element.find('.ass-es-template-image-result-loader').hide();
            $element.find('.ass-es-save-image-download-btn').show();
            $element.find('.ass-es-save-image-to-library-btn').show();
            $element.find('.ass-es-page-template-image-result-item-image').append(img);
            if (content.scale != undefined && content.scale == 'true') {
                $element.find('.ass-es-page-template-image-result-item-image').append(`
                    <div class="ass-es-image-alert ass-es-alert-info ass-flex ass-gap-10 ass-align-center" data-id="scale">
                        <i class="bi bi-info-circle ass-fs-16"></i>
                        <span class="ass-fs-12 ass-fw-600">${__('Your image was automatically resized for optimal performance.', 'assistini')}</span>    
                    </div>    
                `);
            }
            if (parseInt(jQuery('.ass-es-page-template').attr('data-template-id')) == 25) {
                if (assi_plugin_data?.user_data?.plan_id != undefined && assi_plugin_data.user_data.plan_id > 1) {
                    jQuery('.ass-es-page-template-submit-edit-btn').show();
                }
            } else {
                jQuery('.ass-es-page-template-submit-edit-btn').hide();
            }
        } else {
            $element.find('.ass-es-template-image-result-loader').hide();
            $element.find('.ass-es-page-template-image-result-item-image').append(`
                <div class="ass-es-image-alert ass-es-alert-info ass-flex ass-gap-10 ass-align-center" data-id="unavailable">
                    <i class="bi bi-info-circle ass-fs-16"></i>
                    <span class="ass-fs-12 ass-fw-600">${__('The image source is no longer available on the server. Please recreate the image.', 'assistini')}</span>    
                </div>    
            `);
        }
    }
}

function checkImage(url = '') {
    return new Promise((resolve, reject) => {
        let img = new Image();
        img.onload = () => {
            resolve(true);
        };
        img.onerror = () => {
            resolve(false);
        };
        img.src = url;
    });
}

async function injectTemplateAudioResult(variant, content, requestId = '') {
    let $element = jQuery('.ass-es-page-template-audio-result-item[data-variant="' + variant + '"]');
    if ($element.length > 0) {

        let audioExists = await checkAudio(content.audio);

        if (audioExists) {
            let audio = document.createElement('audio');
            audio.controls = true;
            audio.src = content.audio;
            audio.classList.add('ass-es-page-template-audio-result-item-audio-tag');
            audio.setAttribute('data-filename', content.filename);
            audio.setAttribute('data-title', content.title);
            audio.setAttribute('data-extension', content.extension);
            audio.setAttribute('data-request-id', requestId);
            $element.find('.ass-es-template-audio-result-loader').hide();
            $element.find('.ass-es-save-audio-download-btn').show();
            $element.find('.ass-es-save-audio-to-library-btn').show();
            $element.find('.ass-es-page-template-audio-result-item-audio').append(audio);
        } else {
            $element.find('.ass-es-template-audio-result-loader').hide();
            $element.find('.ass-es-page-template-audio-result-item-audio').append(`
                <div class="ass-es-audio-alert ass-es-alert-info ass-flex ass-gap-10 ass-align-center" data-id="unavailable">
                    <i class="bi bi-info-circle ass-fs-16"></i>
                    <span class="ass-fs-12 ass-fw-600">${__('The audio source is no longer available on the server. Please recreate the audio.', 'assistini')}</span>    
                </div>    
            `);
        }

    }
}

function checkAudio(url = '') {
    return new Promise((resolve, reject) => {
        let audio = new Audio();
        audio.oncanplaythrough = () => {
            resolve(true);
        };
        audio.onerror = () => {
            resolve(false);
        };
        audio.src = url;
    });
}

function displayCredits() {
    let creditsOpen = proxyLiveData.creditsOpen;
    let creditsTotal = proxyLiveData.creditsTotal;
    changeText('.ass-es-licence-credits-open', creditsOpen);
    changeText('.ass-es-licence-credits-total', creditsTotal);
    changeText('.ass-es-licence-pin-credits', creditsTotal);
    let planCreditsMaxWidth = 100;
    let promoCreditsWidth = 0;
    let promoCreditsOpen = proxyLiveData.promoCreditsOpen;
    let promoCreditsTotal = proxyLiveData.promoCreditsTotal;
    if (proxyLiveData.promoCreditsTotal > 0) {
        let promoCreditsMaxWidth = 0;
        changeText('.ass-es-licence-pin-credits', (creditsTotal - promoCreditsTotal));
        changeText('.ass-es-licence-pin-promo-credits', promoCreditsTotal);
        jQuery('.ass-es-licence-promo').show();
        planCreditsMaxWidth = ((creditsTotal - promoCreditsTotal) / creditsTotal) * 100;
        promoCreditsMaxWidth = 100 - planCreditsMaxWidth;

        promoCreditsWidth = (promoCreditsOpen / promoCreditsTotal) * (promoCreditsMaxWidth / 100) * 100;
        if (promoCreditsWidth < 0) {
            promoCreditsWidth = 0;
        }
        if (promoCreditsWidth > promoCreditsMaxWidth) {
            promoCreditsWidth = promoCreditsMaxWidth;
        }
    }
    let planCreditsWidth = ((creditsOpen - promoCreditsOpen) / (creditsTotal - promoCreditsTotal)) * (planCreditsMaxWidth / 100) * 100;
    if (planCreditsWidth < 0) {
        planCreditsWidth = 0;
    }
    if (planCreditsWidth > planCreditsMaxWidth) {
        planCreditsWidth = planCreditsMaxWidth;
    }
    jQuery('.ass-licence-progress-bar').css('width', planCreditsWidth + '%');
    jQuery('.ass-licence-progress-bar-promo').css('width', promoCreditsWidth + '%');
}

function changeText(selector, newText) {
    const $element = jQuery(selector);
    if ($element.text() === newText) {
        return;
    }
    $element.fadeOut(150, () => {
        $element.text(newText).fadeIn(150);
    });
}

function openUpgradeModal() {
    let dialog = document.getElementById('ass-es-modal-upgrade');
    if (assi_plugin_data?.user_data?.plan_id > 1) {
        jQuery('.ass-es-modal-upgrade-content').hide();
        jQuery('.ass-es-modal-upgrade-content[data-type="smart"]').show();
    } else {
        jQuery('.ass-es-modal-upgrade-content').hide();
        jQuery('.ass-es-modal-upgrade-content[data-type="free"]').show();
    }
    dialog.showModal();
    jQuery('#ass-es-modal-upgrade').hide();
    jQuery('#ass-es-modal-upgrade').fadeIn(150);
}
function openConsentModal(type = '') {
    if (type == 'admin') {
        let dialog = document.getElementById('ass-es-modal-consent');
        dialog.showModal();
        jQuery('#ass-es-modal-consent').hide();
        jQuery('#ass-es-modal-consent').fadeIn(150);
    } else if (type == 'rejected') {
        let dialog = document.getElementById('ass-es-modal-consent-rejected');
        dialog.showModal();
        jQuery('#ass-es-modal-consent-rejected').hide();
        jQuery('#ass-es-modal-consent-rejected').fadeIn(150);
    } else {
        let dialog = document.getElementById('ass-es-modal-consent-no-admin');
        dialog.showModal();
        jQuery('#ass-es-modal-consent-no-admin').hide();
        jQuery('#ass-es-modal-consent-no-admin').fadeIn(150);
    }
}

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function showNotice(type = 'error', message = '') {
    if (message == undefined || message == '') {
        type = 'error';
        message = __('Something went wrong with the AI server request - please retry.', 'assistini');
    }
    if (assi_plugin_data.editor_type == 'default') {
        let id = Date.now();
        wp.data.dispatch('core/notices').createNotice(type, 'Assistini: ' + message, {
            isDismissible: true,
            id: id
        });
        setTimeout(() => {
            wp.data.dispatch('core/notices').removeNotice(id);
        }, 10000);
    } else if (assi_plugin_data.editor_type == 'classic') {
        let $noticeElm = jQuery('.ass-notice-editor-classic');
        $noticeElm.removeClass('notice-success').removeClass('notice-warning').removeClass('notice-error').addClass('notice-' + type);
        jQuery('.ass-notice-editor-classic-message').text('Assistini: ' + message);
        $noticeElm.show();
        setTimeout(() => {
            $noticeElm.hide();
        }, 10000);
}
}

function checkOpenAiStatus() {
    jQuery.ajax({
        url: ajaxurl,
        type: "POST",
        cache: false,
        data: {
            'action': 'assi_open_ai_status',
            'assi_security_nonce': assi_plugin_data.assi_security_nonce
        },
        beforeSend: function () {
            jQuery('.ass-es-open-ai-status-body').hide();
            jQuery('.ass-es-open-ai-status-body[data-status="-1"]').show();
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data.result != undefined && data.result == true && data.status != undefined && data.status > 0) {
                jQuery('.ass-es-open-ai-status-body').hide();
                if (data.status > 1) {
                    jQuery('.ass-es-open-ai-status').show();
                    jQuery('.ass-es-open-ai-status-body[data-status="' + data.status + '"]').show();
                }
            } else {
                jQuery('.ass-es-open-ai-status-body').hide();
                jQuery('.ass-es-open-ai-status-body[data-status="0"]').show();
            }
        },
        error: function () {
            jQuery('.ass-es-open-ai-status-body').hide();
            jQuery('.ass-es-open-ai-status-body[data-status="0"]').show();
        }
    });
}

function calculatePageTemplateHeight() {
    let headlineTopOffset = 0;
    if (assi_plugin_data.editor_type == 'classic') {
        let headlineHeight = jQuery('.ass-es-headline').height();
        let sidebarHeight = jQuery('.ass-es').height();
        jQuery('.ass-es-page-template').css('top', headlineTopOffset + headlineHeight + 'px');    
    }
}

function editorGenerateImage(templateId, entry, isSystem, content = '') {
    let imageSize = jQuery('#ass-es-page-template-size').val();
    let imageQuality = jQuery('#ass-es-page-template-quality').val();
    let imageFormat = jQuery('#ass-es-page-template-format').val();
    let model = jQuery('#ass-es-page-template-model').val();
    let artStyle = jQuery('#ass-es-page-template-art-style').val();
    let customStyle = jQuery('#ass-es-page-template-custom-style').val();

    let returnError = false;
    if (content == undefined || content == '') {
        jQuery('#ass-es-page-template-content').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-content').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (imageSize == undefined || imageSize == '') {
        jQuery('#ass-es-page-template-size').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-size').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (imageQuality == undefined || imageQuality == '') {
        jQuery('#ass-es-page-template-quality').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-quality').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (imageFormat == undefined || imageFormat == '') {
        jQuery('#ass-es-page-template-format').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-format').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }

    let imageUploadId = 0;
    let imageUploadUrl = '';
    if (entry?.option_fields != undefined && entry.option_fields.includes('image')) {
        imageUploadId = parseInt(jQuery('#ass-es-page-template-image').attr('data-id'));
        imageUploadUrl = jQuery('#ass-es-page-template-image').attr('data-url');
        if ((imageUploadId == undefined || imageUploadId <= 0 || isNaN(imageUploadId)) && (imageUploadUrl == undefined || imageUploadUrl == '')) {
            jQuery('#ass-es-page-template-image').addClass('ass-es-red-border');
            setTimeout(function () {
                jQuery('#ass-es-page-template-image').removeClass('ass-es-red-border');
            }, 2000);
            returnError = true;
        }
    }
    if (returnError) {
        return;
    }
    if (assi_plugin_data?.custom_ai_connection?.active == undefined || assi_plugin_data.custom_ai_connection.active == 0) {
        if (proxyLiveData.creditsOpen <= 0) {
            openUpgradeModal();
            return;
        }
    }
    let requestId = generateRequestId();
    let data = {
        action: 'assi_editor_send_prompt_image',
        template_id: templateId,
        content: content,
        additional_content: jQuery('#ass-es-page-template-content-additional').val(),
        image_size: imageSize,
        image_quality: imageQuality,
        image_format: imageFormat,
        assi_security_nonce: assi_plugin_data.assi_security_nonce,
        is_system: isSystem,
        image_id: imageUploadId,
        image_url: imageUploadUrl,
        model: model,
        art_style: artStyle,
        custom_style: customStyle,
        request_id: requestId
    };
    jQuery.ajax({
        url: ajaxurl,
        type: 'POST',
        data: data,
        beforeSend: function () {
            showTemplateImageResultLoader(jQuery('#ass-es-page-template-number').val());
            let seconds = 45;
            let entry = globalTemplates.find(x => x.id == templateId && x.type == 'editor');
            if (entry != undefined && entry?.option_models != undefined && entry?.option_models[model] != undefined && entry?.option_models[model].time != undefined && entry.option_models[model].time > 0) {
                seconds = entry.option_models[model].time;
            }
            startProgressCircle(seconds, 'image');
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data != undefined && data?.result != undefined && data?.result == true && data?.content != undefined) {
                finishProgressCircle('image');
                setTimeout(() => {
                    showTemplateImageResult(data.content, requestId);
                }, 1500);
                if (data?.user_data?.credits_open != undefined) {
                    proxyLiveData.creditsOpen = data.user_data.credits_open;
                }
                initHistory();
            } else {
                jQuery('.ass-es-page-template-image-result-item').hide();
                stopProgressCircle();
                if (data.error == 'client_timeout') {
                    hideResultContainer();
                    showTimeoutNotice();
                    startNotificationHeartbeat();
                } else {
                    hideResultContainer();
                    showNotice('error', (data?.error_message != undefined ? data.error_message : ''));
                }
            }
        },
        error: function (xhr, status, error) {
            if (xhr.status == 504) {
                jQuery.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'assi_create_notification',
                        type: 'editor',
                        category: 'image',
                        assi_security_nonce: assi_plugin_data.assi_security_nonce,
                        request_data: data
                    },
                    complete: function () {
                        startNotificationHeartbeat();
                    }
                });
                stopProgressCircle();
                hideResultContainer();
                showTimeoutNotice();
            } else {
                jQuery('.ass-es-page-template-image-result-item').hide();
                showNotice('error');
                stopProgressCircle();
            }
        }
    });
}

function getWpEditorContent() {
    if (assi_plugin_data.editor_type == 'classic') {
        if (typeof tinymce !== 'undefined' && tinymce.activeEditor && !tinymce.activeEditor.isHidden()) {
            return (tinymce.get('content').getContent()).replace(/<!--.*?-->/gs, '');
        } else {
            return jQuery('#content').val().replace(/<!--.*?-->/gs, '');
        }
    } else {
        return (wp.data.select('core/editor').getEditedPostContent()).replace(/<!--.*?-->/gs, '');
    }
}

function startNotificationHeartbeat() {
    if (typeof wp.heartbeat !== "undefined" && wp.hasOwnProperty('heartbeat')) {
        if (!activeHeartbeats.includes('ass_editor_notifications')) {
            activeHeartbeats.push('ass_editor_notifications');
            originalHeartbeatInterval = wp.heartbeat.interval();
            wp.heartbeat.interval(assHeartbeatInterval);
            wp.heartbeat.connectNow();
        }
    }
}
function stopNotificationHeartbeat() {
    if (typeof wp.heartbeat !== "undefined" && wp.hasOwnProperty('heartbeat')) {
        if (activeHeartbeats.includes('ass_editor_notifications')) {
            activeHeartbeats.splice(activeHeartbeats.indexOf('ass_editor_notifications'), 1);
        }
        wp.heartbeat.interval(originalHeartbeatInterval);
    }
}

function initNotifications() {
    jQuery.ajax({
        url: ajaxurl,
        type: "POST",
        cache: false,
        data: {
            action: 'assi_get_editor_notifications',
            assi_security_nonce: assi_plugin_data.assi_security_nonce
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data.result != undefined && data.result == true && data.notifications != undefined && data.notifications.length > 0) {
                jQuery('.ass-es-notification-list').html('');
                proxyLiveData.notifications = data.notifications;
                data.notifications.forEach((notification) => {
                    let icon = '';
                    let wording = '';
                    if (notification.category == 'audio') {
                        icon = 'bi-music-note-list';
                        wording = __('Your generated audio transcript is now ready', 'assistini');
                    } else if (notification.category == 'image') {
                        icon = 'bi-card-image';
                        wording = __('Your generated image is now ready', 'assistini');
                    } else {
                        icon = 'bi-card-text';
                        wording = __('Your generated text is now ready', 'assistini');
                    }
                    jQuery('.ass-es-notification-list').append(`
                        <li class="ass-es-notification-list-item ass-flex ass-align-center ass-gap-10" data-id="${notification.notification_id}">
                            <i class="ass-es-notification-list-header-icon bi ${icon} ass-fs-22 ass-es-gradient-primary"></i>
                            <div class="ass-flex-column">
                                <span>${wording}</span>
                                <span class="ass-fs-12 ass-text-gray">${notification.create_date}</span>
                            </div>
                            <i class="ass-es-notification-list-delete-icon bi bi-x-lg"></i>
                        </li>
                    `);
                });
            }
        },
        error: function () {
            showNotice('error');
        }
    });
}
function initHistory() {
    if (assi_plugin_data?.user_data?.plan_id > 1) {
        jQuery.ajax({
            url: ajaxurl,
            type: "POST",
            cache: false,
            data: {
                action: 'assi_get_editor_history',
                assi_security_nonce: assi_plugin_data.assi_security_nonce
            },
            success: function (data) {
                data = JSON.parse(data);
                if (data.result != undefined && data.result == true && data.history != undefined && data.history.length > 0) {
                    proxyLiveData.history = data.history;
                }
            },
            error: function () {
                showNotice('error');
            }
        });
    }
}

function notificationFillTemplateForm(requestId = '', data = {}, showResponse = true) {
    if (data.request_data != undefined) {
        let requestData = data.request_data;
        let category = requestData.category;
        setTimeout(() => {
            for (const [key, value] of Object.entries(requestData)) {
                if (key == 'content' && typeof value == 'object') {
                    jQuery('.ass-es-page-template-conversation-list').html('');
                    jQuery('#ass-es-page-template-custom-content-check').prop('checked', true).trigger('change');
                    let speakerIndexing = [];
                    for (const [entryKey, entryValue] of Object.entries(value)) {
                        let name = entryValue?.name;
                        let text = entryValue?.text;
                        if (!speakerIndexing.includes(name)) {
                            speakerIndexing.push(name);
                        }
                        addConversationListItem(name, text, (speakerIndexing.indexOf(name) + 1).toString());
                    }
                } else {
                    let $formElement = jQuery('.ass-es-page-template-form-input[data-id="' + key + '"]');
                    if (key == 'user_input') {
                        $formElement = jQuery('.ass-es-page-template-form-input[data-id="content"]');
                    }
                    if ($formElement.length > 0) {
                        $formElement.val(value);
                    }
                    if (key == 'speakers' && key.length > 0) {
                        jQuery('.ass-es-page-template-speaker-list').html('');
                        for (let i = 0; i < value.length; i++) {
                            let name = value[i].name;
                            let voice = value[i].voice;
                            addSpeakerListItem(name, voice);
                        }
                        updateConversationSpeakerList();
                    }
                }
            }
            if (showResponse) {
                if (category == 'image') {
                    showTemplateImageResultLoader(1);
                    showTemplateImageResult(data.ai_response.content, requestId);
                } else if (category == 'audio') {
                    showTemplateAudioResultLoader(1);
                    showTemplateAudioResult(data.ai_response.content, requestId);
                } else {
                    showTemplateResultLoader(data?.request_data?.number_of_results != undefined ? data.request_data.number_of_results : 1);
                    showTemplateResult(data.ai_response.content, false);
                }
            }
        }, 250);
    }
}
function updateConversationSpeakerList() {
    let speakerList = jQuery('.ass-es-page-template-speaker-list-item');
    if (speakerList.length > 0) {
        jQuery('#ass-es-page-template-conversation-speaker').html('');
        let speakerHtml = '';
        let counter = 1;
        for (let i = 0; i < speakerList.length; i++) {
            let name = speakerList.eq(i).attr('data-name');
            speakerHtml += `<option value="${name}" data-id="${counter}">${name}</option>`;
            counter++;
        }
        jQuery('#ass-es-page-template-conversation-speaker').html(speakerHtml);
    } else {
        jQuery('#ass-es-page-template-conversation-speaker').html('<option value="" disabled selected>' + __('Add Speaker to create a Conversation', 'assistini') + '...</option>');
    }
}

function editorGenerateAudio(templateId, entry, isSystem, content = '') {
    let model = jQuery('#ass-es-page-template-model').val();
    let outputFormat = jQuery('#ass-es-page-template-format').val();
    let promptLanguage = jQuery('#ass-es-page-template-language').val();
    let pointOfView = jQuery('#ass-es-page-template-pov').val();
    let tone = jQuery('#ass-es-page-template-tone').val();

    let returnError = false;
    if (outputFormat == undefined || outputFormat == '') {
        jQuery('#ass-es-page-template-format').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-format').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (promptLanguage == undefined || promptLanguage == '') {
        jQuery('#ass-es-page-template-language').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-language').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (pointOfView == undefined || pointOfView == '') {
        jQuery('#ass-es-page-template-pov').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-pov').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (tone == undefined || tone == '') {
        jQuery('#ass-es-page-template-tone').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-tone').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;

    }
    let isConversation = jQuery('#ass-es-page-template-custom-content-check').is(':checked');
    if (isConversation == true) {
        let tempContent = [];
        let $elements = jQuery('.ass-es-page-template-conversation-list-item');
        for (let i = 0; i < $elements.length; i++) {
            let speaker = $elements.eq(i).attr('data-speaker');
            let text = $elements.eq(i).attr('data-text');
            tempContent.push({name: speaker, text: text});
        }
        content = tempContent;
    }
    if (isConversation == true) {
        if (content == undefined || content.length == 0) {
            jQuery('#ass-es-page-template-conversation').addClass('ass-es-red-border');
            setTimeout(function () {
                jQuery('#ass-es-page-template-conversation').removeClass('ass-es-red-border');
            }, 2000);
            returnError = true;
        }
    } else {
        if (content == undefined || content == '') {
            jQuery('#ass-es-page-template-content').addClass('ass-es-red-border');
            setTimeout(function () {
                jQuery('#ass-es-page-template-content').removeClass('ass-es-red-border');
            }, 2000);
            returnError = true;
        }
    }
    let speakers = [];
    let $speakerElements = jQuery('.ass-es-page-template-speaker-list-item');
    for (let i = 0; i < $speakerElements.length; i++) {
        let name = $speakerElements.eq(i).attr('data-name');
        let voice = $speakerElements.eq(i).attr('data-voice');
        speakers.push({name: name, voice: voice});
    }
    if (speakers.length == 0) {
        jQuery('#ass-es-page-template-speaker').addClass('ass-es-red-border');
        setTimeout(function () {
            jQuery('#ass-es-page-template-speaker').removeClass('ass-es-red-border');
        }, 2000);
        returnError = true;
    }
    if (returnError == true) {
        return;
    }
    if (assi_plugin_data?.custom_ai_connection?.active == undefined || assi_plugin_data.custom_ai_connection.active == 0) {
        if (proxyLiveData.creditsOpen <= 0) {
            openUpgradeModal();
            return;
        }
    }
    let requestId = generateRequestId();
    let data = {
        action: 'assi_editor_send_prompt_audio',
        template_id: templateId,
        content: content,
        additional_content: jQuery('.ass-es-page-template-form-input[data-id="additional_content"]').val(),
        output_format: outputFormat,
        prompt_language: promptLanguage,
        point_of_view: pointOfView,
        tone: tone,
        speakers: speakers,
        conversation: isConversation,
        assi_security_nonce: assi_plugin_data.assi_security_nonce,
        is_system: isSystem,
        model: model,
        request_id: requestId
    };
    jQuery.ajax({
        url: ajaxurl,
        type: 'POST',
        data: data,
        beforeSend: function () {
            showTemplateAudioResultLoader(jQuery('#ass-es-page-template-number').val());
            let seconds = 45;
            let entry = globalTemplates.find(x => x.id == templateId && x.type == 'editor');
            if (entry != undefined && entry?.option_models != undefined && entry?.option_models[model] != undefined && entry?.option_models[model].time != undefined && entry.option_models[model].time > 0) {
                seconds = entry.option_models[model].time;
            }
            startProgressCircle(seconds, 'audio');
        },
        success: function (data) {
            data = JSON.parse(data);
            if (data != undefined && data?.result != undefined && data?.result == true && data?.content != undefined) {
                finishProgressCircle('audio');
                setTimeout(() => {
                    showTemplateAudioResult(data.content, requestId);
                }, 1500);
                if (data?.user_data?.credits_open != undefined) {
                    proxyLiveData.creditsOpen = data.user_data.credits_open;
                }
                initHistory();
            } else {
                jQuery('.ass-es-page-template-audio-result-item').hide();
                stopProgressCircle();
                if (data.error == 'client_timeout') {
                    hideResultContainer();
                    showTimeoutNotice();
                    startNotificationHeartbeat();
                } else {
                    hideResultContainer();
                    showNotice('error', (data?.error_message != undefined ? data.error_message : ''));
                }
            }
        },
        error: function (xhr, status, error) {
            if (xhr.status == 504) {
                jQuery.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'assi_create_notification',
                        type: 'editor',
                        category: 'audio',
                        assi_security_nonce: assi_plugin_data.assi_security_nonce,
                        request_data: data
                    },
                    complete: function () {
                        startNotificationHeartbeat();
                    }
                });
                hideResultContainer();
                showTimeoutNotice();
                stopProgressCircle();
            } else {
                jQuery('.ass-es-page-template-audio-result-item').hide();
                showNotice('error');
                stopProgressCircle();
            }
        }
    });
}
function addConversationListItem(speaker = '', text = '', speakerId = '') {
    jQuery('.ass-es-page-template-conversation-list').append(`
        <li class="ass-es-page-template-conversation-list-item" data-speaker="${speaker}" data-text="${text}">
            <div class="ass-flex ass-justify-between ass-align-center ass-es-page-template-conversation-speaker-${speakerId}">
                <div class="ass-flex ass-align-center">
                    <i class="ass-es-page-template-conversation-list-item-drag ass-fs-18 bi bi-three-dots-vertical"></i>
                    <div class="ass-flex-column">
                        <span class="ass-fw-600">${speaker}</span>
                        <span>${text}</span>
                    </div>
                </div>
                <div class="ass-flex ass-align-center ass-gap-5">
                    <i class="ass-es-page-template-conversation-list-item-delete ass-fs-16 bi bi-trash"></i>
                </div>
            </div>    
        </li>
    `);
}
function addSpeakerListItem(name = '', speaker = '') {
    jQuery('.ass-es-page-template-speaker-list').append(`
        <li class="ass-es-page-template-speaker-list-item ass-flex ass-justify-between ass-align-center" data-name="${name}" data-voice="${speaker}">
            <div class="ass-flex ass-align-center ass-justify-between ass-w-100">
                <div class="ass-flex-column">
                    <span class="ass-fw-600">${name}</span>
                    <span>${__('Voice', 'assistini')}: ${speaker}</span>
                </div>
                <i class="ass-es-page-template-speaker-list-item-delete ass-fs-16 bi bi-trash"></i>
            </div>
        </li>
    `);
}
function hideResultContainer() {
    jQuery('.ass-es-page-template-result-item').hide();
    jQuery('.ass-es-page-template-image-result-item').hide();
    jQuery('.ass-es-page-template-audio-result-item').hide();
    jQuery('.ass-es-page-template-timeout-result-item').hide();
    jQuery('.ass-es-page-template-result-ctn').hide();
}
function showTimeoutNotice() {
    jQuery('.ass-es-page-template-result-ctn').show();
    jQuery('.ass-es-page-template-timeout-result-item').show();
}
function generateRequestId() {
    const randomBytes = crypto.getRandomValues(new Uint8Array(5));
    const hex = [...randomBytes].map(b => b.toString(16).padStart(2, '0')).join('');
    const timestamp = Math.floor(Date.now() / 1000);
    return `rq_${hex}${timestamp}`;
}
async function displayHistory(templateId = 0, type = '') {
    if (assi_plugin_data.user_data.plan_id > 1) {
        closeHistory();
        let $element = jQuery('.ass-es-page-template-history');
        $element.html('');
        if (proxyLiveData.history != undefined && proxyLiveData.history.length > 0) {
            let isSystem = (type == TYPE_USER ? 0 : 1);
            let entrys = proxyLiveData.history.filter(x => x.template_id == templateId && x.is_system == isSystem);
            if (entrys.length > 0) {
                let count = 1;
                for (let entry of entrys) {
                    let variantsHtml = await getHistoryVariantsHtml(entry);
                    let showDate = getRelativeTime(entry?.timestamp);
                    if (!showDate) {
                        showDate = entry?.create_date;
                    }
                    $element.append(`
                        <div class="ass-es-page-template-history-item ass-flex-column" data-request-id="${entry?.request_id}">
                            <div class="ass-flex ass-gap-10">
                                <div>
                                    <div class="ass-es-page-template-history-item-toggle">
                                        <i class="ass-fs-12 bi bi-caret-down-fill"></i>
                                    </div>
                                </div>
                                <div class="ass-flex-column ass-gap-5 ass-w-100">
                                    <div class="ass-flex ass-align-center ass-justify-between">
                                        <div class="ass-flex ass-gap-5 ass-align-center ass-fs-12 ass-date-color">
                                            <i class="bi bi-calendar"></i>
                                            <span>${showDate}</span>
                                        </div>
                                        <div class="ass-flex">
                                            <span class="ass-fs-12 ass-es-page-template-history-item-variants-badge">${entry?.data?.result_data?.length} ${entry?.data?.result_data?.length > 1 ? __('Variants', 'assistini') : __('Variant', 'assistini')}</span>
                                        </div>
                                    </div>  
                                    <div class="ass-flex ass-gap-10">
                                        <button class="ass-es-page-template-history-item-action-reload" type="button">
                                            <div class="ass-flex ass-align-center ass-gap-5">
                                                <i class="bi bi-arrow-counterclockwise ass-flex"></i>
                                                <span>${__('Reload used Prompt', 'assistini')}</span>                                        
                                            </div>
                                        </button>
                                        <button class="ass-es-page-template-history-item-action-delete" type="button">
                                            <div class="ass-flex ass-align-center ass-gap-5">
                                                <i class="bi bi-trash ass-flex"></i>
                                                <span>${__('Delete', 'assistini')}</span>                                        
                                            </div>
                                        </button>
                                    </div>
                                </div>
                            </div>
                            <div class="ass-es-page-template-history-variants-ctn ass-es-overflow-hidden" style="display:none;">
                                <div class="ass-flex-column ass-gap-10 ass-mt-20 ass-mb-10">
                                    ${variantsHtml}
                                </div>
                            </div>
                        </div>
                    `);
                    if (count == 1) {
                        jQuery('.ass-es-page-template-history-item-toggle').trigger('click');
                    }
                    count++;
                }
                jQuery('.ass-es-page-template-history-ctn').show();
                return;
            }
        }
        jQuery('.ass-es-page-template-history-ctn').hide();
    } else {
        jQuery('.ass-es-page-template-history-ctn').hide();
        jQuery('.ass-es-page-template-history-smart-ctn').show();
    }
}
function getRelativeTime(timestamp) {
    const now = Date.now();
    const ts = timestamp * 1000;
    const diffMs = now - ts;

    const oneHourMs = 60 * 60 * 1000;
    const threeHoursMs = 7 * oneHourMs;
    const oneMinuteMs = 60 * 1000;

    if (diffMs < oneHourMs) {
        const minutes = Math.floor(diffMs / oneMinuteMs);
        if (minutes <= 1) {
            return sprintf(__('%d minute ago', 'assistini'), 1);
        } else {
            return sprintf(__('%d minutes ago', 'assistini'), minutes);
        }
    } else if (diffMs < threeHoursMs) {
        const hours = Math.floor(diffMs / oneHourMs);
        if (hours == 1) {
            return sprintf(__('%d hour ago', 'assistini'), hours);
        } else {
            return sprintf(__('%d hours ago', 'assistini'), hours);
        }
    }
    return false;
}
async function getHistoryVariantsHtml(entry) {
    let variantsHtml = '';
    if (entry?.data?.result_data != undefined && entry.data.result_data.length > 0) {
        let count = 1;
        if (entry?.category != undefined && entry.category == 'text') {
            entry.data.result_data.forEach((variant) => {
                variantsHtml += `
                    <div class="ass-es-page-template-history-variants-item">
                        <span class="ass-es-page-template-history-variants-item-number ass-flex ass-align-center ass-justify-center ass-fs-10">${count}</span>
                        <div class="ass-flex-column ass-gap-5">
                            <span class="ass-es-page-template-history-variants-item-text">${replaceNewLine(marked.parse(variant.replace(/<br\s*\/?>/gi, '\n')))}</span>
                            <div class="ass-flex ass-justify-end">
                                <button class="ass-es-page-template-history-variants-item-copy ass-fs-12" type="button">
                                    <div class="ass-flex ass-align-center ass-gap-5">
                                        <i class="bi bi-copy ass-flex"></i>
                                        <span>${__('Copy', 'assistini')}</span>
                                    </div>
                                </button>
                            </div>
                        </div>
                    </div>
                `;
                count++;
            });
        }
        if (entry?.category != undefined && entry.category == 'image') {
            for (let variant of entry.data.result_data) {
                let imageExists = await checkImage(variant?.image);
                if (imageExists) {
                    variantsHtml += `
                        <div class="ass-es-page-template-history-variants-item">
                            <span class="ass-es-page-template-history-variants-item-number ass-flex ass-align-center ass-justify-center ass-fs-10">${count}</span>
                            <div class="ass-flex-column ass-gap-5">
                                <img src="${variant?.image}" data-filename="${variant?.filename}" data-title="${variant?.title}" data-extension="${variant?.extension}" alt="" class="ass-es-page-template-history-variants-item-img" />
                                ${variant?.scale != undefined && variant.scale == 'true' ? `
                                    <div class="ass-es-alert-info ass-flex ass-gap-10 ass-align-center">
                                        <i class="bi bi-info-circle ass-fs-16"></i>
                                        <span class="ass-fs-12 ass-fw-600">${__('Your image was automatically resized for optimal performance.', 'assistini')}</span>    
                                    </div>      
                                ` : ''}
                                <div class="ass-flex ass-justify-end ass-gap-5">
                                    <button class="ass-es-page-template-history-variants-item-download ass-fs-12" type="button" data-type="image">
                                        <div class="ass-flex ass-align-center ass-gap-5">
                                            <i class="bi bi-download ass-flex"></i>
                                            <span>${__('Download', 'assistini')}</span>
                                        </div>
                                    </button>
                                    <button class="ass-es-page-template-history-variants-item-library ass-fs-12" type="button" data-type="image">
                                        <div class="ass-flex ass-align-center ass-gap-5">
                                            <i class="bi bi-save ass-flex"></i>
                                            <span>${__('Save to Library', 'assistini')}</span>
                                        </div>
                                    </button>
                                </div>
                            </div>
                        </div>
                    `;
                } else {
                    variantsHtml += `
                        <div class="ass-es-page-template-history-variants-item">
                            <span class="ass-es-page-template-history-variants-item-number ass-flex ass-align-center ass-justify-center ass-fs-10">${count}</span>
                            <div class="ass-flex-column ass-gap-5">
                                <div class="ass-es-alert-info ass-flex ass-gap-10 ass-align-center">
                                    <i class="bi bi-info-circle ass-fs-16"></i>
                                    <span class="ass-fs-12 ass-fw-600">${__('The image source is no longer available on the server. Please recreate the image.', 'assistini')}</span>    
                                </div>
                            </div>
                        </div>
                    `;
                }
                count++;
            }
        }
        if (entry?.category != undefined && entry.category == 'audio') {
            for (let variant of entry.data.result_data) {
                let audioExists = await checkAudio(variant?.audio);
                if (audioExists) {
                    variantsHtml += `
                        <div class="ass-es-page-template-history-variants-item">
                            <span class="ass-es-page-template-history-variants-item-number ass-flex ass-align-center ass-justify-center ass-fs-10">${count}</span>
                            <div class="ass-flex-column ass-gap-5">
                                <audio controls class="ass-es-page-template-history-variants-item-audio" data-src="${variant?.audio}" data-filename="${variant?.filename}" data-title="${variant?.title}" data-extension="${variant?.extension}">
                                    <source src="${variant?.audio}">
                                </audio>
                                <div class="ass-flex ass-justify-end ass-gap-5">
                                    <button class="ass-es-page-template-history-variants-item-download ass-fs-12" type="button" data-type="audio">
                                        <div class="ass-flex ass-align-center ass-gap-5">
                                            <i class="bi bi-download ass-flex"></i>
                                            <span>${__('Download', 'assistini')}</span>
                                        </div>
                                    </button>
                                    <button class="ass-es-page-template-history-variants-item-library ass-fs-12" type="button" data-type="audio">
                                        <div class="ass-flex ass-align-center ass-gap-5">
                                            <i class="bi bi-save ass-flex"></i>
                                            <span>${__('Save to Library', 'assistini')}</span>
                                        </div>
                                    </button>
                                </div>
                            </div>
                        </div>
                    `;
                } else {
                    variantsHtml += `
                        <div class="ass-es-page-template-history-variants-item">
                            <span class="ass-es-page-template-history-variants-item-number ass-flex ass-align-center ass-justify-center ass-fs-10">${count}</span>
                            <div class="ass-flex-column ass-gap-5">
                                <div class="ass-es-alert-info ass-flex ass-gap-10 ass-align-center" data-id="unavailable">
                                    <i class="bi bi-info-circle ass-fs-16"></i>
                                    <span class="ass-fs-12 ass-fw-600">${__('The audio source is no longer available on the server. Please recreate the audio.', 'assistini')}</span>    
                                </div>
                            </div>
                        </div>
                    `;
                }
                count++;
            }
            entry.data.result_data.forEach((variant) => {
            });
        }
    }
    return variantsHtml;
}
function openHistory() {
    jQuery('.ass-es-page-template-history-toggle').addClass('ass-es-active');
    jQuery('.ass-es-page-template-history-wrapper').slideDown(200);
}
function closeHistory() {
    jQuery('.ass-es-page-template-history-toggle').removeClass('ass-es-active');
    jQuery('.ass-es-page-template-history-wrapper').slideUp(200);
}
function uploadImageToLibrary(requestId = '', imageUrl = '', filename = '', title = '', extension = '') {
    return new Promise((resolve) => {
        jQuery.ajax({
            url: ajaxurl,
            type: "POST",
            cache: false,
            data: {
                'action': 'assi_upload_image_to_library',
                'filename': filename,
                'title': title,
                'extension': extension,
                'assi_security_nonce': assi_plugin_data.assi_security_nonce,
                'image': imageUrl,
                'request_id': requestId
            },
            success: function (data) {
                data = JSON.parse(data);
                if (data.result != undefined && data.result == true) {
                    resolve(true);
                } else {
                    resolve(false);
                }
            },
            error: function () {
                resolve(false);   
            },
        });
    });
}
function uploadAudioToLibrary(requestId = '', audioUrl = '', filename = '', title = '', extension = '') {
    return new Promise((resolve) => {
        jQuery.ajax({
            url: ajaxurl,
            type: "POST",
            cache: false,
            data: {
                'action': 'assi_upload_audio_to_library',
                'request_id': requestId,
                'filename': filename,
                'title': title,
                'extension': extension,
                'assi_security_nonce': assi_plugin_data.assi_security_nonce,
                'audio': audioUrl,
            },
            success: function (data) {
                data = JSON.parse(data);
                if (data.result != undefined && data.result == true) {
                    resolve(true);
                } else {
                    resolve(false);
                }
            },
            error: function () {
                resolve(false);   
            },
        });
    });
}
function replaceNewLine(text) {
    text = text
        .split(/(<[^>]+>)/g) // In Tags und Nicht-Tags aufteilen
        .map(part => {
            if (!part.startsWith("<")) {
                // Newlines zu <br>
                part = part.replace(/(?:\r\n|\r|\n)/g, '<br>');
                // Maximal 2 <br> hintereinander
                part = part.replace(/(?:<br>\s*){3,}/g, '<br><br>');
            }
            return part;
        })
        .join("");

    if (text.endsWith('<br>')) {
        text = text.slice(0, -4);
    }

    text = text.replace(/(<\/?(ul|ol)[^>]*>)([\s\S]*?)(<\/\2>)/g,
        (match, openTag, listType, content, closeTag) => {
            content = content.replace(/<br\s*\/?>/gi, '');
            return `${openTag}${content}${closeTag}`;
        }
    );

    // <br> aus Tabellen entfernen
    text = text.replace(/(<table[^>]*>)([\s\S]*?)(<\/table>)/gi,
        (match, openTag, content, closeTag) => {
            content = content.replace(/<br\s*\/?>/gi, '');
            return `<br>${openTag}${content}${closeTag}<br>`;
        }
    );

    // remove <br> from lists
    text = text.replace(/(<\/?(ul|ol)[^>]*>)([\s\S]*?)(<\/\2>)/g, (match, openTag, listType, content, closeTag) => {
        content = content.replace(/<br>/g, '');
        return `${openTag}${content}${closeTag}`;
    });

    // remove <br> after paragraphs
    text = text.replace(/<\/p>\s*<br>/g, '</p>');

    // remove <br> after <h1-5> tags
    text = text.replace(/(<\/h[1-5]>)\s*<br\s*\/?>/gi, "$1");

    // remove <hr> at end of text
    text = text.replace(/<hr\s*\/?>\s*$/i, '');

    // remove multiple <br> to one
    text = text.replace(/(?:<br\s*\/?>\s*){3,}/g, '<br><br>');
    return text;
}

function convertHtmlToGutenbergBlocks(html) {
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');
    const body = doc.body;
    let output = '';
    body.childNodes.forEach(node => {
        if (node.nodeType !== Node.ELEMENT_NODE) {
            return;
        }
        const tag = node.tagName.toLowerCase();
        const innerHTML = node.outerHTML;
        if (node.innerHTML.trim() != '' || tag == 'hr') {
            switch (tag) {
                case 'p':
                    output += `<!-- wp:paragraph -->${innerHTML}<!-- /wp:paragraph -->\n\n`;
                    break;
                case 'h1':
                    output += `<!-- wp:heading {"level":1} -->${innerHTML}<!-- /wp:heading -->\n\n`;
                    break;
                case 'h2':
                    output += `<!-- wp:heading {"level":2} -->${innerHTML}<!-- /wp:heading -->\n\n`;
                    break;
                case 'h3':
                    output += `<!-- wp:heading {"level":3} -->${innerHTML}<!-- /wp:heading -->\n\n`;
                    break;
                case 'h4':
                    output += `<!-- wp:heading {"level":4} -->${innerHTML}<!-- /wp:heading -->\n\n`;
                    break;
                case 'ul':
                    output += `<!-- wp:list -->${innerHTML}<!-- /wp:list -->\n\n`;
                    break;
                case 'ol':
                    output += `<!-- wp:list {"ordered":true} -->${innerHTML}<!-- /wp:list -->\n\n`;
                    break;
                case 'hr':
                    output += '<!-- wp:separator --><hr class="wp-block-separator" /><!-- /wp:separator -->\n\n';
                    break;
                default:
                    output += innerHTML + '\n\n';
                    break;
            }
        }
    });
    return output.trim();
}