/**
 * @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/edit/generate/currently-generating',
    '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',
    'WriteTextAI_WriteTextAI/js/model/gallery',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'mage/translate',
    'WriteTextAI_WriteTextAI/js/grid/reload',
    'WriteTextAI_WriteTextAI/js/utils/grid/actions',
    'WriteTextAI_WriteTextAI/js/model/grid/invalid-image-popup',
    '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',
    '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',
    'WriteTextAI_WriteTextAI/js/utils/signalr',
    'text!ui/template/modal/modal-popup.html',
    'Magento_Ui/js/modal/alert',
    'WriteTextAI_WriteTextAI/js/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/grid/bulk-actions',
    'WriteTextAI_WriteTextAI/js/model/grid/reference-products',
    'mage/validation'
], function (
    $,
    ko,
    _,
    Massactions,
    confirm,
    notifications,
    currentlyGeneratingModel,
    errorMessagesModel,
    listingModel,
    totalCredits,
    proBadge,
    galleryModel,
    product,
    $t,
    reloadGrid,
    gridUtils,
    gridInvalidImagePopupModel,
    transferUtils,
    generateUtils,
    keywordAnalysisUtils,
    fullAutomationUtils,
    bulkGeneratePopupTmpl,
    bulkKeywordAnalysisPopupTmpl,
    bulkFullAutomationPopupTmpl,
    signalrUtils,
    modalPopupTmpl,
    alert,
    signalrModel,
    bulkActionsData,
    referenceProducts
) {
    'use strict';

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

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

            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);

            signalrModel.triggerContinueBulkTransfer.subscribe(function (triggerContinueBulkTransfer) {
                if (triggerContinueBulkTransfer && this.initTransfer) {
                    transferUtils.continueBulkTransfer(this);
                }
                this.initTransfer = true;
            }, this);
        },

        /** @inheritdoc */
        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 (signalrUtils.isCancelling(status) && status.user === this.currentUser().email) {
                        return true;
                    }
                    return (
                        !statuses.includes(status.status) &&
                        status.user === this.currentUser().email
                    );
                }, this);
                var disableBulkSelect = bulkActionsData.disableBulkSelect();

                return bulkGenerateOngoing || disableBulkSelect;
            }, this);

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

            return this;
        },

        /**
         * Disable action if user does not have pro access
         *
         * @param {string} actionType - Action type.
         *
         * @returns {boolean}
         */
        disableAction: function (actionType) {
            var proActions = ['keyword_analysis', 'full_automation'];
            return !totalCredits.hasProAccess() && proActions.includes(actionType);
        },

        /**
         * Show badge if user does not have pro access
         *
         * @param {Object} action - Action data.
         *
         * @returns {boolean}
         */
        showBadge: function (action) {
            return proBadge.showBadge() && action.pro === true;
        },

        /** @inheritdoc */
        applyAction: function (actionIndex) {
            var data = this.getSelections(),
                action,
                callback,
                disabledRowIds = [];
            const maxItems = 500;
            
            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.disabledRowIds(disabledRowIds);

            if (data.total && data.total > maxItems) {
                alert({
                    content: $t('The maximum limit for bulk processing is %s products.').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;
        },

        /**
         * Default action callback. Sends selections data
         * via POST request.
         *
         * @param {Object} action - Action data.
         * @param {Object} data - Selections data.
         *
         * @returns {void}
         */
        defaultCallback: function (action, _data) {
            var settings = {};
            var data = JSON.parse(JSON.stringify(_data));

            errorMessagesModel.messages([]);

            try {
                switch (action.type) {
                    case 'generate':
                        settings = gridUtils.convertForm($(this.generateFormSelector));
                        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));
                        fullAutomationUtils.bulkFullAutomation(this, action, data, settings);
                        break;
                    default:
                        this._super(action, data);
                }
            } catch (e) {
                errorMessagesModel.messages.push(window.wtaGeneralErrorMessage);
            }
        },

        /**
         * Bulk full automation
         *
         * @param {Object} self - Self data.
         * @param {Object} action - Action data.
         * @param {Object} data - Selections data.
         * @param {Object} settings - Form settings.
         */
        fullAutomationRequest: function (self, action, data, settings) {
            fullAutomationUtils.bulkGenerateRequest(self, action, data, settings);
        },

        /**
         * Bulk generate
         *
         * @param {Object} self - Self data.
         * @param {Object} action - Action data.
         * @param {Object} data - Selections data.
         * @param {Object} settings - Form settings.
         *
         * @returns {void}
         */
        bulkGenerateRequest: function (self, action, data, settings) {
            generateUtils.bulkGenerateRequest(self, action, data, settings);
        },

        /**
         * Bulk keyword analysis
         *
         * @param {Object} self - Self data.
         * @param {Object} action - Action data.
         * @param {Object} data - Selections data.
         * @param {Object} settings - Form settings.
         *
         * @returns {void}
         */
        bulkKeywordAnalysisRequest: function (self, action, data, settings) {
            keywordAnalysisUtils.bulkKeywordAnalysisRequest(self, action, data, settings);
        },

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

            reloadGrid.reloadUIComponent(
                'wtai_products_grid_listing.wtai_products_grid_listing_data_source',
                showLoader,
                debounce
            );
        },

        /**
         * Shows actions' confirmation window.
         *
         * @param {Object} action - Actions' data.
         * @param {Function} callback - Callback that will be
         *      invoked if action is confirmed.
         *
         * @returns {void}
         */
        _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: bulkFullAutomationPopupTmpl
                }
            };

            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')
                },
                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) {
                        const $form = $(config.formSelector);
                        if ($form.data('validator') &&
                            $form.validation() &&
                            $form.validation('isValid')
                        ) {
                            this.closeModal(event, true);
                            $('body').removeClass('_has-modal');
                        }
                    }
                }]
            });
        },
        /**
         * Check if row is disabled.
         *
         * @param {Object} row
         * @returns {Boolean}
         */
        isRowDisabled: function (entity_id) {
            try {
                var isSingleGenerating = signalrModel.generating() && product.productId() === entity_id,
                    productsUploading = galleryModel.productsUploading().includes(entity_id),
                    isBulkGenerating = notifications.statuses().some((status) => {
                        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) => {
                        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 == 'Product' &&
                            !status.stop;
                });
                var currentlyGeneratingRecordIdentifiers = currentlyGeneratingModel.recordIdentifiers();
                var productIdentifier = 'Product' + '_' + entity_id + '_' + referenceProducts.storeId();
                var isCurrentlyGenerating = currentlyGeneratingRecordIdentifiers.includes(productIdentifier);
                var isDisabled = isBulkGenerating
                    || isSingleGenerating || productsUploading || isOtherUserSingleGenerating
                    || isBulkCancelling || isCurrentlyGenerating;

                return isDisabled;
            } catch (error) {
                console.log(error);
                return false;
            }
        },
    });
});
