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

define([
    'jquery',
    'underscore',
    'WriteTextAI_WriteTextAI/js/model/grid/listing',
    'WriteTextAI_WriteTextAI/js/model/grid/error-messages',
    'WriteTextAI_WriteTextAI/js/model/grid/transfer',
    'WriteTextAI_WriteTextAI/js/model/grid/notifications',
    'WriteTextAI_WriteTextAI/js/utils/grid/actions'
], function (
    $,
    _,
    listingModel,
    errorMessagesModel,
    transfer,
    notifications,
    actionsUtils
) {
    'use strict';
    
    /**
     * Check if transferable
     *
     * @param {Object} self - Self data.
     * @param {Object} action - Action data.
     * @param {Object} data - Selections data.
     * @param {Object} settings - Form settings.
     *
     * @returns {void}
     */
    function transferable(self, action, data, settings)
    {
        var selections = actionsUtils.processSelections(data, settings, self.defaultStoreId);
        notifications.addNewTransferStatus(
            data.selected,
            listingModel.currentUser(),
            data
        );
        notifications.opened(true);
        notifications.currentBulkRequestId(notifications.transferTempId);
        if (data.selected.length > 1) {
            /*$.ajax({
                url: self.transferableUrl,
                type: 'POST',
                data: selections,
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        errorMessagesModel.messages.push(response.message);
                        notifications.statuses.remove(function (status) {
                            return status.id === notifications.transferTempId;
                        });
                        if (response.unauthorized) {
                            window.location.href = response.login_url;
                        }
                        if (response.reload) {
                            self.gridReload();
                        }
                    } else {
                        transfer.queueIds(data.selected);
                        transfer.completedIds([]);
                        transfer.cancelBulkTransfer(false);
                        transferViaApi(self, data, settings);
                    }
                }
            });*/
            
            
            transfer.queueIds(data.selected);
            transfer.completedIds([]);
            transfer.cancelBulkTransfer(false);
            actionsUtils.pingApi(self, data, settings, transferViaApi, removeNotification);
        } else {
            $.ajax({
                url: self.transferableUrl,
                type: 'POST',
                data: selections,
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        errorMessagesModel.messages.push(response.message);
                        notifications.statuses.remove(function (status) {
                            return status.id === notifications.transferTempId;
                        });
                        if (response.unauthorized) {
                            window.location.href = response.login_url;
                        }
                        if (response.reload) {
                            self.gridReload();
                        }
                    } else {
                        transfer.queueIds(data.selected);
                        transfer.completedIds([]);
                        transfer.cancelBulkTransfer(false);
                        /*saveBulkTransferProgress(self, data, settings); */
                        bulkTransfer(self, action, data, settings, 0);
                    }
                }
            });
        }
        
    }

    /**
     * Bulk transfer request
     *
     * @param {Object} self - Self data.
     * @param {Object} action - Action data.
     * @param {Object} origData - Selections data.
     * @param {Object} settings - Form settings.
     * @param {Number} index - Index of the current batch (incremented by 3).
     *
     * @returns {void}
     */
    function bulkTransfer(self, action, origData, settings, index)
    {
        const data = {...origData};
        const BATCH_SIZE = 10;

        /*Create proper copy of selected IDs to prevent mutation */
        const originalSelectedIds = [...data.selected];
        
        /*Deep freeze to prevent any mutations */
        const frozenSelectedIds = Object.freeze([...originalSelectedIds]);

        /*Check if we have products to process by checking current queue state */
        let currentQueueIds = transfer.queueIds();
        let hasProductsToProcess = currentQueueIds.length > 0;
        
        /*For first request (index === 0), initialize with all selected products */
        if (index === 0) {
            transfer.queueIds(frozenSelectedIds);
            transfer.completedIds([]);
            currentQueueIds = frozenSelectedIds;
            hasProductsToProcess = true;
        }
        
        if (hasProductsToProcess) {
            var previousRemainingCount = currentQueueIds.length;

            /*Create a completely isolated copy of data to prevent processSelections from modifying original */
            var isolatedData = {
                ...data,
                selected: frozenSelectedIds
            };
            var proccessedSelections = actionsUtils.processSelections(isolatedData, settings, self.defaultStoreId);
            var selections = {...proccessedSelections};
            
            /*Apply BATCH_SIZE logic for frontend batching */
            let batchToProcess;
            if (index === 0) {
                /*First batch - take first BATCH_SIZE products */
                batchToProcess = frozenSelectedIds.slice(0, BATCH_SIZE);
            } else {
                /*Use current queue state to determine next batch */
                batchToProcess = currentQueueIds.slice(0, BATCH_SIZE);
            }

            if (!Array.isArray(batchToProcess) || batchToProcess.length === 0) {
                self.isTransferOngoing(false);
                notifications.currentBulkRequestId(null);
                self.gridReload();
                return;
            }
            
            /*Send the current batch and all selected for context */
            selections.selected = batchToProcess;
            selections.all_selected = frozenSelectedIds; /*Send all selected IDs for context */
            selections.batch_size = BATCH_SIZE; /*Let backend know the batch size */
            self.isTransferOngoing(true);
            $.ajax({
                url: self.bulkTransferUrl,
                type: 'POST',
                data: selections,
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        if (response.unauthorized) {
                            window.location.href = response.login_url;
                        }
                        if (response.reload) {
                            self.gridReload();
                        }
                        return;
                    }

                    if (transfer.cancelBulkTransfer() === false) {
                        /*Update progress tracking from response data */
                        if (response.remaining !== undefined && response.processed !== undefined) {
                            /*Calculate progress based on totals */
                            let totalProducts = frozenSelectedIds.length;
                            let completedCount = totalProducts - response.remaining;
                            let remainingCount = response.remaining;
                            
                            /*For notification purposes, create arrays based on counts */
                            let completedIds = frozenSelectedIds.slice(0, completedCount);
                            let queueIds = frozenSelectedIds.slice(completedCount);
                            
                            transfer.completedIds(completedIds);
                            transfer.queueIds(queueIds);
                            
                            /*Update notifications with progress */
                            /*notifications.updateTransferStatus( */
                            /*    originalSelectedIds, */
                            /*    listingModel.currentUser().email, */
                            /*    queueIds, */
                            /*    completedIds */
                            /*); */
                        }

                        /**
                         * Safety guard: if backend reports no progress, stop recursion to avoid infinite polling.
                         */
                        try {
                            var nextRemainingCount = transfer.queueIds().length;
                            if (response.completed !== true && nextRemainingCount >= previousRemainingCount) {
                                self.isTransferOngoing(false);
                                notifications.currentBulkRequestId(null);
                                transfer.cancelBulkTransfer(true);
                                self.gridReload();
                                return;
                            }
                        } catch (e) {
                            // no-op
                        }
                        
                        /*Check if all products are completed */
                        if (response.completed === true) {
                            self.isTransferOngoing(false);
                            notifications.currentBulkRequestId(null);
                            /*All products processed, reload grid */
                            self.gridReload();
                        } else {
                            /*Continue processing next batch */
                            setTimeout(function () {
                                /*Increment index by BATCH_SIZE to move to next batch */
                                bulkTransfer(self, action, data, settings, index + BATCH_SIZE);
                            }, 500); /*Small delay to prevent overwhelming the server */
                        }
                    } else {
                        /*Transfer was cancelled */
                        /*saveBulkTransferProgress(self, data, settings, true); */
                    }
                },
                error: function (xhr, status, error) {
                    self.isTransferOngoing(false);
                    notifications.currentBulkRequestId(null);
                    if (status !== 'abort') {
                        errorMessagesModel.messages.push(error);
                    }
                }
            });
        } else {
            self.gridReload();
        }
    }

    /**
     * Save bulk transfer progress
     *
     * @param {Object} self - Self data.
     * @param {Object} data - Selections data.
     * @param {Object} settings - Form settings.
     * @param {Boolean} isCancel - Is cancel.
     *
     * @returns {void}
     */
    function saveBulkTransferProgress(self, data, settings, isCancel = false)
    {
        $.ajax({
            url: self.saveTransferProgressUrl,
            type: 'POST',
            data: {
                is_cancel: isCancel,
                queue_ids: transfer.queueIds(),
                completed_ids: transfer.completedIds(),
                store_id: data.params.filters['store_id'] ?? self.defaultStoreId,
                stores: settings.stores,
                fields: settings.fields,
                user: listingModel.currentUser().email
            },
            dataType: 'json',
            showLoader: false,
            success: function (response) {
                if (!response.success) {
                    console.log(response.message);
                }
            }
        });
    }

    /**
     * Save bulk transfer progress
     *
     * @param {Object} self - Self data.
     * @param {Object} data - Selections data.
     * @param {Object} settings - Form settings.
     * @param {Boolean} isCancel - Is cancel.
     *
     * @returns {void}
     */
    function transferViaApi(self, data, settings, isCancel = false)
    {
        var transferData = {
            is_cancel: isCancel,
            queue_ids: transfer.queueIds(),
            completed_ids: transfer.completedIds(),
            store_id: data.params.filters['store_id'] ?? self.defaultStoreId,
            stores: settings.stores,
            fields: settings.fields,
            user: listingModel.currentUser().email
        };
        
        $.ajax({
            url: self.bulkTransferViaApiUrl + '?form_key=' + encodeURIComponent(window.FORM_KEY),
            type: 'POST',
            data: JSON.stringify(transferData),
            contentType: 'application/json',
            dataType: 'json',
            showLoader: false,
            success: function (response) {
                if (!response.success) {
                    errorMessagesModel.messages.push(response.message);
                    notifications.statuses.remove(function (status) {
                        return status.id === notifications.transferTempId;
                    });
                    console.log(response.message);
                } else {
                    notifications.updateTempStatusId(
                        response.api_response.requestId,
                        notifications.transferTempId
                    );
                }
            }
        });
    }


    /**
     * Continue bulk transfer
     *
     * @param {Object} self - Self data.
     *
     * @returns {void}
     */
    function continueBulkTransfer(self)
    {
        try {
            notifications.statuses().forEach(status => {
                if (status.status === self.statusRunning &&
                    status.user === listingModel.currentUser().email &&
                    status.transfer === true &&
                    status.queuedIds.length > 0
                ) {
                    let action = {},
                        data = {
                            excludeMode: false,
                            excluded: [],
                            params: {
                                fields: status.continueParams.fields,
                                stores: status.continueParams.stores,
                                namespace: "wtai_products_grid_listing",
                                filters: {
                                    store_id: status.continueParams.store_filter
                                }
                            },
                            /** IMPORTANT: always set completed first so the index is correct */
                            selected: [...status.completedIds, ...status.queuedIds],
                            total: status.queuedIds.length + status.completedIds.length
                    },
                        settings = {
                            stores: status.continueParams.stores,
                            fields: status.continueParams.fields
                    },
                        index = status.completedIds.length;
                    
                    if (data.total > 1) {
                        return;
                    }
                    if (self.isTransferOngoing()) {
                        return;
                    }
                    transfer.completedIds(status.completedIds);
                    transfer.queueIds(status.queuedIds);
                    bulkTransfer(self, action, data, settings, index);
                }
            });
        } catch (e) {
            return;
        }
    }

    /**
     * Remove notification
     *
     * @returns {void}
     */
    function removeNotification()
    {
        notifications.statuses.remove(function (status) {
            return status.id === notifications.transferTempId;
        });
    }

    return {
        transferable: transferable,
        bulkTransfer: bulkTransfer,
        saveBulkTransferProgress: saveBulkTransferProgress,
        continueBulkTransfer: continueBulkTransfer,
        removeNotification: removeNotification
    };
});
