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

define([
    'jquery',
    'ko',
    'uiComponent',
    'underscore',
    'WriteTextAI_WriteTextAI/js/model/edit',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'WriteTextAI_WriteTextAI/js/model/edit/textfields',
    'WriteTextAI_WriteTextAI/js/model/edit/error-messages',
    'WriteTextAI_WriteTextAI/js/model/edit/transfer/settings',
    'WriteTextAI_WriteTextAI/js/utils/edit/textfields',
    'WriteTextAI_WriteTextAI/js/model/edit/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/mark-reviewed',
    'WriteTextAI_WriteTextAI/js/model/edit/preferences',
    'WriteTextAI_WriteTextAI/js/model/edit/gallery',
    'WriteTextAI_WriteTextAI/js/model/edit/review-status',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis',
    'Magento_Ui/js/modal/confirm',
    'mage/translate',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/attributes',
    'WriteTextAI_WriteTextAI/js/model/edit/additional-prompt',
    'WriteTextAI_WriteTextAI/js/utils/edit/generate',
    'WriteTextAI_WriteTextAI/js/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/edit/attributes',
    'WriteTextAI_WriteTextAI/js/model/edit/invalid-image-popup',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keywords',
    'WriteTextAI_WriteTextAI/js/model/grid/popups/image-upload-progressbar',
    'WriteTextAI_WriteTextAI/js/model/edit/select-template',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/currently-generating',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/model/edit/audience',
    'Magento_Ui/js/modal/alert'
], function (
    $,
    ko,
    Component,
    _,
    editData,
    product,
    textfields,
    errorMessagesModel,
    transferSettings,
    textfieldsUtils,
    settings,
    markReviewed,
    preferences,
    gallery,
    reviewStatus,
    keywordAnalysisData,
    confirm,
    $t,
    generateSettings,
    generateAttributes,
    additionalPrompt,
    generateUtils,
    signalRModel,
    attributes,
    invalidImagePopupModel,
    keywordsData,
    imageUploadProgressbarModel,
    selectTemplateModel,
    currentlyGeneratingModel,
    genkeywordAnalysis,
    audience,
    alert
) {
    'use strict';

    /**
     * @var {Component} self
     */
    var self;
    
    /**
     * @var {Component} self2
     */
    var self2 = {
        targetFieldId: null,
        targetFieldClass: null,
        generatedFieldId: null,
        generatedFieldIdSecondary: null,
        generatedOpenGraphEditor: null,
        generatedImageContainer: null,
        customPageTitle: null,
        customPageDescription: null,
        customProductDescription: null,
        customShortDescription: null,
        bulkGenerateImageContainer: null,
        baseUrl: null,
        activeGenerateRequest: null,  /** Track active generate request */
        activeUploadRequest: null,   /** Track active upload request */
        pendingRetryData: null       /** Store data for retry */
    };

    return Component.extend({
        defaults: {
            previewButtonSelector: '.wtai-preview-button',
            defaultStoreId: 0,
            productId: '',
            storeId: '',
            pageTitle: '',
            pageDescription: '',
            productDescription: '',
            productShortDescription: '',
            openGraph: '',
            selectedFields: [],
            eventsInitialized: false,
            directiveRegex: [],
            descriptionDirectiveExists: false,
            shortDescriptionDirectiveExists: false,
            selectedStores: [],
            guideSteps: false,
            customTone: '',
            customStyle: '',
            selectedTones: [],
            selectedStyles: '',
            selectedAudience: [],
            error: '',
            statuses: {
                pageTitleGenerateStatus: false,
                pageDescriptionGenerateStatus: false,
                productDescriptionGenerateStatus: false,
                productShortDescriptionGenerateStatus: false,
                openGraphGenerateStatus: false,
                pageTitleTransferStatus: false,
                pageDescriptionTransferStatus: false,
                productDescriptionTransferStatus: false,
                productShortDescriptionTransferStatus: false,
                openGraphTransferStatus: false
            }
        },
        updateFields: [],

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

            self = this;

            this.isKoRefreshing = ko.pureComputed(function () {
                return Boolean(
                    keywordAnalysisData.refreshingData && keywordAnalysisData.refreshingData()
                );
            });

            self.initAjaxRetryHandler();

            signalRModel.isConnected.subscribe(function (isConnected) {
                if (editData.opened() && isConnected) {
                    var recordId = self.productId();
                    var storeId = self.storeId();
                    var entityType = 'Product';
                    var identifier = entityType + '_'+ recordId + '_' + storeId;
                    var currentlyGeneratingRecordIdentifiers = currentlyGeneratingModel.recordIdentifiers();
                    if (currentlyGeneratingRecordIdentifiers.includes(identifier)) {
                        self.getGenerated(self.selectedFields(), false);
                    }
                }
            }, this);

            /* get product and store id */
            product.productId.subscribe(function (productId) {
                self.productId(productId);
            });
            product.storeId.subscribe(function (storeId) {
                self.storeId(storeId);
            });

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

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

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

            /* get field values */
            textfields.pageTitle.subscribe(function (pageTitle) {
                self.pageTitle(pageTitle);
            });
            textfields.pageDescription.subscribe(function (pageDescription) {
                self.pageDescription(pageDescription);
            });
            textfields.productDescription.subscribe(
                function (productDescription) {
                    /* productDescription = textfieldsUtils.convertNewLinesToBr(productDescription); */
                    self.productDescription(productDescription);
                }
            );
            textfields.productShortDescription.subscribe(
                function (productShortDescription) {
                   /* productShortDescription = textfieldsUtils.convertNewLinesToBr(productShortDescription); */
                    self.productShortDescription(productShortDescription);
                }
            );
            textfields.openGraph.subscribe(function (openGraph) {
                self.openGraph(openGraph);
            });

            /* get selected fields */
            textfields.selectedFields.subscribe(function (selectedFields) {
                self.selectedFields([]);

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

            textfields.statuses.subscribe(function (statuses) {
                self.statuses(statuses);
            });

            editData.opened.subscribe(function (opened) {
                if (opened && !self.eventsInitialized) {
                    self.bindPreviewButton();
                    self.eventsInitialized = true;
                }
            });

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

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

            /* get preferences */
            preferences.customTone.subscribe(function (customTone) {
                self.customTone(customTone);
            });

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

            preferences.tonesSelected.subscribe(function (tonesSelected) {
                self.selectedTones([]);
                for (let key in tonesSelected) {
                    if (tonesSelected.hasOwnProperty(key)) {
                        self.selectedTones.push(tonesSelected[key]);
                    }
                }
            });

            preferences.stylesSelected.subscribe(function (stylesSelected) {
                self.selectedStyles(stylesSelected);
            });

            preferences.audienceSelected.subscribe(function (audienceSelected) {
                self.selectedAudience([]);
                for (let key in audienceSelected) {
                    if (audienceSelected.hasOwnProperty(key)) {
                        self.selectedAudience.push(audienceSelected[key]);
                    }
                }
            });
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'productId',
                'storeId',
                'pageTitle',
                'pageDescription',
                'productDescription',
                'productShortDescription',
                'openGraph',
                'selectedFields',
                'directiveRegex',
                'descriptionDirectiveExists',
                'shortDescriptionDirectiveExists',
                'selectedStores',
                'guideSteps',
                'customTone',
                'customStyle',
                'selectedTones',
                'selectedStyles',
                'selectedAudience',
                'error',
                'statuses'
            ]);

            this.isNotAllStoreView = ko.computed(function () {
                return parseInt(this.storeId()) !== this.defaultStoreId;
            }, this);

            this.canSave = ko.computed(function () {
                const fieldFunctions = {
                    'page_title': {
                        original: textfields.originalPageTitle,
                        edited: textfields.pageTitle
                    },
                    'page_description': {
                        original: textfields.originalPageDescription,
                        edited: textfields.pageDescription
                    },
                    'product_description': {
                        original: textfields.originalProductDescription,
                        edited: textfields.productDescription
                    },
                    'short_product_description': {
                        original: textfields.originalProductShortDescription,
                        edited: textfields.productShortDescription
                    },
                    'open_graph': {
                        original: textfields.originalOpenGraph,
                        edited: textfields.openGraph
                    }
                },
                    fields = [
                        'page_title',
                        'page_description',
                        'product_description',
                        'short_product_description',
                        'open_graph'
                    ];
                this.updateFields = [];
                var canSaveText = fields.some(function (field) {
                    if (fieldFunctions[field] &&
                                fieldFunctions[field].original() !== fieldFunctions[field].edited() &&
                                fieldFunctions[field].edited() !== ''
                            ) {
                        return true;
                    }
                }),
                    canSaveMedia = gallery.images().some(function (data) {
                        if (data.original_writetext_alt !== data.writetext_alt &&
                            data.writetext_alt !== '') {
                            return true;
                        }
                    });

                fields.forEach(function (item) {
                    if (fieldFunctions[item] &&
                            fieldFunctions[item].original() !== fieldFunctions[item].edited() &&
                            fieldFunctions[item].edited() !== ''
                        ) {
                        this.updateFields.push(item);
                    }
                }, this);

                return canSaveText || canSaveMedia;
            }, this);

            this.canTransfer = ko.computed(function () {
                const fieldFunctions = {
                    'page_title': {
                        generated: this.statuses().pageTitleGenerateStatus
                    },
                    'page_description': {
                        generated: this.statuses().pageDescriptionGenerateStatus
                    },
                    'product_description': {
                        generated: this.statuses().productDescriptionGenerateStatus
                    },
                    'short_product_description': {
                        generated: this.statuses().productShortDescriptionGenerateStatus
                    },
                    'open_graph': {
                        generated: this.statuses().openGraphGenerateStatus
                    }
                };
                var canTransferText = this.selectedFields().some(function (field) {
                    if (fieldFunctions[field] && fieldFunctions[field].generated) {
                        return true;
                    }
                }),
                    canTransferMedia = gallery.images().some(function (data) {
                        return gallery.selectedImages().includes(data.id) && data.writetext_alt !== '';
                    }),
                    isOptimizing = keywordAnalysisData.statuses().find(function (status) {
                        return Number(status.storeId) === Number(self.storeId()) && status.recordId === self.productId() && status.status === 'Running';
                    }),
                    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 (
                    (keywordAnalysisData.refreshingData && keywordAnalysisData.refreshingData()) ||
                    isOptimizing ||
                    (keywordAnalysisOngoing && isProductOptimizing)
                ) {
                    return false;
                }

                return canTransferText || canTransferMedia;
            }, this);

            this.canGenerate = 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 (keywordAnalysisData.refreshingData && keywordAnalysisData.refreshingData()) {
                    return false;
                }

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

                var canGenerateFields = this.selectedFields() ? this.selectedFields().length > 0 : false,
                    canGenerateMedia = gallery.selectedImages() ? gallery.selectedImages().length > 0 : false;

                return canGenerateFields || canGenerateMedia;
            }, this);

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

            this.selectedAiModel = ko.computed(function () {
                return settings.selectedAiModel();
            }, this);

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

            return this;
        },

        /**
         * Initialize AJAX retry handler for _generate function only
         */
        initAjaxRetryHandler: function () {
            /** Listen for admin-idle.js events */
            $(document).on('wtai:user-return', function () {
                console.log('WriteText.ai: User returned, checking for interrupted generation');
                self.checkAndRetryGenerate();
            });
            
            /** Also use Page Visibility API as backup */
            document.addEventListener('visibilitychange', function () {
                if (!document.hidden) {
                    console.log('WriteText.ai: Page became visible');
                    setTimeout(function () {
                        self.checkAndRetryGenerate();
                    }, 500);
                }
            });
            
            /** Handle focus event for additional reliability on tablets */
            window.addEventListener('focus', function () {
                setTimeout(function () {
                    self.checkAndRetryGenerate();
                }, 500);
            });
        },
        
        /**
         * Check for interrupted generate and upload requests and retry
         */
        checkAndRetryGenerate: function () {
            /** Check if we have pending retry data */
            if (self2.pendingRetryData) {
                console.log('WriteText.ai: Retrying interrupted request');
                var retryData = self2.pendingRetryData;
                self2.pendingRetryData = null;
                
                if (retryData.type === 'upload') {
                    /** Check if upload is still needed */
                    if (imageUploadProgressbarModel && imageUploadProgressbarModel.visible()) {
                        console.log('WriteText.ai: Retrying upload from index', retryData.index);
                        self.uploadRequest(
                            retryData.data,
                            retryData.params,
                            retryData.imageChunks,
                            retryData.index,
                            retryData.keywordAnalysis
                        );
                    } else {
                        console.log('WriteText.ai: Upload no longer active, skipping retry');
                    }
                } else {
                    /** Check if generation is still needed */
                    if (signalRModel && signalRModel.generating && signalRModel.generating()) {
                        self._generate(retryData.data, retryData.keyword_analysis ?? false);
                    } else {
                        console.log('WriteText.ai: Generation no longer active, skipping retry');
                    }
                }
            }
            
            /** Check if generate request is stuck */
            if (self2.activeGenerateRequest) {
                var now = Date.now();
                var duration = now - self2.activeGenerateRequest.startTime;
                
                /** If request has been running for more than 60 seconds, retry */
                if (duration > 60000) {
                    console.log('WriteText.ai: Generate request appears stuck, retrying');
                    
                    /** Abort if possible */
                    if (self2.activeGenerateRequest.jqXHR && self2.activeGenerateRequest.jqXHR.abort) {
                        self2.activeGenerateRequest.jqXHR.abort();
                    }
                    
                    /** Store for retry */
                    self2.pendingRetryData = {
                        type: 'generate',
                        url: self2.activeGenerateRequest.url,
                        data: self2.activeGenerateRequest.data
                    };
                    
                    self2.activeGenerateRequest = null;
                    
                    /** Retry */
                    self.checkAndRetryGenerate();
                }
            }
            
            /** Check if upload request is stuck */
            if (self2.activeUploadRequest) {
                var now = Date.now();
                var duration = now - self2.activeUploadRequest.startTime;
                
                /** If request has been running for more than 60 seconds, retry */
                if (duration > 60000) {
                    console.log('WriteText.ai: Upload request appears stuck, retrying');
                    
                    /** Abort if possible */
                    if (self2.activeUploadRequest.jqXHR && self2.activeUploadRequest.jqXHR.abort) {
                        self2.activeUploadRequest.jqXHR.abort();
                    }
                    
                    /** Store for retry */
                    self2.pendingRetryData = {
                        type: 'upload',
                        data: self2.activeUploadRequest.data,
                        params: self2.activeUploadRequest.params,
                        imageChunks: self2.activeUploadRequest.imageChunks,
                        index: self2.activeUploadRequest.index,
                        keywordAnalysis: self2.activeUploadRequest.keywordAnalysis
                    };
                    
                    self2.activeUploadRequest = null;
                    
                    /** Retry */
                    self.checkAndRetryGenerate();
                }
            }
        },

        /**
         * Get selected field values.
         */
        getSelectedFieldValues: function () {
            var fields = [];

            if (self.selectedFields().includes('product_description')) {
                fields.push(textfields.productDescription());
            }

            if (self.selectedFields().includes('short_product_description')) {
                fields.push(textfields.productShortDescription());
            }

            return fields;
        },

        /**
         * Check if checkboxes are valid.
         */
        isCheckboxesValid: function () {
            var tonesSelectedCount = preferences.tonesSelected() ? preferences.tonesSelected().length : 0;

            var selectedAiModel = this.selectedAiModel();

            if (this.useAiModel() && (!selectedAiModel || String(selectedAiModel).trim() === '')) {
                this.error($t('Please select a brand voice.'));
                return false;
            }

            if (this.useAiModel()) {
                return true;
            }


            if (tonesSelectedCount === 0) {
                this.error($t('Please select at least one tone.'));
                return false;
            } else if (
                tonesSelectedCount === 1 &&
                preferences.tonesSelected()[0] === 'custom' &&
                String(preferences.customTone() || '').trim() === ''
            ) {
                this.error($t('Write your specific tone...'));
                return false;
            }

            var selectedStyle = String(preferences.stylesSelected() || '').trim();

            if (!selectedStyle) {
                this.error($t('Please select a style.'));
                return false;
            } else if (
                selectedStyle === 'custom' &&
                String(preferences.customStyle() || '').trim() === ''
            ) {
                this.error($t('Write your specific style...'));
                return false;
            }

            return true;
        },

        /**
         * Check if selected fields has media or directive.
         */
        hasMediaOrDirective: function () {
            var fields = this.getSelectedFieldValues();

            if (fields.length === 0) {
                return false;
            }

            return this.directiveRegex().some(pattern => {
                pattern = new RegExp(pattern, 'si');
                return fields.some(field => {
                    let matches = field.match(pattern);

                    return matches && matches.length;
                });
            });
        },

        /**
         * Generate selected text fields.
         *
         * @param {boolean} rewrite
         * @param {boolean} keywordAnalysis
         *
         * @returns {void}
         */
        generate: function (rewrite = false, keywordAnalysis = false) {
            var selectedFields = self.selectedFields();

            let isAnyFieldModified = false;

            const fieldsToCheck = [
                {
                    field: 'page_title',
                    getter: () =>
                        textfields.originalPageTitle() !==
                        textfields.pageTitle()
            }, {
                field: 'page_description',
                getter: () =>
                    textfields.originalPageDescription() !==
                    textfields.pageDescription()
            }, {
                field: 'product_description',
                getter: () =>
                    textfields.originalProductDescription() !==
                    textfields.productDescription()
            }, {
                field: 'short_product_description',
                getter: () =>
                    textfields.originalProductShortDescription() !==
                    textfields.productShortDescription()
            }, {
                field: 'open_graph',
                getter: () =>
                    textfields.originalOpenGraph() !==
                    textfields.openGraph()
            }
            ];

            for (const field of fieldsToCheck) {
                if (selectedFields.includes(field.field) && field.getter()) {
                    isAnyFieldModified = true;
                    break;
                }
            }

            for (const image of gallery.images()) {
                if (
                    gallery.selectedImages().includes(image.id) &&
                    image.original_writetext_alt !== image.writetext_alt
                ) {
                    isAnyFieldModified = true;
                    break;
                }
            }

            if (isAnyFieldModified) {
                confirm({
                    /* eslint-disable-next-line max-len */
                    content: $t('You have unsaved changes. Are you sure you want to regenerate and replace text?'),
                    buttons: [{
                        text: $t('Cancel'),
                        class: 'action-secondary action-dismiss',
                        click: function (event) {
                            keywordsData.showProgress(false);
                            keywordAnalysisData.isUploading(false);
                            keywordAnalysisData.optimizing(false);
                            this.closeModal(event);
                        }
                    }, {
                        text: $t('Ok'),
                        class: 'action-primary action-accept',
                        click: function (event) {
                            this.closeModal(event, true);
                            self.generateAction(rewrite, keywordAnalysis);
                        }
                    }]
                });
            } else {
                self.generateAction(rewrite, keywordAnalysis);
            }
        },

        /**
         * Generate selected text fields.
         *
         * @param {boolean} rewrite
         * @param {boolean} keywordAnalysis
         *
         * @returns {void}
         */
        generateAction: function (rewrite = false, keywordAnalysis = false) {
            var tones = preferences.tonesSelected(),
                styles = preferences.stylesSelected(),
                audienceSelected = preferences.audienceSelected(),
                storeId = self.storeId(),
                productId = self.productId(),
                descMin = generateSettings.descMin(),
                descMax = generateSettings.descMax(),
                excMin = generateSettings.excMin(),
                excMax = generateSettings.excMax(),
                productAttributes = attributes.productAttributes(),
                productAttributesSelected = generateAttributes.productAttributesSelected(),
                selectedFields = self.selectedFields(),
                selectedImages = gallery.selectedImages(),
                images = gallery.images(),
                customAudience = audience.selectedAudience(),
                keywordAnalysisViews = genkeywordAnalysis.views(),
                keywords = self.keywords(),
                data = {
                    tones: tones,
                    styles: styles,
                    audience: audienceSelected,
                    custom_audience: customAudience,
                    store_id: storeId,
                    product_id: productId,
                    desc_min: descMin,
                    desc_max: descMax,
                    exc_min: excMin,
                    exc_max: excMax,
                    product_attributes: productAttributes,
                    product_attributes_selected: productAttributesSelected,
                    selected_fields: selectedFields,
                    rewrite: rewrite,
                    keyword_analysis_views: keywordAnalysisViews,
                    selected_images: selectedImages,
                    images: images,
                    keywords: keywords,
                    search_intent_selected: keywordsData.searchIntentSelected(),
                    gallery_images: [],
                    templates_used: selectTemplateModel.selectedTemplates,
                    use_ai_model: self.useAiModel(),
                    selected_ai_model: self.selectedAiModel()
            };

            if (keywordAnalysis) {
                data.keyword_analysis = keywordAnalysis;
            }

            /** Check for AI model availability first */
            /* if (this.hasAiModels && this.selectedAiModel() === '') {
                confirm({
                    content: $t('An AI model is available. Do you want to proceed without using it?'),
                    buttons: [{
                        text: $t('Cancel'),
                        class: 'action-secondary action-dismiss',
                        click: function (event) {
                            keywordsData.showProgress(false);
                            keywordAnalysisData.isUploading(false);
                            keywordAnalysisData.optimizing(false);
                            this.closeModal(event);
                        }
                    }, {
                        text: $t('Proceed'),
                        class: 'action-primary action-accept',
                        click: function (event) {
                            this.closeModal(event, true);
                            self.continueGeneration(data, keywordAnalysis, rewrite);
                        }
                    }]
                });
                return;
            } */

            this.continueGeneration(data, keywordAnalysis, rewrite);
        },

        /**
         * Continue generation after AI model confirmation
         *
         * @param {Object} data
         * @param {boolean} keywordAnalysis
         * @param {boolean} rewrite
         */
        continueGeneration: function (data, keywordAnalysis, rewrite) {
            var self = this;
            var otherProductDetailsChecked = generateAttributes.otherProductDetailsChecked(),
                otherProductDetails = generateAttributes.otherProductDetails(),
                additionalPromptValue = additionalPrompt.promptValue(),
                tones = preferences.tonesSelected(),
                styles = preferences.stylesSelected(),
                customTone = preferences.customTone(),
                customStyle = preferences.customStyle(),
                images = gallery.images();

            if (!this.isCheckboxesValid()) {
                keywordsData.showProgress(false);
                keywordAnalysisData.isUploading(false);
                keywordAnalysisData.optimizing(false);
                alert({
                    content: this.error()
                });
                return;
            }

            if (otherProductDetailsChecked) {
                data.other_product_details = otherProductDetails;
            }
            if (additionalPromptValue) {
                data.additional_prompt = additionalPromptValue;
            }
            if (tones.indexOf('custom') !== -1) {
                data.custom_tone = customTone;
            }
            if (styles === 'custom') {
                data.custom_style = customStyle;
            }

            if (rewrite && this.hasMediaOrDirective()) {
                confirm({
                    title: $.mage.__('Rewrite selected'),
                    /* eslint-disable-next-line max-len */
                    content: $.mage.__('Note: Any media or directive you have inserted into the existing text will not be included in the rewritten version. The language of the text you are rewriting will be the same language used in the output.'),
                    actions: {
                        confirm: function () {
                            self._generate(data, keywordAnalysis);
                        },
                        cancel: function () {
                            keywordsData.showProgress(false);
                            keywordAnalysisData.isUploading(false);
                            keywordAnalysisData.optimizing(false);
                            return;
                        }
                    }
                });
            } else {
                var imageSelected = gallery.selectedImages() ? gallery.selectedImages().length > 0 : false;

                var galleryToUpload = false;
                if (images.length > 0 &&
                    (data.selected_fields.includes('product_description') ||
                    data.selected_fields.includes('short_product_description'))
                ) {
                    var allGalleryImageIds = images.map(function (image) {
                        return image.id;
                    });
                    galleryToUpload = allGalleryImageIds.length > 0;
                    if (galleryToUpload) {
                        data.gallery_images = allGalleryImageIds;
                    }
                }

                var thumbnail = data.product_attributes.find(
                    function (attr) {
                        return attr.attribute_code === 'thumbnail';
                    }
                );
                
                var thumbnailSelected = thumbnail && data.product_attributes_selected.includes('thumbnail') ? true : false;

                gallery.failedImages([]);
                gallery.failedImagesWithoutThumbnail([]);
                gallery.successImages([]);
                gallery.invalid([]);
                gallery.notSupported([]);
                gallery.downloadFailed([]);
                gallery.general([]);
                gallery.errorMessages([]);
                if (galleryToUpload || imageSelected || thumbnailSelected || keywordAnalysis) {
                    if (!keywordAnalysis) {
                        imageUploadProgressbarModel.visible(true);
                        imageUploadProgressbarModel.toCancel(false);
                        imageUploadProgressbarModel.progress(0);
                    }
                    self.uploadImages(data, keywordAnalysis);
                } else {
                    self._generate(data);
                }
            }
        },

        /**
         * Upload images
         *
         * @param {Object} data
         * @returns {void}
         */
        uploadImages: function (data, keywordAnalysis = false) {
            var params = {
                store_id: data.store_id,
                product_id: data.product_id,
                selected_images: data.selected_images,
                images: data.images,
                selected_fields: data.selected_fields,
                gallery_images: data.gallery_images
            };

            if (data.selected_fields.length > 0 || keywordAnalysis) {
                params.product_attributes_selected = data.product_attributes_selected;
                params.product_attributes = data.product_attributes;
            }

            errorMessagesModel.messages([]);
            /* gallery.failedImages([]);
            gallery.failedImagesWithoutThumbnail([]); */
            gallery.successImages([]);
            gallery.proceedable(false);
            /** Collect all images first, then split into chunks of 10 */
            var allImages = [];

            if ((params.product_attributes_selected && params.product_attributes_selected.includes('thumbnail')) || keywordAnalysis) {
                var thumbnail = params.product_attributes.find(
                    function (attr) {
                        return attr.attribute_code === 'thumbnail';
                    }
                );
                if (thumbnail) {
                    allImages.push(thumbnail.value);
                }
            }

            if (data.selected_fields.includes('product_description') ||
                data.selected_fields.includes('short_product_description')
            ) {
                if (data.gallery_images.length > 0) {
                    allImages = allImages.concat(data.gallery_images);
                }
            } else {
                if (data.selected_images.length > 0) {
                    allImages = allImages.concat(data.selected_images);
                }
            }

            /** Remove duplicates from collected images */
            allImages = [...new Set(allImages)];
            
            /** Split all collected images into chunks of 10 */
            var imageChunks = [];
            for (var i = 0; i < allImages.length; i += 10) {
                imageChunks.push(allImages.slice(i, i + 10));
            }

            imageUploadProgressbarModel.total(imageChunks.reduce(function (total, chunk) {
                return total + chunk.length;
            }, 0));

            /** Start uploading the first chunk */
            self.uploadRequest(data, params, imageChunks, 0, keywordAnalysis);
        },

        /**
         * Upload images request
         *
         * @param {Object} data
         * @param {Object} params
         * @param {Array} imageChunks
         * @param {Number} index
         * @param {boolean} keywordAnalysis
         *
         * @returns {void}
         */
        uploadRequest: function (data, params, imageChunks, index, keywordAnalysis = false) {
            keywordAnalysisData.imageUploadFailed(false);
            if (keywordAnalysis) {
                keywordAnalysisData.isUploading(true);
            }

            if (imageUploadProgressbarModel.toCancel()) {
                imageUploadProgressbarModel.visible(false);
                return;
            }

            var errorMessages = gallery.errorMessages();
            if (index < imageChunks.length) {
                /** Add images to params */
                /** params.selected_images = imageChunks[index]; */
                params.gallery_images = imageChunks[index];

                /** Track active upload request for retry mechanism */
                self2.activeUploadRequest = {
                    url: self.uploadImagesUrl,
                    data: data,
                    params: params,
                    imageChunks: imageChunks,
                    index: index,
                    keywordAnalysis: keywordAnalysis,
                    startTime: Date.now()
                };

                var ajaxRequest = $.ajax({
                    url: self.uploadImagesUrl,
                    type: 'POST',
                    data: params,
                    dataType: 'json',
                    showWriteTextAILoader: true,
                    showGalleryLoader: true,
                    success: function (response) {
                        /* Clear active upload request */
                        self2.activeUploadRequest = null;
                        
                        if (!response.success) {
                            if (response.unauthorized) {
                                window.location.href = response.login_url;
                            }

                            if (response.failed_images) {
                                gallery.failedImages.push(...response.failed_images);
                                gallery.failedImagesWithoutThumbnail.push(...response.failed_images_without_thumbnail);
                                gallery.successImages.push(...response.success_images);
                                gallery.invalid.push(...response.invalid);
                                gallery.notSupported.push(...response.not_supported);
                                gallery.downloadFailed.push(...response.download_failed);
                                gallery.general.push(...response.general);
                                gallery.errorMessages({...errorMessages, ...response.error_messages});

                                if (response.proceedable || keywordAnalysis) {
                                    gallery.proceedable(true);
                                }
                            } else {
                                if (response.message) {
                                    errorMessagesModel.messages.push(response.message);
                                }
                                imageUploadProgressbarModel.visible(false);
                                return;
                            }
                        } else {
                            imageUploadProgressbarModel.progress(
                                imageChunks
                                    .slice(0, index + 1)
                                    .reduce((total, chunk) => total + chunk.length, 0)
                            );
                        }

                        /** Upload next chunk */
                        self.uploadRequest(data, params, imageChunks, index + 1, keywordAnalysis);
                    },
                    error: function (xhr, status, error) {
                        /* Clear active upload request */
                        self2.activeUploadRequest = null;
                        
                        /* Check if this was due to page being backgrounded */
                        if (status === 'abort' || (xhr && xhr.readyState === 0)) {
                            console.log('WriteText.ai: Upload request interrupted, will retry on page focus');
                            /* Store for retry */
                            self2.pendingRetryData = {
                                type: 'upload',
                                data: data,
                                params: params,
                                imageChunks: imageChunks,
                                index: index,
                                keywordAnalysis: keywordAnalysis
                            };
                        } else {
                            /* Normal error handling */
                            keywordAnalysisData.imageUploadFailed(true);
                            errorMessagesModel.messages.push($t('Image upload failed. Please try again.'));
                        }
                    }
                });
                
                /* Store the jqXHR object for potential abort */
                if (self2.activeUploadRequest) {
                    self2.activeUploadRequest.jqXHR = ajaxRequest;
                }
            } else {
                imageUploadProgressbarModel.visible(false);

                if (gallery.failedImages().length <= 0) {
                    self._generate(data, keywordAnalysis);
                } else {
                    if (keywordAnalysis) {
                        keywordAnalysisData.imageUploadFailed(true);
                    }
                    invalidImagePopupModel.data({});
                    
                    if (gallery.proceedable()) {
                        invalidImagePopupModel.data(data);
                        invalidImagePopupModel.keywordAnalysis(keywordAnalysis);
                        if (data.selected_images.length > 0) {
                            data.selected_images = data.selected_images.filter(function (image) {
                                return gallery.successImages().includes(image);
                            });
                        }
                        data.gallery_images = gallery.successImages();
                        keywordsData.showProgress(false);
                    }

                

                    var isGalleryOnlySelected =
                        Array.isArray(data.selected_images) &&
                        data.selected_images.length > 0 &&
                        (!Array.isArray(data.selected_fields) || data.selected_fields.length === 0);

                    var allInvalidImages =
                        Array.isArray(data.selected_images) &&
                        data.selected_images.length > 0 &&
                        gallery.successImages().length === 0;


                    var suppressPopup = !!invalidImagePopupModel.doNotShowAgain() || !!window.wtaiInvalidImagePopupDoNotShowAgain;

                    if (( isGalleryOnlySelected) && allInvalidImages) {
                        $('.wtai-invalid-image-popup').modal('openModal');
                    } else if (suppressPopup ) {
                        if (keywordAnalysis) {
                            keywordAnalysisData.imageUploadFailed(false);
                        }
                        self._generate(data, keywordAnalysis);
                    } else {
                        $('.wtai-invalid-image-popup').modal('openModal');
                    }
                }

                keywordAnalysisData.customProgressText($t('Preparing for keyword analysis...'));
                keywordAnalysisData.isUploading(false);
            }
        },

        /**
         * Generate selected text fields.
         *
         * @param {Object} data
         * @returns {void}
         */
        _generate: function (data, keywordAnalysis = false) {
            /**clear error */
            $('body').notification('clear');

            var url = self.generateUrl;

            data.failed_images = gallery.failedImages();

            if (keywordAnalysis) {
                keywordsData.showProgress(true);
            }

            /**
            if (data.gallery_images.length > 0) {
                data.selected_images = data.selected_images.filter(function(image) {
                    return data.gallery_images.includes(image);
                });
            }
            */

            /* close dropdown */
            $(self.collapsibleSelector + '.submit').collapsible('deactivate');

            /* do not rewrite empty fields */
            if (data.rewrite) {
                data.selected_fields = generateUtils.removeEmptyFields(
                    data.selected_fields
                );

                if (data.selected_images && data.selected_images.length > 0) {
                    data.selected_images = generateUtils.removeImageWithEmptyAlt(
                        data.selected_images
                    );
                }
            }

            if (keywordAnalysis && generateUtils.checkIfFieldsAndImagesAreEmpty(data)) {
                keywordsData.noGenerateOnAutoGenerateAfterKo(true);
                generateUtils.requestKeywordAnalysis(self.updateOptimizationUrl, 'Product');
                return;
            }

            /* empty text fields */
            generateUtils.clearFields(data.selected_fields, data.selected_images);

            /* remove error messages */
            errorMessagesModel.messages([]);
            
            /** Track active generate request for retry mechanism */
            self2.activeGenerateRequest = {
                url: url,
                data: data,
                startTime: Date.now()
            };

            if (!keywordAnalysis) {
                signalRModel.editTitleStatusText($t('Preparing for text generation...'));
            }
            
            var ajaxRequest = $.ajax({
                url: url,
                type: 'POST',
                data: data,
                dataType: 'json',
                showWriteTextAILoader: true,
                showPageTitleLoader: data.selected_fields.includes('page_title'),
                showPageDescriptionLoader: data.selected_fields.includes('page_description'),
                showProductDescriptionLoader: data.selected_fields.includes('product_description'),
                showShortDescriptionLoader: data.selected_fields.includes('short_product_description'),
                showOpenGraphLoader: data.selected_fields.includes('open_graph'),
                showGalleryLoader: data.selected_images ? data.selected_images.length > 0 : false,
                success: function (response) {
                    /* Clear active request */
                    self2.activeGenerateRequest = null;
                    
                    if (response.success) {
                        markReviewed.reviewed(response.reviewed);
                        genkeywordAnalysis.views(0);
                        if (keywordAnalysis) {
                            keywordAnalysisData.customProgressText($t('Queued for keyword analysis'));
                        }
                    } else {
                        keywordAnalysisData.optimizationFailed(true);
                        keywordAnalysisData.optimizing(false);
                        keywordsData.showProgress(false);
                        self.getGenerated(data.selected_fields, data.selected_images);
                        if (response.message) {
                            errorMessagesModel.messages.push(response.message);
                        }
                        signalRModel.generating(false);
                        generateUtils.removeIdentifierFromCurrentlyGeneratingRecordIdentifiers('Product');

                        if (response.unauthorized) {
                            window.location.href = response.login_url;
                        }
                    }
                },
                error: function (xhr, status, error) {

                    /* Clear active request */
                    self2.activeGenerateRequest = null;
                    
                    /* Check if this was due to page being backgrounded */
                    if (status === 'abort' || (xhr && xhr.readyState === 0)) {
                        console.log('WriteText.ai: Generate request interrupted, will retry on page focus');
                        /* Store for retry */
                        self2.pendingRetryData = {
                            url: url,
                            data: data
                        };
                    } else {
                        /* Normal error handling */
                        errorMessagesModel.messages.push($t('An error occurred while generating content. Please try again.'));
                        signalRModel.generating(false);
                        generateUtils.removeIdentifierFromCurrentlyGeneratingRecordIdentifiers('Product');
                    }
                }
            });
            
            /* Store the jqXHR object for potential abort */
            if (self2.activeGenerateRequest) {
                self2.activeGenerateRequest.jqXHR = ajaxRequest;
            }
        },

        /**
         * Get generated text fields.
         *
         * @param {Array} selectedFields
         * @param {Array} selectedImages
         *
         * @returns {void}
         */
        getGenerated: function (selectedFields, selectedImages) {
            var url = self.getGeneratedUrl,
                productId = self.productId(),
                storeId = self.storeId();

            errorMessagesModel.messages([]);

            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showPageTitleLoader: selectedFields.includes('page_title'),
                showPageDescriptionLoader: selectedFields.includes('page_description'),
                showProductDescriptionLoader: selectedFields.includes('product_description'),
                showShortDescriptionLoader: selectedFields.includes('short_product_description'),
                showOpenGraphLoader: selectedFields.includes('open_graph'),
                showGalleryLoader: selectedImages ? selectedImages.length > 0 : false,
                success: function (response) {
                    if (response.success) {
                        if (selectedFields.includes('page_title')) {
                            textfields.pageTitle(
                                response.textfields.page_title
                            );
                            textfields.originalPageTitle(
                                response.textfields.page_title
                            );
                        }
                        if (selectedFields.includes('page_description')) {
                            textfields.pageDescription(
                                response.textfields.page_description
                            );
                            textfields.originalPageDescription(
                                response.textfields.page_description
                            );
                        }
                        if (selectedFields.includes('product_description')) {
                            textfields.productDescription(
                                response.textfields.product_description
                            );
                            textfields.originalProductDescription(
                                response.textfields.product_description
                            );
                        }
                        if (
                            selectedFields.includes('short_product_description')
                        ) {
                            textfields.productShortDescription(
                                response.textfields.short_product_description
                            );
                            textfields.originalProductShortDescription(
                                response.textfields.short_product_description
                            );
                        }
                        if (selectedFields.includes('open_graph')) {
                            textfields.openGraph(
                                response.textfields.open_graph
                            );
                            textfields.originalOpenGraph(
                                response.textfields.open_graph
                            );
                        }
                    } else {
                        console.log('response.message', response.message);
                        errorMessagesModel.messages.push(response.message);
                    }
                }
            });
        },

        /**
         * Bind preview button.
         */
        bindPreviewButton: function () {
            $(this.previewButtonSelector).on('click', function () {
                var previewUrl = $(this).data('link');

                window.open(previewUrl, '_blank');
            });
        },

        /**
         * Save text to api.
         */
        save: function () {
            var url = self.saveUrl,
                productId = self.productId(),
                storeId = self.storeId(),
                pageTitle = self.pageTitle(),
                pageDescription = self.pageDescription(),
                productDescription = self.productDescription(),
                productShortDescription = self.productShortDescription(),
                openGraph = self.openGraph(),
                selectedFields = self.selectedFields(),
                customTone = self.customTone(),
                customStyle = self.customStyle(),
                selectedTones = self.selectedTones(),
                selectedStyles = self.selectedStyles(),
                selectedAudience = audience.selectedAudience(),
                images = gallery.images();
            var stringImages = JSON.stringify(images);
            errorMessagesModel.messages([]);
            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId,
                    page_title: pageTitle,
                    page_description: pageDescription,
                    product_description: productDescription,
                    product_short_description: productShortDescription,
                    open_graph: openGraph,
                    selected_fields: selectedFields,
                    custom_tone: customTone,
                    custom_style: customStyle,
                    tones: selectedTones,
                    styles: selectedStyles,
                    audience: selectedAudience,
                    images: stringImages,
                    update_fields: self.updateFields
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showPageTitleLoader: true,
                showPageDescriptionLoader: true,
                showProductDescriptionLoader: true,
                showShortDescriptionLoader: true,
                showOpenGraphLoader: true,
                showGalleryLoader: true,
                success: function (response) {
                    if (!response.success) {
                        errorMessagesModel.messages.push(response.message);
                    } else {
                        if (response.params.fields && response.params.fields.length > 0) {
                            markReviewed.reviewed(false);
                        }
                        textfields.originalPageTitle(pageTitle);
                        textfields.originalPageDescription(pageDescription);
                        textfields.originalProductDescription(
                            productDescription
                        );
                        textfields.originalProductShortDescription(
                            productShortDescription
                        );
                        textfields.originalOpenGraph(openGraph);
                        if (response.images) {
                            gallery.images(response.images);
                        }
                        if (response.textfields_statuses && response.textfields_statuses.length > 0) {
                            textfields.statuses({
                                pageTitleGenerateStatus: response.textfields_statuses.page_title_generated,
                                pageDescriptionGenerateStatus: response.textfields_statuses.page_description_generated,
                                productDescriptionGenerateStatus: response.textfields_statuses.product_description_generated,
                                productShortDescriptionGenerateStatus: response.textfields_statuses.short_product_description_generated,
                                openGraphGenerateStatus: response.textfields_statuses.open_graph_generated,
                                pageTitleTransferStatus: response.textfields_statuses.page_title_transferred,
                                pageDescriptionTransferStatus: response.textfields_statuses.page_description_transferred,
                                productDescriptionTransferStatus: response.textfields_statuses.product_description_transferred,
                                productShortDescriptionTransferStatus: response.textfields_statuses.short_product_description_transferred,
                                openGraphTransferStatus: response.textfields_statuses.open_graph_transferred
                            });
                        }
                    }
                }
            });
        },

        /**
         * Transfer text to Magento.
         */
        transfer: function () {
            confirm({
                title: $.mage.__('Transfer selected to Magento'),
                content: self.confirmContent,
                modalClass: 'wtai-modal wtai-bulk-transfer-popup wtai-transfer wtai-edit',
                actions: {
                    confirm: function () {
                        self._transfer();
                    }
                },
                buttons: [{
                    text: $t('Cancel'),
                    class: 'action-secondary action-dismiss',
                    click: function (event) {
                        this.closeModal(event);
                    }
                }, {
                    text: $t('OK'),
                    class: 'action-primary action-accept',
                    click: function (event) {
                        if (
                            $('#wtaiEditTransferForm').data('validator') &&
                            $('#wtaiEditTransferForm').validation() &&
                            $('#wtaiEditTransferForm').validation('isValid')
                        ) {
                            this.closeModal(event, true);
                        }
                    }
                }]
            });
        },

        /**
         * Transfer text to Magento.
         */
        _transfer: function () {
            var url = self.transferUrl,
                productId = self.productId(),
                storeId = self.storeId(),
                pageTitle = self.pageTitle(),
                pageDescription = self.pageDescription(),
                productDescription = self.productDescription(),
                productShortDescription = self.productShortDescription(),
                openGraph = self.openGraph(),
                selectedFields = self.selectedFields(),
                selectedStores = self.selectedStores(),
                selectedImages = gallery.selectedImages(),
                images = gallery.images();

            errorMessagesModel.messages([]);

            signalRModel.editTitleStatusText('Transferring text...');

            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId,
                    page_title: pageTitle,
                    page_description: pageDescription,
                    product_description: productDescription,
                    product_short_description: productShortDescription,
                    open_graph: openGraph,
                    selected_fields: selectedFields,
                    selected_stores: selectedStores,
                    selected_images: selectedImages,
                    images: images
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showPageTitleLoader: selectedFields.includes('page_title'),
                showPageDescriptionLoader: selectedFields.includes('page_description'),
                showProductDescriptionLoader: selectedFields.includes('product_description'),
                showShortDescriptionLoader: selectedFields.includes('short_product_description'),
                showOpenGraphLoader: selectedFields.includes('open_graph'),
                showGalleryLoader: selectedImages.length > 0,
                success: function (response) {
                    var fields = response.fields;
                    
                    if (response.success) {
                        markReviewed.reviewed(response.reviewed);
                        if (response.use_default) {
                            textfields.useDefault({
                                pageTitle: selectedFields.includes('page_title') ?
                                    response.use_default.page_title : textfields.useDefault().pageTitle,
                                pageDescription: selectedFields.includes('page_description') ?
                                    response.use_default.page_description : textfields.useDefault().pageDescription,
                                productDescription: selectedFields.includes('product_description') ?
                                    response.use_default.product_description : textfields.useDefault().productDescription,
                                productShortDescription: selectedFields.includes('short_product_description') ?
                                    response.use_default.short_product_description : textfields.useDefault().productShortDescription,
                                openGraph: selectedFields.includes('open_graph') ?
                                    response.use_default.open_graph : textfields.useDefault().openGraph
                            });
                        }
                        
                        if (selectedStores.map(String).includes(String(storeId))) {
                            textfieldsUtils.updateCurrentFields(fields, selectedFields, {
                                'page_title': pageTitle,
                                'page_description': pageDescription,
                                'product_description': productDescription,
                                'short_product_description': productShortDescription,
                                'open_graph': openGraph
                            });
                            self.descriptionDirectiveExists(
                                response.directives.product_description
                            );
                            self.shortDescriptionDirectiveExists(
                                response.directives.short_product_description
                            );
                            gallery.images(response.images);
                        }
                    } else {
                        errorMessagesModel.messages.push(response.message);
                    }
                        
                    reviewStatus.reviewStatus(response.updatedReview);
                    signalRModel.editTitleStatusText('');
                }
            });
        },

        /**
         * Check if media or directive exists.
         */
        hasMediaOrDirective: function () {
            if (self.selectedFields().includes('product_description')) {
                return self.descriptionDirectiveExists();
            }
            if (self.selectedFields().includes('short_product_description')) {
                return self.shortDescriptionDirectiveExists();
            }
        }
    });
});
