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

define([
    'jquery',
    'ko',
    'underscore',
    'Magento_Ui/js/grid/massactions',
    'WriteTextAI_WriteTextAI/js/modal/confirm',
    'WriteTextAI_WriteTextAI/js/model/grid/notifications',
    'WriteTextAI_WriteTextAI/js/model/grid/error-messages',
    'WriteTextAI_WriteTextAI/js/model/grid/listing',
    'WriteTextAI_WriteTextAI/js/model/total-credits',
    'WriteTextAI_WriteTextAI/js/model/pro-badge',
    'mage/translate',
    'WriteTextAI_WriteTextAI/js/grid/reload',
    'WriteTextAI_WriteTextAI/js/utils/grid/actions',
    'WriteTextAI_WriteTextAI/js/utils/grid/transfer',
    'WriteTextAI_WriteTextAI/js/utils/grid/generate',
    'WriteTextAI_WriteTextAI/js/utils/grid/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/utils/grid/full-automation',
    'WriteTextAI_WriteTextAI/js/model/grid/field-templates',
    'text!WriteTextAI_WriteTextAI/template/modal/bulk-generate.html',
    'text!WriteTextAI_WriteTextAI/template/modal/bulk-keyword-analysis.html',
    'text!WriteTextAI_WriteTextAI/template/modal/bulk-full-automation.html',
    'text!ui/template/modal/modal-popup.html',
    'Magento_Ui/js/modal/alert',
    'uiRegistry',
    'WriteTextAI_WriteTextAI/js/model/grid/ai-models',
    'WriteTextAI_WriteTextAI/js/categories/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/currently-generating',
    'WriteTextAI_WriteTextAI/js/model/grid/bulk-actions',
    'WriteTextAI_WriteTextAI/js/model/grid/reference-products',
    'WriteTextAI_WriteTextAI/js/model/grid/invalid-image-popup',
    'mage/validation',
    'wtaiAdminIdle'
], function (
    $,
    ko,
    _,
    Massactions,
    confirm,
    notifications,
    errorMessagesModel,
    listingModel,
    totalCredits,
    proBadge,
    $t,
    reloadGrid,
    gridUtils,
    transferUtils,
    generateUtils,
    keywordAnalysisUtils,
    fullAutomationUtils,
    fieldTemplatesModel,
    bulkGeneratePopupTmpl,
    bulkKeywordAnalysisPopupTmpl,
    fullAutomationPopupTmpl,
    modalPopupTmpl,
    alert,
    uiRegistry,
    aiModels,
    signalrModel,
    currentlyGeneratingModel,
    bulkActionsData,
    referenceProducts,
    gridInvalidImagePopupModel
) {
    'use strict';

    var self;

    return Massactions.extend({
        defaults: {
            template: 'WriteTextAI_WriteTextAI/categories/grid/actions',
            gridName: 'wtai_categories_grid_listing.wtai_categories_grid_listing_data_source',
            generateFormSelector: '#wtaiBulkGenerateForm',
            transferFormSelector: '#wtaiBulkTransferForm',
            keywordAnalysisFormSelector: '#wtaiBulkKeywordAnalysisForm',
            fullAutomationFormSelector: '#wtaiFullAutomationForm',
            statusRunning: 'Running',
            defaultStoreId: 0,
            currentUser: {},
            initTransfer: false,
            isTransferOngoing: false
        },

        initialize: function () {
            this._super();
            self = this;

            this.currentUser.subscribe(function (currentUser) {
                if (currentUser && Object.keys(currentUser).length !== 0) {
                    listingModel.currentUser(currentUser);
                    gridInvalidImagePopupModel.currentUser(currentUser);
                    transferUtils.continueBulkTransfer(this);
                }
            }, this);

            this.ids.subscribe(function (ids) {
                listingModel.ids(ids);
            }, this);
        },

        initObservable: function () {
            this._super()
                .observe([
                    'currentUser',
                    'ids',
                    'isTransferOngoing'
                ]);

            this.isDisabled = ko.computed(function () {
                var bulkGenerateOngoing = notifications.statuses().some((status) => {
                    var statuses = ['Cancelled', 'Completed', 'Failed'];
                    if ((status.recordType || 'Product') !== 'Category') {
                        return false;
                    }
                    return (
                        !statuses.includes(status.status) &&
                        status.user === this.currentUser().email
                    );
                }, this);

                var disableBulkSelect = bulkActionsData.getDisableBulkSelect('Category')();

                return bulkGenerateOngoing || disableBulkSelect;
            }, this);

            this.isLoading = ko.computed(function () {
                return bulkActionsData.getIsLoading('Category')();
            }, this);

            return this;
        },

        disableAction: function (actionType) {
            var proActions = ['keyword_analysis', 'full_automation'];
            return !totalCredits.hasProAccess() && proActions.includes(actionType);
        },

        showBadge: function (action) {
            return proBadge.showBadge() && action.pro === true;
        },

        applyAction: function (actionIndex) {
            var data = this.getSelections(),
                action,
                callback,
                disabledRowIds = [];
            const maxItems = 5000;
            const minItems = 2;

            if (this.isDisabled() || this.disableAction(actionIndex)) {
                return;
            }

            _.each(data.selected, function (entity_id) {
                if (this.isRowDisabled(entity_id)) {
                    data.selected = _.without(data.selected, entity_id);
                    data.total--;
                    disabledRowIds.push(entity_id);
                }
            }, this);
            bulkActionsData.getDisabledRowIds('Category')(disabledRowIds);

            if (data.total && data.total < minItems) {
                alert({
                    content: $t('Select at least two items to perform a bulk action.')
                });
                return this;
            }

            if (data.total && data.total > maxItems) {
                alert({
                    content: $t('The maximum limit for bulk processing is %s categories.').replace('%s', maxItems)
                });
                return this;
            }

            if (!data.total) {
                alert({
                    content: this.noItemsMsg
                });
                return this;
            }

            action = this.getAction(actionIndex);
            callback = this._getCallback(action, data);

            action.confirm ?
                this._confirm(action, callback) :
                callback();

            return this;
        },

        defaultCallback: function (action, _data) {
            var settings = {};
            var data = JSON.parse(JSON.stringify(_data));

            errorMessagesModel.messages([]);

            try {
                window.localStorage.setItem(
                    bulkActionsData.getDeselectStorageKey('Category'),
                    String(Date.now())
                );
            } catch (e) {
                // no-op
            }

            try {
                switch (action.type) {
                    case 'generate':
                        settings = gridUtils.convertForm($(this.generateFormSelector));
                        settings = this.sanitizeWordLengthSettings(settings);
                        generateUtils.bulkGenerate(this, action, data, settings);
                        break;
                    case 'transfer':
                        settings = gridUtils.convertForm($(this.transferFormSelector));
                        transferUtils.transferable(this, action, data, settings);
                        break;
                    case 'keyword_analysis':
                        settings = gridUtils.convertForm($(this.keywordAnalysisFormSelector));
                        keywordAnalysisUtils.bulkKeywordAnalysis(this, action, data, settings);
                        break;
                    case 'full_automation':
                        settings = gridUtils.convertForm($(this.fullAutomationFormSelector));
                        settings = this.sanitizeWordLengthSettings(settings);
                        fullAutomationUtils.fullAutomation(this, action, data, settings);
                        break;
                    default:
                        this._super(action, data);
                }
            } catch (e) {
                errorMessagesModel.messages.push(window.wtaGeneralErrorMessage);
            }
        },

        /**
         * Remove empty min/max word length fields.
         *
         * When these keys are included with an empty value, backend/API validation may treat them
         * as "required" and return errors (e.g. "Min and max words required").
         *
         * @param {Object} settings
         * @return {Object}
         */
        sanitizeWordLengthSettings: function (settings) {
            if (!settings || typeof settings !== 'object') {
                return settings;
            }

            ['description_min', 'description_max'].forEach(function (key) {
                if (!Object.prototype.hasOwnProperty.call(settings, key)) {
                    return;
                }

                var value = settings[key];
                var isEmpty = value === '' || value === null || value === undefined;
                if (isEmpty) {
                    delete settings[key];
                }
            });

            return settings;
        },

        gridReload: function () {
            var showLoader = false;
            var debounce = true;

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

        _confirm: function (action, callback) {
            const actionType = action.type;
            const confirmData = action.confirm;

            if (!['generate', 'transfer', 'keyword_analysis', 'full_automation'].includes(actionType)) {
                return this._super(action, callback);
            }

            const actionConfig = {
                generate: {
                    buttonText: confirmData.button,
                    modalClass: 'wtai-modal wtai-bulk-generate-popup wtai-confirm',
                    formSelector: this.generateFormSelector,
                    popupTpl: bulkGeneratePopupTmpl
                },
                transfer: {
                    buttonText: $t('Transfer'),
                    modalClass: 'wtai-modal wtai-bulk-transfer-popup wtai-transfer',
                    formSelector: this.transferFormSelector,
                    popupTpl: modalPopupTmpl
                },
                keyword_analysis: {
                    buttonText: $t('Start AI-powered keyword analysis'),
                    modalClass: 'wtai-modal wtai-bulk-keyword-analysis-popup',
                    formSelector: this.keywordAnalysisFormSelector,
                    popupTpl: bulkKeywordAnalysisPopupTmpl
                },
                full_automation: {
                    buttonText: $t('Run full automation'),
                    modalClass: 'wtai-modal wtai-bulk-full-automation-popup wtai-confirm',
                    formSelector: this.fullAutomationFormSelector,
                    popupTpl: fullAutomationPopupTmpl
                }
            };

            const config = actionConfig[actionType];

            confirm({
                creditCostText: $t('How is credit cost calculated?'),
                title: confirmData.title,
                content: confirmData.message,
                modalClass: config.modalClass,
                popupTpl: config.popupTpl,
                actions: {
                    confirm: callback,
                    cancel: () => {
                        $('body').removeClass('_has-modal');
                        reloadGrid.reloadUIComponent(self.gridName, false, true);
                    }
                },
                buttons: [{
                    text: $t('Cancel'),
                    class: 'action-secondary action-dismiss',
                    click: function (event) {
                        this.closeModal(event);
                    }
                }, {
                    text: config.buttonText,
                    class: 'action-primary action-accept',
                    click: function (event) {
                        event.preventDefault();
                        event.stopPropagation();

                        const confirmSelf = this;
                        const $form = $(config.formSelector);

                        const isFormValid = function () {
                            return !!(
                                $form.data('validator') &&
                                $form.validation() &&
                                $form.validation('isValid')
                            );
                        };

                        const proceedWithSubmission = function () {
                            confirmSelf.closeModal(event, true);
                            $('body').removeClass('_has-modal');
                        };

                        const handleTemplateValidation = function () {
                            if (['generate', 'full_automation'].includes(actionType)
                                && !self.checkTemplateSelection(actionType)
                            ) {
                                self.showEmptyTemplateConfirmation(function () {
                                    proceedWithSubmission();
                                });
                                return;
                            }

                            proceedWithSubmission();
                        };

                        if (!isFormValid()) {
                            return;
                        }

                        handleTemplateValidation();
                    }
                }]
            });
        },

        /**
         * Check template selection for required fields (Categories).
         *
         * @param {string} actionType
         * @returns {boolean}
         */
        checkTemplateSelection: function (actionType) {
            var requiredTemplateFields = ['page_title', 'page_description', 'category_description'];
            var fieldEquivalent = {
                'page_title': 'category page title',
                'page_description': 'category page description',
                'category_description': 'category description'
            };

            var selectedFields = [];
            var formSelector = actionType === 'generate' ? '#wtaiBulkGenerateForm' : '#wtaiFullAutomationForm';
            var fieldsCheckboxes = $(formSelector + ' input[name="fields[]"]:checked');
            fieldsCheckboxes.each(function () {
                selectedFields.push($(this).val());
            });

            var hasRequiredField = selectedFields.some(function (field) {
                return requiredTemplateFields.includes(field);
            });

            if (!hasRequiredField) {
                return true;
            }

            if (!fieldTemplatesModel
                || !fieldTemplatesModel.templateSettings
                || Object.keys(fieldTemplatesModel.templateSettings() || {}).length === 0
            ) {
                return true;
            }

            var isThereAvailableTemplateForSelectedFields = false;
            selectedFields.forEach(function (fieldType) {
                if (fieldEquivalent[fieldType]
                    && fieldTemplatesModel.templateSettings()[fieldEquivalent[fieldType]]
                ) {
                    isThereAvailableTemplateForSelectedFields = true;
                }
            });

            if (!isThereAvailableTemplateForSelectedFields) {
                return true;
            }

            var hasTemplateForRequiredFields = false;

            requiredTemplateFields.forEach(function (fieldType) {
                if (selectedFields.includes(fieldType)
                    && fieldEquivalent[fieldType]
                    && fieldTemplatesModel.templateSettings()[fieldEquivalent[fieldType]]
                ) {
                    var templateSelect;
                    if (actionType === 'generate') {
                        templateSelect = $('select[name="wtai_generate_template_' + fieldType.replace(' ', '_') + '"]');
                    } else {
                        templateSelect = $('select[name="wtai_template_' + fieldType.replace(' ', '_') + '"]');
                    }

                    if (templateSelect.length && templateSelect.val()) {
                        hasTemplateForRequiredFields = true;
                    }
                }
            });

            return hasTemplateForRequiredFields;
        },

        /**
         * Show empty template confirmation dialog.
         *
         * @param {Function} callback
         * @returns {void}
         */
        showEmptyTemplateConfirmation: function (callback) {
            $('.wtai-empty-template-confirm').show();

            $('.wtai-empty-template-confirm .action-accept').off('click.emptyTemplate').on('click.emptyTemplate', function (e) {
                e.preventDefault();
                e.stopPropagation();
                $('.wtai-empty-template-confirm').hide();
                if (typeof callback === 'function') {
                    callback();
                }
            });

            $('.wtai-empty-template-confirm .action-back').off('click.emptyTemplate').on('click.emptyTemplate', function (e) {
                e.preventDefault();
                e.stopPropagation();

                var templatesTab = $('.wtai-bulk-generate-popup .item.title a[href="#wtaiTemplatesTab"], .wtai-bulk-full-automation-popup .item.title a[href="#wtaiTemplatesTab"]');
                if (templatesTab.length && !templatesTab.hasClass('switch')) {
                    templatesTab.trigger('click');
                }

                if (templatesTab.length === 0) {
                    $('.wtai-bulk-generate-popup .item.title a, .wtai-bulk-full-automation-popup .item.title a').each(function () {
                        if ($(this).text().toLowerCase().includes('template')) {
                            $(this).trigger('click');
                            return false;
                        }
                    });
                }

                $('.wtai-empty-template-confirm').hide();
            });

            $('.wtai-empty-template-confirm .wtai-empty-template-confirm-overlay').off('click.emptyTemplate').on('click.emptyTemplate', function (e) {
                e.preventDefault();
                e.stopPropagation();
                $('.wtai-empty-template-confirm').hide();
            });
        },

        isRowDisabled: function (entity_id) {
            try {
                var isBulkGenerating = notifications.statuses().some((status) => {
                    if ((status.recordType || 'Product') !== 'Category') {
                        return false;
                    }
                    var isQueued =
                        (status.status === this.statusRunning || status.status === 'Pending') && (
                            status.queuedIds.indexOf(entity_id) !== -1 ||
                            status.runningIds.indexOf(entity_id) !== -1 ||
                            status.completedIds.indexOf(entity_id) !== -1
                        );
                    
                    return isQueued;
                }, this),
                    isBulkCancelling = notifications.statuses().some((status) => {
                        if ((status.recordType || 'Product') !== 'Category') {
                            return false;
                        }
                        return (status.status === 'Cancelling' && (
                                status.queuedIds.indexOf(entity_id) !== -1 ||
                                status.runningIds.indexOf(entity_id) !== -1 ||
                                status.completedIds.indexOf(entity_id) !== -1
                            ));
                    }, this);
                var isOtherUserSingleGenerating = signalrModel.singleGeneratingStatuses().some(function (status) {
                    return status.recordId == entity_id &&
                        status.storeId == referenceProducts.storeId() &&
                        status.generationType == 'Category' &&
                        !status.stop;
                });

                var currentlyGeneratingRecordIdentifiers = currentlyGeneratingModel.recordIdentifiers();
                var categoryIdentifier = 'Category' + '_' + entity_id + '_' + referenceProducts.storeId();
                var isCurrentlyGenerating = currentlyGeneratingRecordIdentifiers.includes(categoryIdentifier);

                var isDisabled = isBulkGenerating || isBulkCancelling || isOtherUserSingleGenerating || isCurrentlyGenerating;

                return isDisabled;
            } catch (error) {
                return false;
            }
        }
    });
});
