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

define([
    'jquery',
    'ko',
    'uiComponent',
    'WriteTextAI_WriteTextAI/js/model/edit',
    'WriteTextAI_WriteTextAI/js/model/edit/feedback',
    'WriteTextAI_WriteTextAI/js/model/history-log',
    'WriteTextAI_WriteTextAI/js/model/edit/audience',
    'WriteTextAI_WriteTextAI/js/model/edit/custom-tone-style',
    'WriteTextAI_WriteTextAI/js/categories/model/edit',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/category',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/textfields',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/representative-products',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'WriteTextAI_WriteTextAI/js/model/edit/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/review-status',
    'WriteTextAI_WriteTextAI/js/model/edit/mark-reviewed',
    'WriteTextAI_WriteTextAI/js/model/edit/error-messages',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keywords',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-pipelines',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/image',
    'WriteTextAI_WriteTextAI/js/grid/reload',
    'WriteTextAI_WriteTextAI/js/categories/edit/representative-products',
    'WriteTextAI_WriteTextAI/js/categories/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/grid/reference-products',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/triggers',
    'WriteTextAI_WriteTextAI/js/model/edit/select-template',
    'WriteTextAI_WriteTextAI/js/model/edit/additional-prompt',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/currently-generating',
    'mage/backend/notification',
    'WriteTextAI_WriteTextAI/js/categories/modal/modal',
    'Magento_Ui/js/modal/modal',
    'accordion'
], function (
    $,
    ko,
    Component,
    productEditData,
    feedback,
    historyLog,
    audience,
    customToneStyle,
    editData,
    category,
    textfields,
    representativeProducts,
    product,
    settings,
    reviewStatus,
    markReviewed,
    errorMessagesModel,
    genKeywordAnalysis,
    keywordsData,
    keywordPipelinesData,
    keywordAnalysisData,
    categoryImageModel,
    reloadGrid,
    representativeProductsComponent,
    signalRModel,
    gridReferenceProducts,
    triggers,
    selectTemplateModel,
    additionalPrompt,
    currentlyGenerating,
    notification
) {
    'use strict';

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

    return Component.extend({
        defaults: {
            modal: null,
            categoryId: '',
            storeId: 0,
            isLoading: false,
            selectors: {
                mainModalSelector: '.wtai-edit-modal.wtai-edit-main',
                keywordsAnalysisModalSelector: '.wtai-edit-modal.wtai-edit-keyword-analysis',
                mainModalClass: 'wtai-edit-modal wtai-edit-main',
                accordionSelector: '.wtai-edit-modal-wrapper .wtai-accordions',
                tooltipSelector:
                    '.wtai-edit-modal-wrapper .admin__field-tooltip-action',
                reviewStatusPopupSelector: '.wtai-review_status-tooltip .tooltip-toggle'
            },
            ajaxRequests: 0,
            pageTitleAjaxRequests: 0,
            pageDescriptionAjaxRequests: 0,
            categoryDescriptionAjaxRequests: 0,
            analysisAjaxRequests: 0,
            audienceAjaxRequests: 0,
            editPipelineAjaxRequests: 0
        },

        gettingData: null,
        isCurrentCategoryChange: false,

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

            self = this;

            this.initModal();

            $(document).on({
                ajaxSend: this._onAjaxSend.bind(this),
                ajaxComplete: this._onAjaxComplete.bind(this),
                ajaxError: this._onAjaxError.bind(this)
            });

            this.storeId.subscribe(function (storeId) {
                if (!this.isCurrentCategoryChange) {
                    let currentCategory = editData.currentCategory();

                    currentCategory.storeId = storeId;
                    editData.currentCategory(currentCategory);
                    product.storeId(storeId);
                }
            }, this);

            this.categoryId.subscribe(function (categoryId) {
                if (!this.isCurrentCategoryChange) {
                    let currentCategory = editData.currentCategory();

                    currentCategory.categoryId = categoryId;
                    editData.currentCategory(currentCategory);
                    product.productId(categoryId);
                }
            }, this);

            editData.currentCategory.subscribe(function (currentCategory) {
                this.isCurrentCategoryChange = true;
                self.categoryId(currentCategory.categoryId);
                self.storeId(currentCategory.storeId);
                this.isCurrentCategoryChange = false;
                
                if (!$(self.selectors.mainModalSelector).hasClass('_show')) {
                    $(self.modalSelector).categoriesModal('openModal');
                }
            }, this);

        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'categoryId',
                'storeId',
                'isLoading'
            ]);

            this.isCurrentlyGenerating = ko.computed(function () {
                var identifier = 'Category' + '_' +  this.categoryId() + '_' + this.storeId();
                var recordIdentifiers = currentlyGenerating.recordIdentifiers();
                if (recordIdentifiers.includes(identifier)) {
                    return true;
                }
                return false;
            }, this);

            return this;
        },

        /**
         * Initialize edit modal.
         */
        initModal: function () {
            var prev = 1,
                next = 1;

            this.modal = $(this.modalSelector).categoriesModal({
                type: 'slide',
                title: 'WriteText.ai',
                modalClass: self.selectors.mainModalClass,
                overlayClass: 'modals-overlay wtai-edit-modal-overlay',
                innerScroll: true,
                buttons: [
                    {
                        class: 'wtai-link-preview action',
                        attr: {
                            title: $.mage.__('View')
                        },
                        click: function () {
                            self.linkPreview(this);
                        }
                }, {
                    class: 'wtai-history-log action',
                    attr: {
                        title: $.mage.__('History log')
                    },
                    click: function () {
                        self.openHistoryLog();
                    }
                }, {
                    text: $.mage.__('Previous'),
                    class: 'action-previous action-default',
                    attr: {
                        'data-prev': prev,
                        'data-bind': 'disable: 1'
                    },
                    click: function () {
                        self.showPrevious();
                    }
                }, {
                    text: $.mage.__('Next'),
                    class: 'action-next action-default',
                    attr: { 'data-next': next },
                    click: function () {
                        self.showNext();
                    }
                }
                ],
                opened: function () {
                    self.afterOpen();
                },
                closed: function () {
                    self.afterClose();
                }
            });

            $(self.selectors.mainModalSelector + ' .page-main-actions .page-actions-buttons')
                .append('<div class="wtai-edit-loading-mask wtai-show"></div>');
        },

        /**
         * Open preview.
         *
         * @param {Object} modal
         * @returns {void}
         */
        linkPreview: function (modal) {
            $.each(modal.buttons, function (index, button) {
                if ($(button).is('.wtai-link-preview')) {
                    let link = $(button).data('link');

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

        /**
         * Open history log modal.
         */
        openHistoryLog: function () {
            $('.wtai-history-log-modal').modal('openModal');
        },

        /**
         * Show previous category.
         *
         * @returns {void}
         */
        showPrevious: function () {
            var prevCategoryId = this.getCategoryByIndex('prev');

            self.resetPage();

            if (prevCategoryId) {
                self.categoryId(prevCategoryId);
                self.getModalData();
            }
        },

        /**
         * Show next category.
         *
         * @returns {void}
         */
        showNext: function () {
            var nextCategoryId = this.getCategoryByIndex('next');

            self.resetPage();

            if (nextCategoryId) {
                self.categoryId(nextCategoryId);
                self.getModalData();
            }
        },

        /**
         * Get category by index.
         *
         * @param {String} type
         * @returns {Boolean|String}
         */
        getCategoryByIndex: function (type) {
            var ids = editData.ids(),
                currentIndex = ids.indexOf(self.categoryId());

            if (!ids || ids.length === 0) {
                return false;
            }

            let offset = (type === 'next') ? 1 : (type === 'prev') ? -1 : 0;
            let category = ids[currentIndex + offset];

            return category || false;
        },

        /**
         * Show preloader
         */
        showPreloader: function () {
            self.isLoading(true);
        },

        /**
         * Hide preloader
         */
        hidePreloader: function () {
            self.isLoading(false);
        },

        /**
         * After open modal.
         */
        afterOpen: function () {
            $('.modal-content').trigger('contentUpdated');

            this.initAccordion();
            this.initTooltip();
            
            productEditData.opened(true);
            editData.opened(true);

            this.ajaxRequests = 0;
            this.pageTitleAjaxRequests = 0;
            this.pageDescriptionAjaxRequests = 0;
            this.categoryDescriptionAjaxRequests = 0;
            this.analysisAjaxRequests = 0;
            this.audienceAjaxRequests = 0;
            this.editPipelineAjaxRequests = 0;

            this.getModalData();

            genKeywordAnalysis.views(0);

            productEditData.initialized(true);
        },

        /**
         * After closing edit modal actions.
         */
        afterClose: function () {
            productEditData.initialized(false); /** IMPORTANT: Make sure to call this first before resetPage for user preference*/
            $('.wtai-edit-modal-overlay').remove();
            self.resetPage();

            /** IMPORTANT: Make sure to call this first before gridReload as grid reload is disabled when edit page is open */
            editData.opened(false);
            productEditData.opened(false);
            self.gridReload();

            self.showPreloader();
            signalRModel.showMessage(false);
        },

        /**
         * Reset edit modal.
         */
        resetPage: function () {
            var data = {
                texts: {
                    page_title: '',
                    page_description: '',
                    category_description: ''
                },
                generated_texts: {
                    page_title: '',
                    page_description: '',
                    category_description: ''
                }
            };

            $(self.selectors.mainModalSelector + ' .wtai-category-name').html('');

            self.updateTextFields(data);

            historyLog.recordId(null);
            historyLog.storeId(gridReferenceProducts.storeId());
            historyLog.update(false);
            markReviewed.reviewed(false);
            product.storeScope('');
            representativeProductsComponent.prototype.resetValue();
            representativeProductsComponent.prototype.resetSearch();
            keywordsData.showProgress(false);
        },

        /**
         * Reload grid.
         */
        gridReload: function () {
            var showLoader = false;
            var debounce = true;

            reloadGrid.reloadUIComponent(
                'wtai_categories_grid_listing.wtai_categories_grid_listing_data_source',
                showLoader,
                debounce
            );
        },

        /**
         * Clear messages.
         */
        clearMessages: function () {
            $('body').notification('clear');
            $('body').find('div[data-role="messages"]').parent().remove();
        },

        /**
         * Get modal data.
         */
        getModalData: function () {
            self.showPreloader();
            self.clearMessages();

            /** Placed here to remove optimization failed on edit close while keeping the grid progress */
            var statuses = keywordAnalysisData.statuses();
            keywordAnalysisData.statuses(statuses.filter(function (status) {
                return Number(status.storeId) !== Number(self.storeId()) || status.recordId !== self.categoryId();
            }));
        
            errorMessagesModel.messages([]);

            historyLog.update(false);

            if (self.gettingData !== null) {
                self.gettingData.abort();
            }

            self.gettingData = $.ajax({
                url: self.editUrl,
                dataType: 'json',
                data: {
                    form_key: window.FORM_KEY,
                    category_id: self.categoryId(),
                    store_id: self.storeId()
                },
                showWriteTextAILoader: true,
                hideWriteTextTitleLoader: true,
                success: function (response) {
                    if (response.success) {
                        self.updateModal(response);
                    } else {
                        errorMessagesModel.messages.push(response.message);
                    }
                    
                    self.hidePreloader();
                },
                error: function (xhr, status, error) {
                    if (status !== 'abort') {
                        errorMessagesModel.messages.push(error);
                    }
                }
            });
        },

        /**
         * Update modal.
         *
         * @param {Object} data
         */
        updateModal: function (data) {
            $(self.selectors.mainModalSelector + ' .wtai-category-name').html(
                data.name
            );

            self.updateCategory(data);
            self.updateButtons(data);
            self.updateTextFields(data);
            self.updateTextfieldsStatuses(data);
            self.updateKeywordsUsed(data);
            self.updateUseDefault(data);
            self.updatePronouns(data);
            self.updateKeywordAnalysis(data); /** IMPORTANT: Make sure to update analysis first before keywords for checking of thumbnail */
            self.updateRepresentativeProducts(data);
            self.updateAdditionalPrompt(data);
            self.updateHistoryLog(data);
            self.updateMarkReviewed(data);
            self.updateAudience(data);
            self.updateCustomToneStyle(data);
            self.updateSelectedFields(data); /** IMPORTANT: Make sure to update selected fields first before keywords for checking of auto generate after KO */
            self.updateKeywords(data);
            self.updateSettings(data);
            self.updateReviewStatus(data);
            self.updateFeedbacks(data);
            self.updateTemplatesUsed(data);
            self.bindStoreSwitcher();

            $('.wtai-edit-modal-wrapper').trigger('contentUpdated');
        },

        /**
         * Bind store switcher.
         */
        bindStoreSwitcher: function () {
            $('.wtai-store-scope li a').on('click', function () {
                self.resetPage();
                self.storeId($(this).data('value'));
                self.getModalData();
                $('.wtai-store-scope .dropdown').collapsible(
                    'deactivate'
                );
            });
        },

        /**
         * Update keywords analysis.
         */
        updateKeywordAnalysis: function (data) {
            keywordPipelinesData.forceResetEditPipeline(false); /** set to false first to trigger change*/
            keywordPipelinesData.forceResetEditPipeline(true);
            keywordPipelinesData.editKeywordRankingVisible(false);
            keywordPipelinesData.editKeywordRankingVisible.valueHasMutated();
            var optimizationData = data.optimization || {};
            keywordAnalysisData.optimizationData(optimizationData);
            keywordAnalysisData.snapshotData(optimizationData.snapshots || {});

            var isRefreshOngoing = optimizationData.refreshStatus === 'InProgress';
            keywordAnalysisData.refreshingData(isRefreshOngoing);

            triggers.defaultTriggers(data.global_triggers);
        },

        /**
         * Update feedbacks.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateFeedbacks: function (data) {
            feedback.feedbacks(data.feedback);
        },

        /**
         * Update product.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateCategory: function (data) {
            category.categoryName(data.name);
            category.image(data.image);
            category.breadcrumbs(data.breadcrumbs);
            categoryImageModel.useDefault(data.use_default_image);
            categoryImageModel.categoryImageSelected(JSON.parse(data.category_image_selected));

            /**
             * Reuse product model for some components
             */
            product.productId(self.categoryId());
            product.storeId(self.storeId());
            product.productName($($.parseHTML(data.name)).text());
            product.productUrl(data.link_preview_url);
            product.language(data.language.toLowerCase());
            product.stores(data.stores);
            product.storeScope(data.store_scope);
        },

        /**
         * Update custom tone and style.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateCustomToneStyle: function (data) {
            customToneStyle.customTone(data.custom_tone);
            customToneStyle.customStyle(data.custom_style);
        },
        
        /**
         * Update selected fields.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateSelectedFields: function (data) {
            textfields.selectedFields([]);
            for (let key in data.selected_fields) {
                if (data.selected_fields.hasOwnProperty(key)) {
                    textfields.selectedFields.push(data.selected_fields[key]);
                }
            }
        },

        /**
         * Update mark reviewed.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateMarkReviewed: function (data) {
            markReviewed.reviewed(data.reviewed);
        },

        /**
         * Update review status.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateReviewStatus: function (data) {
            reviewStatus.reviewStatus(data.review_status);
        },

        /**
         * Update pronouns.
         *
         * @param {Object} data
         * @returns {void}
         */
        updatePronouns: function (data) {
            textfields.highlightPronouns(
                JSON.parse(data.highlight_pronouns.toLowerCase())
            );
        },

        /**
         * Update keywords.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateKeywords: function (data) {
            keywordsData.searchIntentSelected(data.search_intent_selected);
            keywordsData.language(data.language);
            keywordsData.country(data.country);
            keywordsData.location(data.location);
            keywordsData.selectedKeywords(data.selected_keywords);
            keywordsData.thumbnail(data.image);
            if (data.category_placeholder_image) {
                keywordsData.categoryPlaceholderImage(data.category_placeholder_image);
            }
            keywordsData.thumbnailId(data.image_id);
            keywordsData.apiThumbnail(data.api_thumbnail);
            keywordsData.autoGenerateRewriteAfterKo(data.auto_generate_after_ko);
        },

        /**
         * Update representative products.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateRepresentativeProducts: function (data) {
            representativeProducts.representativeProducts(data.representative_products.options);
            representativeProducts.totalSize(data.representative_products.total);
            representativeProducts.selected(data.representative_products.selected);
            representativeProducts.otherDetails(data.representative_products.other_details);
            representativeProducts.otherDetailsChecked(data.representative_products.other_details_checked);
            representativeProducts.productResearchData(data.representative_products.product_research_data);
        },

        /**
         * Update additional prompt.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateAdditionalPrompt: function (data) {
            additionalPrompt.promptValue(data.additional_prompt);
        },
        
        /**
         * Update settings.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateSettings: function (data) {
            /**
             * IMPORTANT: Always updates styles first before tones
             * to prioritize in redering
             */
            settings.disallowedCombinations(data.disallowed_combinations);
            settings.styles(data.styles);
            settings.tones(data.tones);
            settings.audience(data.audience);
            settings.descMin(data.desc_min);
            settings.descMax(data.desc_max);
            settings.formalLanguageSupport(data.formal_language_support);
            settings.formalLanguages(data.formal_languages);
            settings.guideSteps(data.guide_steps);
        },

        /**
         * Update use default data.
         *
         * @param {*} data
         * @returns {void}
         */
        updateUseDefault: function (data) {
            textfields.useDefault({
                pageTitle: data.use_default.page_title,
                pageDescription: data.use_default.page_description,
                categoryDescription: data.use_default.category_description
            });
        },

        /**
         * Update buttons.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateButtons: function (data) {
            /**
             * next
             */
            if (this.getCategoryByIndex('next')) {
                $(this.selectors.mainModalSelector + ' .action-next').prop(
                    'disabled',
                    false
                );
            } else {
                $(this.selectors.mainModalSelector + ' .action-next').prop(
                    'disabled',
                    true
                );
            }

            /**
             * prev
             */
            if (this.getCategoryByIndex('prev')) {
                $(this.selectors.mainModalSelector + ' .action-previous').prop(
                    'disabled',
                    false
                );
            } else {
                $(this.selectors.mainModalSelector + ' .action-previous').prop(
                    'disabled',
                    true
                );
            }

            /**
             * link preview
             */
            $(this.selectors.mainModalSelector + ' .wtai-link-preview').data(
                'link',
                data.link_preview_url
            );

            /**
             * preview changes
             */
            $(this.selectors.mainModalSelector + ' .wtai-preview-button').data(
                'link',
                data.preview_changes_url
            );

            /**
             * keywords analysis
             */
            $(this.selectors.keywordsAnalysisModalSelector + ' .wtai-link-preview').data(
                'link',
                data.link_preview_url
            );

            /**
             * Toggle preview visibility
             */
            if (data.is_active) {
                $(this.selectors.mainModalSelector + ' .wtai-link-preview').removeClass('wtai-no-display');
                $(this.selectors.mainModalSelector + ' .wtai-preview-button').removeClass('wtai-no-display');
                $(this.selectors.mainModalSelector + ' .wtai-preview-button + .wtai-tooltip-wrapper').removeClass('wtai-no-display');
            } else {
                $(this.selectors.mainModalSelector + ' .wtai-link-preview').addClass('wtai-no-display');
                $(this.selectors.mainModalSelector + ' .wtai-preview-button').addClass('wtai-no-display');
                $(this.selectors.mainModalSelector + ' .wtai-preview-button + .wtai-tooltip-wrapper').addClass('wtai-no-display');
            }
        },

        /**
         * Update text fields.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateTextFields: function (data) {
            textfields.mgPageTitle(data.texts.page_title);
            textfields.mgPageDescription(data.texts.page_description);
            textfields.mgCategoryDescription(data.texts.category_description);
            textfields.pageTitle(data.generated_texts.page_title);
            textfields.pageDescription(data.generated_texts.page_description);
            textfields.categoryDescription(data.generated_texts.category_description);
            textfields.originalPageTitle(data.generated_texts.page_title);
            textfields.originalPageDescription(data.generated_texts.page_description);
            textfields.originalCategoryDescription(data.generated_texts.category_description);
        },

        /**
         * Update templates used.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateTemplatesUsed: function (data) {
            selectTemplateModel.selectedTemplates.category_page_title(data.templates_used.page_title);
            selectTemplateModel.selectedTemplates.category_description(data.templates_used.category_description);
        },

        /**
         * Update textfields statuses.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateTextfieldsStatuses: function (data) {
            textfields.statuses({
                pageTitleGenerateStatus: data.textfields_statuses.page_title_generated,
                pageDescriptionGenerateStatus: data.textfields_statuses.page_description_generated,
                categoryDescriptionGenerateStatus: data.textfields_statuses.category_description_generated,
                pageTitleTransferStatus: data.textfields_statuses.page_title_transferred,
                pageDescriptionTransferStatus: data.textfields_statuses.page_description_transferred,
                categoryDescriptionTransferStatus: data.textfields_statuses.category_description_transferred
            });
        },

        /**
         * Update keywords used.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateKeywordsUsed: function (data) {
            textfields.keywordsUsed({
                pageTitle: data.keywords_used.page_title,
                pageDescription: data.keywords_used.page_description,
                categoryDescription: data.keywords_used.category_description
            });
        },

        /**
         * Update history log.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateHistoryLog: function (data) {
            historyLog.recordId(self.categoryId());
            historyLog.storeId(self.storeId());
            historyLog.users([]);

            for (let key in data.users) {
                if (data.users.hasOwnProperty(key)) {
                    historyLog.users.push(data.users[key]);
                }
            }
        },

        /**
         * Update audience.
         *
         * @param {Object} data
         * @returns {void}
         */
        updateAudience: function (data) {
            audience.selectedAudience(data.selected_audience.shift());
            audience.suggestedAudience(data.suggested_audience);
        },

        /**
         * Initialize edit modal accordions.
         */
        initAccordion: function () {
            $(self.selectors.accordionSelector).each(function () {
                var active = [],
                    activeValues = {
                        'wtai-keywords-attributes': [0, 1, 2, 3],
                        'wtai-fieldset': [0, 1, 2]
                },
                    elementClasses = $(this).attr('class').split(/\s+/);
                    
                $.each(elementClasses, function (index, className) {
                    if (activeValues.hasOwnProperty(className)) {
                        active = activeValues[className];
                    }
                });

                $(this).accordion({
                    active: active,
                    collapsible: true,
                    openedState: '_show',
                    closedState: '_hide',
                    multipleCollapsible: true
                });
            });
        },

        /**
         * Initialize edit modal tooltips.
         */
        initTooltip: function () {
            $(this.selectors.tooltipSelector).dropdown({
                parent: '.admin__field-tooltip',
                autoclose: true
            });
            $(this.selectors.reviewStatusPopupSelector).dropdown({
                parent: '.wtai-review_status-tooltip',
                autoclose: true
            });
        },

        /**
         * Show field loader
         *
         * @param {String} field
         * @returns {void}
         */
        showFieldLoader: function (field) {
            $('.wtai-' + field + '-loading-mask').addClass('wtai-show');
        },

        /**
         * Hide field loader
         *
         * @param {String} field
         * @returns {void}
         */
        hideFieldLoader: function (field) {
            $('.wtai-' + field + '-loading-mask').removeClass('wtai-show');
        },

        /**
         * Show loader
         *
         * @param {Boolean} loadTitle
         * @returns {void}
         */
        showLoader: function (loadTitle = true) {
            $('.wtai-edit-loading-mask').addClass('wtai-show');
            if (loadTitle) {
                $('.wtai-edit-modal .modal-title').addClass('wtai-loading');
            }
        },

        /**
         * hide loader
         */
        hideLoader: function () {
            if (this.isCurrentlyGenerating()) {
                return;
            }
            $('.wtai-edit-modal .modal-title').removeClass('wtai-loading');
            $('.wtai-edit-loading-mask').removeClass('wtai-show');
        },

        /**
         * On ajax send.
         *
         * @param {Object} event
         * @param {Object} xhr
         * @param {Object} config
         *
         * @returns {void}
         */
        _onAjaxSend: function (event, xhr, config) {
            if (this.modal && config && config.showWriteTextAILoader) {
                this.showLoader(!config.hideWriteTextTitleLoader);
                this.ajaxRequests++;

                if (config.showPageTitleLoader) {
                    self.showFieldLoader('page-title');
                    this.pageTitleAjaxRequests++;
                }
                if (config.showPageDescriptionLoader) {
                    self.showFieldLoader('page-description');
                    this.pageDescriptionAjaxRequests++;
                }
                if (config.showCategoryDescriptionLoader) {
                    self.showFieldLoader('category-description');
                    this.categoryDescriptionAjaxRequests++;
                }
                if (config.showAnalysisLoader) {
                    self.showFieldLoader('analysis');
                    this.analysisAjaxRequests++;
                }
                if (config.showAudienceLoader) {
                    self.showFieldLoader('audience');
                    this.audienceAjaxRequests++;
                }
                if (config.showEditPipelineLoader) {
                    self.showFieldLoader('edit-pipeline');
                    this.editPipelineAjaxRequests++;
                }
            }
        },

        /**
         * On ajax complete.
         *
         * @param {Object} event
         * @param {Object} xhr
         * @param {Object} config
         *
         * @returns {void}
         */
        _onAjaxComplete: function (event, xhr, config) {
            this._handleAjaxCompletion(config);
        },

        /**
         * Handle AJAX request completion (shared logic for complete/error)
         *
         * @param {Object} config
         */
        _handleAjaxCompletion: function (config) {
            if (!this.modal || !config || !config.showWriteTextAILoader) {
                return;
            }

            /** Decrement main counter */
            if (this.ajaxRequests > 0) {
                this.ajaxRequests--;
            }

            setTimeout(function () {
                if (self.ajaxRequests === 0) {
                    self.hideLoader();
                }
            }, 200);

            /** Field-specific loaders configuration */
            var loaderConfigs = [
                {flag: 'showPageTitleLoader', counter: 'pageTitleAjaxRequests', field: 'page-title'},
                {flag: 'showPageDescriptionLoader', counter: 'pageDescriptionAjaxRequests', field: 'page-description'},
                {flag: 'showCategoryDescriptionLoader', counter: 'categoryDescriptionAjaxRequests', field: 'category-description'},
                {flag: 'showAnalysisLoader', counter: 'analysisAjaxRequests', field: 'analysis'},
                {flag: 'showAudienceLoader', counter: 'audienceAjaxRequests', field: 'audience'},
                {flag: 'showEditPipelineLoader', counter: 'editPipelineAjaxRequests', field: 'edit-pipeline'}
            ];

            /** Process each loader configuration */
            loaderConfigs.forEach(function(loaderConfig) {
                if (config[loaderConfig.flag] && self[loaderConfig.counter] > 0) {
                    self[loaderConfig.counter]--;
                }
                if (config[loaderConfig.flag] && self[loaderConfig.counter] === 0) {
                    self.hideFieldLoader(loaderConfig.field);
                }
            });
        },

        /**
         * Handle AJAX errors (including aborted requests)
         *
         * @param {Object} event
         * @param {Object} xhr
         * @param {Object} config
         */
        _onAjaxError: function (event, xhr, config) {
            this._handleAjaxCompletion(config);
        }
    });
});
