/**
 * @author 1902 Software
 * @copyright Copyright 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

define([
    'jquery',
    'underscore',
    'uiComponent',
    'ko',
    'WriteTextAI_WriteTextAI/js/model/edit',
    'WriteTextAI_WriteTextAI/js/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/attributes',
    'WriteTextAI_WriteTextAI/js/model/edit/additional-prompt',
    'WriteTextAI_WriteTextAI/js/model/edit/textfields',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'WriteTextAI_WriteTextAI/js/model/edit/audience',
    'WriteTextAI_WriteTextAI/js/model/edit/custom-tone-style',
    'WriteTextAI_WriteTextAI/js/model/edit/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/error-messages',
    'WriteTextAI_WriteTextAI/js/utils/edit/toolbar',
    'WriteTextAI_WriteTextAI/js/model/total-credits',
    'WriteTextAI_WriteTextAI/js/model/edit/preferences',
    'WriteTextAI_WriteTextAI/js/model/edit/gallery',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keywords',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis',
    'mage/translate',
    'collapsible',
    'accordion',
    'wtaiAdminIdle'
], function (
    $,
    _,
    Component,
    ko,
    editData,
    signalRModel,
    generateSettings,
    generateAttributes,
    additionalPrompt,
    textfields,
    product,
    audience,
    customToneStyle,
    settings,
    errorMessagesModel,
    toolbarUtils,
    totalCredits,
    preferences,
    gallery,
    keywordsData,
    keywordAnalysisData,
    $t
) {
    'use strict';

    /**
     * @var {Component} self
     */
    var self;

    return Component.extend({
        defaults: {
            element: '.wtai-wtai-toolbar',
            collapsibleSelector: '.wtai-custom-action-select-wrap',
            toggleSelectAllSelector: 'input[name=select_all]',
            accordionTargetSelector: '.wtai-fieldset.wtai-text-editor',
            galleryAccordionSelector: '.wtai-gallery',
            accordionKeywordAttributesSelector: '.wtai-keywords-attributes',
            accordionToggleSelector: '.wtai-wtai-toolbar .wtai-toggle-accordion',
            accordionSingleToggleSelector:
                '.wtai-textfields .admin__collapsible-block-wrapper',
            accordionSelector: '.wtai-edit-modal-wrapper .wtai-accordions',
            textfieldsCount: 5,
            widgetsInitialized: false,
            suggestedAudience: [],
            selectedAudience: '',
            productId: '',
            storeId: '',
            tones: [],
            styles: [],
            audience: [],
            credits: [],
            tonesSelected: [],
            stylesSelected: '',
            audienceSelected: [],
            descMin: 0,
            descMax: 0,
            excMin: 0,
            excMax: 0,
            productAttributesSelected: [],
            otherProductDetails: '',
            otherProductDetailsChecked: false,
            additionalPrompt: '',
            selectedFields: [],
            customTone: '',
            customStyle: '',
            selectAllTonesValue: null,
            canUpdateTones: true,
            selectAllAudienceValue: null,
            canUpdateAudience: true,
            directiveRegex: [],
            customOpenGraph: false,
            formalLanguageSupport: [],
            formalLanguages: [],
            disallowedCombinations: [],
            highlightPronouns: false,
            language: '',
            defaultTones: [],
            defaultStyle: '',
            guideSteps: false,
            selectedImages: [],
            useAiModel: false,
            selectedAiModel: '',
            aiModels: [],
            hasAiModels: false,
            genToneStyleMode: 'manual'
        },

        accordionExpanded: true,
        typingTimer: null,
        isTonesSelectedChanged: false,
        isHighlightPronounsChange: false,
        editToneStyleAllowed: false,
        isAudienceChange: false,
        selectedAudiencechanged: false,
        isGenToneStyleModeChange: false,
        getAudienceRequest: null,
        isGenerateAllowed: false,

        /** @inheritdoc */
        initialize: function () {
            this._super();

            self = this;

            this.isViewerUser = ko.pureComputed(function () {
                return !self.isGenerateAllowed;
            });

            this.isProcessRunning = ko.pureComputed(function () {
                return Boolean(
                    (signalRModel.generating && signalRModel.generating()) ||
                    (keywordAnalysisData.optimizing && keywordAnalysisData.optimizing()) ||
                    (keywordAnalysisData.isUploading && keywordAnalysisData.isUploading()) ||
                    (keywordAnalysisData.refreshingData && keywordAnalysisData.refreshingData())
                );
            });

            if (settings.genToneStyleMode) {
                self.isGenToneStyleModeChange = true;
                self.genToneStyleMode(settings.genToneStyleMode());
                self.isGenToneStyleModeChange = false;
            }

            if (self.hasAiModels === false) {
                self.isGenToneStyleModeChange = true;
                self.genToneStyleMode('manual');
                self.useAiModel(false);
                self.selectedAiModel('');
                if (settings.genToneStyleMode) {
                    settings.genToneStyleMode('manual');
                }
                if (settings.useAiModel) {
                    settings.useAiModel(false);
                }
                if (settings.selectedAiModel) {
                    settings.selectedAiModel('');
                }
                self.isGenToneStyleModeChange = false;
            }

            gallery.selectedImages.subscribe(function (selectedImages) {
                self.selectedImages(selectedImages);
            });

            product.productId.subscribe(function (productId) {
                self.productId(productId);
            });

            product.storeId.subscribe(function (storeId) {
                self.storeId(storeId);
            });

            product.language.subscribe(function (language) {
                self.language(language);
            });

            product.directiveRegex.subscribe(function (directiveRegex) {
                if (directiveRegex && directiveRegex.length > 0) {
                    self.directiveRegex(directiveRegex);
                } else {
                    self.directiveRegex([]);
                }
            });

            self.selectedAudience.subscribe(function (selectedAudience) {
                if (!self.selectedAudiencechanged) {
                    audience.selectedAudience(selectedAudience);
                }
            });

            audience.selectedAudience.subscribe(function (selectedAudience) {
                self.selectedAudiencechanged = true;
                self.selectedAudience(selectedAudience);
                self.selectedAudiencechanged = false;
            });

            audience.suggestedAudience.subscribe(function (suggestedAudience) {
                self.suggestedAudience(suggestedAudience);
            });

            self.tonesSelected.subscribe(
                function (changes) {
                    if (!self.isTonesSelectedChanged) {
                        self.isTonesSelectedChanged = true;

                        _.each(changes, function (change) {
                            if (
                                change.status === 'added' &&
                                change.value === 'custom'
                            ) {
                                self.tonesSelected.remove(self.isNotCustom);
                                self.selectAllTonesValue(false);
                            }
                            if (
                                change.status === 'added' &&
                                change.value !== 'custom'
                            ) {
                                self.tonesSelected.remove('custom');
                                self.customTone('');
                            }
                        });

                        if (self.canUpdateTones) {
                            self.observeTonesSelected();
                        }

                        textfields.formal(
                            self.tonesSelected().indexOf('Formal') !== -1
                        );

                        self.isTonesSelectedChanged = false;
                    }
                    
                    preferences.tonesSelected(self.tonesSelected());
                },
                this,
                'arrayChange'
            );

            if (settings.genToneStyleMode) {
                settings.genToneStyleMode.subscribe(function (mode) {
                    self.isGenToneStyleModeChange = true;
                    self.genToneStyleMode(mode);
                    self.isGenToneStyleModeChange = false;
                });
            }

            this.genToneStyleMode.subscribe(function (mode) {
                if (settings.genToneStyleMode && !self.isGenToneStyleModeChange) {
                    settings.genToneStyleMode(mode);
                }

                this.useAiModel(mode === 'ai_model');

                if (mode === 'manual') {
                    this.selectedAiModel(null);
                }
            }.bind(this));

            self.stylesSelected.subscribe(function (style) {
                if (style !== 'custom') {
                    self.customStyle('');
                }
                preferences.stylesSelected(style);
            });

            preferences.tonesSelected.subscribe(function (tones) {
                if (self.isTonesSelectedChanged) {
                    return;
                }

                if (Array.isArray(tones)) {
                    self.isTonesSelectedChanged = true;
                    self.tonesSelected(tones);
                    self.isTonesSelectedChanged = false;
                }
            });

            preferences.stylesSelected.subscribe(function (style) {
                if (style !== undefined && style !== null) {
                    self.stylesSelected(style);
                }
            });

            self.customTone.subscribe(function (customTone) {
                if (customTone) {
                    self.tonesSelected(['custom']);
                    self.selectAllTonesValue(false);
                }
                preferences.customTone(customTone);
            });

            self.customStyle.subscribe(function (customStyle) {
                self.stylesSelected('custom');
                preferences.customStyle(customStyle);
            });

            self.highlightPronouns.subscribe(function (highlightPronouns) {
                if (!self.isHighlightPronounsChange) {
                    textfields.highlightPronouns(highlightPronouns);
                    self.saveHighlightPronouns(highlightPronouns);
                }
            });

            textfields.highlightPronouns.subscribe(
                function (highlightPronouns) {
                    self.isHighlightPronounsChange = true;
                    self.highlightPronouns(highlightPronouns);
                    self.isHighlightPronounsChange = false;
                }
            );

            customToneStyle.customTone.subscribe(function (customTone) {
                self.customTone(customTone);
            });

            customToneStyle.customStyle.subscribe(function (customStyle) {
                self.customStyle(customStyle);
            });

            settings.customTone.subscribe(function (customTone) {
                self.customTone(customTone);
            });

            settings.customStyle.subscribe(function (customStyle) {
                self.customStyle(customStyle);
            });

            textfields.selectedFields.subscribe(function (selectedFields) {
                self.selectedFields([]);
                for (let key in selectedFields) {
                    if (selectedFields.hasOwnProperty(key)) {
                        self.selectedFields.push(selectedFields[key]);
                    }
                }
            });

            generateSettings.descMin.subscribe(function (descMin) {
                self.descMin(descMin);
            });

            generateSettings.descMax.subscribe(function (descMax) {
                self.descMax(descMax);
            });

            generateSettings.excMin.subscribe(function (excMin) {
                self.excMin(excMin);
            });

            generateSettings.excMax.subscribe(function (excMax) {
                self.excMax(excMax);
            });

            generateAttributes.productAttributesSelected.subscribe(
                function (productAttributesSelected) {
                    self.productAttributesSelected([]);
                    for (let key in productAttributesSelected) {
                        if (productAttributesSelected.hasOwnProperty(key)) {
                            self.productAttributesSelected.push(
                                productAttributesSelected[key]
                            );
                        }
                    }
                }
            );

            generateAttributes.otherProductDetails.subscribe(
                function (otherProductDetails) {
                    self.otherProductDetails(otherProductDetails);
                }
            );

            generateAttributes.otherProductDetailsChecked.subscribe(
                function (otherProductDetailsChecked) {
                    self.otherProductDetailsChecked(otherProductDetailsChecked);
                }
            );

            additionalPrompt.promptValue.subscribe(
                function (additionalPrompt) {
                    self.additionalPrompt(additionalPrompt);
                }
            );

            editData.opened.subscribe(function (opened) {
                if (opened) {
                    /* reset accordions */
                    $(self.accordionKeywordAttributesSelector).accordion('activate', 0);
                    $(self.accordionKeywordAttributesSelector).accordion('activate', 1);
                    $(self.accordionSelector).each(function () {
                        if ($(this).hasClass('wtai-fieldset')) {
                            $(this).accordion('activate');
                        }
                    });
                } else {
                    self.isGenToneStyleModeChange = true;
                    self.genToneStyleMode("manual");
                    settings.genToneStyleMode("manual");
                    self.isGenToneStyleModeChange = false;
                }
                if (opened && !self.widgetsInitialized) {
                    self.bindCollapsible();
                    self.bindCheckboxToggle();
                    self.bindAccordionToggle();
                    self.widgetsInitialized = true;
                }
            });

            settings.tones.subscribe(function (tones) {
                var getTones = tones
                    .filter(function (tone) {
                        return tone.default;
                    })
                    .map(function (tone) {
                        return tone.id;
                    });

                var filteredTones = tones.filter(function (tone) {
                    return tone.id !== 'custom';
                });
                self.tones(filteredTones);
                if (getTones.length > 0) {
                    self.tonesSelected(getTones);
                }
            });

            settings.styles.subscribe(function (styles) {
                var getStyles = styles
                    .filter(function (style) {
                        return style.default;
                    })
                    .map(function (style) {
                        return style.id;
                    });

                self.styles(styles);
                if (!self.stylesSelected() && getStyles.length > 0) {
                    self.stylesSelected(getStyles.shift());
                }
            });

            settings.audience.subscribe(function (settingsAudience) {
                var getAudience = settingsAudience
                    .filter(function (item) {
                        return item.default;
                    })
                    .map(function (item) {
                        return item.id;
                    });

                self.audience(settingsAudience);
                self.isAudienceChange = true;
                self.audienceSelected(getAudience);
                self.isAudienceChange = false;
            });

            settings.credits.subscribe(function (credits) {
                self.credits(credits);
            });

            settings.formalLanguageSupport.subscribe(
                function (formalLanguageSupport) {
                    self.formalLanguageSupport(formalLanguageSupport);
                }
            );

            settings.formalLanguages.subscribe(
                function (formalLanguages) {
                    self.formalLanguages(formalLanguages);
                }
            );

            settings.disallowedCombinations.subscribe(
                function (disallowedCombinations) {
                    self.disallowedCombinations(disallowedCombinations);
                }
            );
            
            settings.guideSteps.subscribe(function (guideSteps) {
                self.guideSteps(guideSteps);
            });

            self.audienceSelected.subscribe(function (audienceSelected) {
                if (!self.isGenerateAllowed) {
                    return;
                }
                if (self.canUpdateAudience) {
                    self.observeAudienceSelected();
                }
                preferences.audienceSelected(audienceSelected);
                if (!self.isAudienceChange) {
                    self.savePreferences('audiences', audienceSelected, 'global', 'grid');
                }
            });

            settings.useAiModel.subscribe(function (useAiModel) {
                this.useAiModel(useAiModel);
            }, this);

            settings.selectedAiModel.subscribe(function (selectedAiModel) {
                this.selectedAiModel(selectedAiModel);
                if (this.selectedAiModel()) {
                    this.genToneStyleMode("ai_model");
                }

            }, this);

            this.useAiModel.subscribe(function (useAiModel) {
                settings.useAiModel(useAiModel);
            });

            this.selectedAiModel.subscribe(function (selectedAiModel) {
                settings.selectedAiModel(selectedAiModel ? selectedAiModel : '');
            });

            this.hasProAccess.subscribe(function (hasProAccess) {
                if (!hasProAccess) {
                    this.useAiModel(false);
                    this.selectedAiModel(null);
                }
            }, this);
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'suggestedAudience',
                'selectedAudience',
                'productId',
                'storeId',
                'tones',
                'styles',
                'audience',
                'credits',
                'tonesSelected',
                'stylesSelected',
                'audienceSelected',
                'descMin',
                'descMax',
                'excMin',
                'excMax',
                'productAttributesSelected',
                'otherProductDetails',
                'otherProductDetailsChecked',
                'additionalPrompt',
                'selectedFields',
                'customTone',
                'customStyle',
                'selectAllTonesValue',
                'selectAllAudienceValue',
                'directiveRegex',
                'formalLanguageSupport',
                'formalLanguages',
                'disallowedCombinations',
                'highlightPronouns',
                'language',
                'guideSteps',
                'selectedImages',
                'useAiModel',
                'selectedAiModel',
                'aiModels',
                'genToneStyleMode'
            ]);

            this.keywords = ko.computed(function () {
                var optimizingKeywords = keywordAnalysisData.optimizationData().allOptimizingKeywords || [];
                
                if (optimizingKeywords && optimizingKeywords.length > 0) {
                    return optimizingKeywords;
                } else {
                    return keywordsData.selectedKeywords();
                }
            }, this);

            this.selectedFieldsCount = ko.computed(function () {
                if (gallery.images().length > 0) {
                    return this.selectedFields().length === this.textfieldsCount && gallery.selectAllImages();
                } else {
                    return this.selectedFields().length === this.textfieldsCount;
                }
            }, this);

            this.getTonesStylesSelected = ko.computed(function () {
                var tonesCount = this.tonesSelected() ? this.tonesSelected().length : 0,
                    stylesCount = this.stylesSelected() ? 1 : 0,
                    total = tonesCount + stylesCount;

                return total + ' ' + $t('selected');
            }, this);

            this.getAudienceSelected = ko.computed(function () {
                var audienceCount = this.audienceSelected() ? this.audienceSelected().length : 0;

                return audienceCount + ' ' + $t('selected');
            }, this);

            /**
             * Check if rewrite is available.
             */
            this.rewriteAvailable = ko.computed(function () {
                var isProductOptimizing = Number(keywordAnalysisData.optimizingId()) === Number(this.productId()) &&
                    Number(keywordAnalysisData.optimizingStoreId()) === Number(this.storeId()),
                keywordAnalysisOngoing = (keywordAnalysisData.optimizing() ||
                    keywordAnalysisData.isUploading()) &&
                    !keywordAnalysisData.optimized() &&
                    !keywordAnalysisData.optimizationFailed() &&
                    !keywordAnalysisData.imageUploadFailed();

                if (keywordAnalysisOngoing && isProductOptimizing) {
                    return false;
                }

                var selectedFields = this.selectedFields(),
                    selectedImages = this.selectedImages(),
                    textFields = textfields,
                    images = gallery.images();
    
                var canRewriteFields = selectedFields.some((field) => {
                        return (
                            field === 'page_title' &&
                                textFields.mgPageTitle() !== '' ||
                            field === 'page_description' &&
                                textFields.mgPageDescription() !== '' ||
                            field === 'product_description' &&
                                textFields.mgProductDescription() !== '' ||
                            field === 'short_product_description' &&
                                textFields.mgProductShortDescription() !== '' ||
                            self.customOpenGraph &&
                                field === 'open_graph' &&
                                textFields.mgOpenGraph() !== ''
                        );
                    }),
                    canRewriteMedia = images.some((image) => {
                        return image.alt !== '' && selectedImages.includes(image.id)
                    });

                return canRewriteFields || canRewriteMedia;
            }, this);

            this.enableHighlightPronouns = ko.computed(function () {
                return this.tonesSelected().indexOf('Formal') !== -1;
            }, this);

            this.isTrainedModelEnabled = ko.computed(function () {
                return this.useAiModel();
            }, this);

            this.hasProAccess = ko.computed(function () {
                return totalCredits.hasProAccess();
            });

            return this;
        },

        /**
         * Save user preferences for tones and styles
         */
        saveTonesAndStyles: function () {
            var url = self.saveUrl,
                tones = self.tonesSelected(),
                customTone = self.customTone(),
                styles = self.stylesSelected(),
                customStyle = self.customStyle();
            
            if (tones.length <= 0) {
                tones = '';
            }

            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    tones: tones,
                    style: styles,
                    custom_tone: customTone,
                    custom_style: customStyle,
                    entity_type: 'global',
                    scope: 'grid'
                },
                dataType: 'json',
                showWriteTextAILoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },
        /**
         * Handle custom tone and style typing
         */
        handleCustomToneStyle: function () {
            clearTimeout(self.typingTimer);

            self.typingTimer = setTimeout(function () {
                self.saveTonesAndStyles();
            }, 2000);
        },

        /**
         * Save user preferences
         *
         * @param {string} field
         * @param {string} selected
         * @param {string} entityType
         * @param {string} scope
         *
         * @returns {void}
         */
        savePreferences: function (field, selected, entityType = '', scope = '') {
            var value = selected;
            
            if (value.length <= 0) {
                value = '';
            }
            
            $.ajax({
                url: self.saveUrl,
                type: 'POST',
                data: {
                    [field]: value,
                    entity_type: entityType,
                    scope: scope
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

        /**
         * Process click functionality of select all
         * Important to always return true
         * in order for checked binding to continue working
         *
         * @returns {boolean}
         */
        processClick: function () {
            var value = gallery.selectAllImages();
            self.savePreferences('gallery', !value, 'product', 'edit');
            return true;
        },

        /**
         * Check if not custom
         *
         * @param {string} value
         * @returns {boolean}
         */
        isNotCustom: function (value) {
            return value !== 'custom';
        },

        /**
         * Save user settings for highlighted pronouns.
         *
         * @param {boolean} highlighted
         * @returns {void}
         */
        saveHighlightPronouns: function (highlighted) {
            $.ajax({
                url: self.highlightPronounsUrl,
                type: 'POST',
                data: {
                    highlighted: highlighted,
                    entity_type: 'product'
                },
                dataType: 'json',
                showWriteTextAILoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response.message);
                    }
                }
            });
        },

        /**
         * Get tooltip text based on disallowed combination
         *
         * @param {string} id
         * @param {string} type
         *
         * @returns {string}
         */
        getToolTipCombinationDisallowed: function (id, type) {
            if (this.isCombinationDisallowed(id, type)) {
                return this.getTooltipCombinationDisallowedText(id, type);
            }
            return '';
        },

        /**
         * Check if combination is not allowed
         *
         * @param {string} id
         * @param {string} type
         *
         * @returns {boolean}
         */
        isCombinationDisallowed: function (id, type) {
            return toolbarUtils.isCombinationDisallowed(id, type, self);
        },

        /**
         * Get tooltip text based on disallowed combination
         *
         * @param {string} id
         * @param {string} type
         *
         * @returns {string}
         */
        getTooltipCombinationDisallowedText: function (id, type) {
            return toolbarUtils.getTooltipCombinationDisallowedText(id, type, self);
        },

        /**
         * Get custom style length.
         */
        getCustomStyleLength: function () {
            var length = this.customStyle() ? this.customStyle().length : 0;

            return (
                length + '/' + this.rules.maxCustomStyleLength + ' ' + $t('Char')
            );
        },

        /**
         * Get custom tone length.
         */
        getCustomToneLength: function () {
            var length = this.customTone() ? this.customTone().length : 0;

            return length + '/' + this.rules.maxCustomToneLength + ' ' + $t('Char');
        },

        /**
         * Get custom tone length.
         */
        getCustomAudienceLength: function () {
            var length = this.selectedAudience()
                ? this.selectedAudience().length
                : 0;

            return (
                length + '/' + this.rules.maxCustomAudienceLength + ' ' + $t('Char')
            );
        },

        /**
         * Bind settings dropdown toggle.
         */
        bindCollapsible: function () {
            toolbarUtils.bindCollapsible(self);
        },

        /**
         * Bind select text fields checkbox toggle.
         */
        bindCheckboxToggle: function () {
            var fields = [
                    'page_title',
                    'page_description',
                    'product_description',
                    'short_product_description'
                ],
                fieldsCopy = [];

            if (self.customOpenGraph) {
                fields.push('open_graph');
            }

            fieldsCopy = [...fields];

            $(self.toggleSelectAllSelector).on('click', function () {
                var value = [];

                if (this.checked) {
                    value = Object.keys(fieldsCopy)
                        .filter(key => fieldsCopy.hasOwnProperty(key))
                        .map(key => fieldsCopy[key]);
                }

                textfields.selectedFields(value);
                gallery.selectAllImages(this.checked);
                self.savePreferences('single_editor', value, 'product', 'edit');
                
            });
        },

        /**
         * Bind text field accordion toggle.
         */
        bindAccordionToggle: function () {
            $(self.accordionToggleSelector).on('click', function () {
                if (self.accordionExpanded) {
                    $(self.accordionTargetSelector).accordion('deactivate');
                    $(self.accordionKeywordAttributesSelector).accordion('deactivate');
                    $(self.galleryAccordionSelector).accordion('deactivate');
                    self.accordionExpanded = false;
                } else {
                    $(self.accordionTargetSelector).accordion('activate');
                    $(self.accordionKeywordAttributesSelector).accordion('activate');
                    $(self.galleryAccordionSelector).accordion('activate');
                    self.accordionExpanded = true;
                }
            });
        },

        /**
         * Handle input custom audience.
         */
        handleInputAudience: function () {
            clearTimeout(self.typingTimer);
            if (!self.isGenerateAllowed) {
                return;
            }

            self.typingTimer = setTimeout(function () {
                self.selectAudience();
            }, 2000);
        },

        /**
         * Regenerate suggested audience.
         */
        regenerateAudience: function () {
            if (!self.isGenerateAllowed) {
                return;
            }
            self.getAudience(true);
        },

        /**
         * Regenerate suggested audience.
         */
        getAudience: function () {
            var url = self.audienceGetUrl,
                regenerate = false,
                storeId = self.storeId(),
                productId = self.productId();

            self.selectedAudience('');
            self.suggestedAudience('');

            errorMessagesModel.messages([]);

            if (self.getAudienceRequest) {
                self.getAudienceRequest.abort();
            }

            self.getAudienceRequest = $.ajax({
                url: url,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId,
                    keywords: self.keywords(),
                    product_name: product.productName(),
                    regenerate: regenerate
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showAudienceLoader: true,
                success: function (response) {
                    if (response.success) {
                        self.selectedAudience(response.selected.shift());
                        self.suggestedAudience(response.values);
                    } else {
                        errorMessagesModel.messages.push(response.message);
                    }
                },
                error: function (xhr, status, error) {
                    if (status !== 'abort') {
                        errorMessagesModel.messages.push(error);
                    }
                }
            });
        },

        /**
         * Select a suggested audience.
         *
         * @param {string} selected
         * @return void
         */
        selectAudience: function (selected = null) {
            if (!self.isGenerateAllowed) {
                return;
            }
            var url = self.audienceSelectUrl,
                storeId = self.storeId(),
                productId = self.productId(),
                productName = product.productName();

            selected = selected || self.selectedAudience();
            
            errorMessagesModel.messages([]);

            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId,
                    selected: selected,
                    product_name: productName
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showAudienceLoader: true,
                success: function (response) {
                    if (response.success) {
                        self.selectedAudience(response.selected.shift());
                        self.suggestedAudience(response.values);
                    } else {
                        errorMessagesModel.messages.push(response.message);
                    }
                }
            });
        },

        /**
         * Reset settings.
         *
         * @param {string} type
         * @returns {void}
         */
        reset: function (type) {
            if (type === 'tones') {
                self.tonesSelected(self.defaultTones);
                self.stylesSelected(self.defaultStyle);
                self.saveTonesAndStyles();
            }

            if (type === 'audience') {
                if (!self.isGenerateAllowed) {
                    return;
                }
                self.audienceSelected([...self.defaultAudiences]);
            }
        },

        /**
         * Select all tones.
         */
        selectAllTones: function () {
            var tones = self.tones().map(function (tone) {
                if (!$('[name="tones[]"][value="' + tone.id + '"]').attr('disabled')
                    && !$('[name="tones[]"][value="' + tone.id + '"]').hasClass('wtai-disabled')) {
                    return tone.id;
                }
            }).filter(function (element) {
                return element != null;
            });

            this.canUpdateTones = false;
            if (this.selectAllTonesValue()) {
                self.tonesSelected(tones);
            } else {
                self.tonesSelected([]);
            }
            this.canUpdateTones = true;

            self.saveTonesAndStyles();
        },

        /**
         * Observe tones selected.
         */
        observeTonesSelected: function () {
            var tonesSelectedCount = self.tonesSelected() ? self.tonesSelected().length : 0;

            if (self.tonesSelected() && self.tonesSelected().indexOf('custom') !== -1) {
                this.selectAllTonesValue(false);
                return;
            }

            if (self.tones().length === tonesSelectedCount) {
                this.selectAllTonesValue(true);
            } else {
                this.selectAllTonesValue(false);
            }
        },

        /**
         * Select all audience.
         */
        selectAllAudience: function () {
            if (!self.isGenerateAllowed) {
                return;
            }
            var allAudience = self.audience().map(function (data) {
                if (!$('[name="audience[]"][value="' + data.id + '"]').attr('disabled')) {
                    return data.id;
                }
            });

            this.canUpdateAudience = false;
            if (this.selectAllAudienceValue()) {
                self.audienceSelected(allAudience);
            } else {
                self.audienceSelected([]);
            }
            this.canUpdateAudience = true;
        },

        /**
         * Observe audience selected.
         */
        observeAudienceSelected: function () {
            var audienceSelectedCount = self.audienceSelected() ? self.audienceSelected().length : 0;

            if (
                self.audience().length === audienceSelectedCount &&
                self.audience().length > 0
            ) {
                this.selectAllAudienceValue(true);
            } else {
                this.selectAllAudienceValue(false);
            }
        },
    });
});

