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

define([
    'underscore',
    'ko',
    'Magento_Ui/js/grid/listing',
    'WriteTextAI_WriteTextAI/js/model/grid/notifications',
    'WriteTextAI_WriteTextAI/js/grid/reload',
    'WriteTextAI_WriteTextAI/js/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/gallery',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/model/grid/popups/keyword-analysis-progress',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/currently-generating'
], function (
    _,
    ko,
    Listing,
    notifications,
    reloadGrid,
    signalRModel,
    galleryModel,
    keywordAnalysis,
    keywordAnalysisProgressModel,
    product,
    currentlyGeneratingModel
) {
    'use strict';

    return Listing.extend({
        defaults: {
            gridName: 'wtai_products_grid_listing.wtai_products_grid_listing_data_source',
            statusRunning: 'Running',
            statuses: [],
            rowsDisabled: []
        },

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

            this.initObservableRowsDisabled();

            this.statuses(notifications.statuses());

            notifications.statuses.subscribe(function (statuses) {
                this.statuses(statuses);
            }, this);
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe(['statuses']);

            return this;
        },

        /**
         * Defines initial order of child elements.
         *
         * @returns {Listing} Chainable.
         */
        initPositions: function () {
            /**
             * Disable sorting to resolve the issue with the show/hide functionality of the Open Graph text.
             */
            return this;
        },

        /**
         * Initialize observables for disabling of rows.
         */
        initObservableRowsDisabled: function () {
            var observable = ko.getObservable(this, 'rows');

            observable.subscribe(function (rows) {
                _.each(
                    rows,
                    function (row) {
                        this.rowsDisabled[row.entity_id] = ko.observable(false);
                        this.rowsDisabled[row.entity_id].subscribe(
                            function (value) {
                                if (value) {
                                    /* this.gridReload(); */
                                }
                            },
                            this,
                            'beforeChange'
                        );
                    },
                    this
                );
            }, this);
        },

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

            reloadGrid.reloadUIComponent(this.gridName, showLoader, debounce);
        },

        /**
         * Check if row is disabled.
         *
         * @param {Object} row
         * @returns {Boolean}
         */
        isRowDisabled: function (row) {
            return ko.computed(function () {
                try {
                    var isSingleGenerating = signalRModel.generating() && product.productId() === row.entity_id,
                        productsUploading = galleryModel.productsUploading().includes(row.entity_id),
                        isBulkGenerating = this.statuses().some((status) => {
                            var isQueued =
                                (status.status === this.statusRunning || status.status === 'Pending') && (
                                    status.queuedIds.indexOf(row.entity_id) !== -1 ||
                                    status.runningIds.indexOf(row.entity_id) !== -1 ||
                                    status.completedIds.indexOf(row.entity_id) !== -1
                                );

                            this.rowsDisabled[row.entity_id](isQueued);
                            
                            return isQueued;
                        }, this),
                        isBulkCancelling = this.statuses().some((status) => {
                            return (status.status === 'Cancelling' &&  (
                                    status.queuedIds.indexOf(row.entity_id) !== -1 ||
                                    status.runningIds.indexOf(row.entity_id) !== -1 ||
                                    status.completedIds.indexOf(row.entity_id) !== -1
                                ));
                        }, this);
                    var isOtherUserSingleGenerating = signalRModel.singleGeneratingStatuses().some(function (status) {
                        return status.recordId == row.entity_id &&
                               status.storeId == row.store_id &&
                               status.generationType == 'Product' &&
                               !status.stop;
                    });
                    var currentlyGeneratingRecordIdentifiers = currentlyGeneratingModel.recordIdentifiers();
                    var productIdentifier = 'Product' + '_' + row.entity_id + '_' + row.store_id;
                    var isCurrentlyGenerating = currentlyGeneratingRecordIdentifiers.includes(productIdentifier);
                    var isDisabled = isBulkGenerating
                        || isSingleGenerating || productsUploading || isOtherUserSingleGenerating
                        || isBulkCancelling || isCurrentlyGenerating;

                    this.rowsDisabled[row.entity_id](isDisabled);

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

        /**
         * Check if row is optimizing.
         *
         * @param {Object} row
         * @returns {Boolean}
         */
        isRowOptimizing: function (row) {
            return ko.computed(function () {
                try {
                    var status = keywordAnalysis.statuses().find(function (status) {
                        return Number(status.storeId) === Number(row.store_id) &&
                            Number(status.recordId) === Number(row.entity_id) &&
                            status.status === 'Running' &&
                            status.recordType === 'Product';
                    });
                    var isBulkOptimizing = this.statuses().some((status) => {
                        return status.status === this.statusRunning &&
                            status.runningIds.indexOf(row.entity_id) !== -1 &&
                            (status.subType === 2 || status.subType === 1);
                    }, this);

                    return status || isBulkOptimizing;
                } catch (error) {
                    return false;
                }
            }, this);
        }
    });
});
