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

define([
    'jquery',
    'ko',
    'uiComponent',
    'underscore',
    'WriteTextAI_WriteTextAI/js/model/total-credits',
    'WriteTextAI_WriteTextAI/js/model/edit/gallery',
    'WriteTextAI_WriteTextAI/js/utils/edit/textfields',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'WriteTextAI_WriteTextAI/js/model/edit/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/textfields',
    'WriteTextAI_WriteTextAI/js/model/edit/preferences',
    'WriteTextAI_WriteTextAI/js/model/edit/transfer/settings',
    'WriteTextAI_WriteTextAI/js/model/edit/mark-reviewed',
    'Magento_Ui/js/modal/confirm',
    'mage/template',
    'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keywords',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/currently-generating',
    'WriteTextAI_WriteTextAI/js/model/edit',
    'WriteTextAI_WriteTextAI/js/model/signalr',
    'WriteTextAI_WriteTextAI/js/model/edit/error-messages',
    'Magento_Ui/js/modal/modal',
    'mage/dropdown'
], function (
    $,
    ko,
    Component,
    _,
    totalCredits,
    gallery,
    textfieldsUtils,
    product,
    settings,
    textfields,
    preferences,
    transferSettings,
    markReviewed,
    confirm,
    mageTemplate,
    thumbnailPreviewTemplate,
    keywordAnalysisData,
    keywordsData,
    currentlyGeneratingModel,
    editData,
    signalRModel,
    errorMessagesModel
) {
    'use strict';

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

    /**
     * Highlight words in a textarea
     */
    ko.bindingHandlers.highlightWords = {
        update: textfieldsUtils.highlightWords
    };

    return Component.extend({
        defaults: {
            selectedImages: [],
            selectAllImages: false,
            images: [],
            highlighted: true,
            selectedImagesNotPremium: [],
            selectAllImagesNotPremium: false
        },

        isSelectedChange: false,
        isSelectAllChange: false,
        isImagesChange: false,
        sendingFeedback: [],

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

            self = this;
            
            gallery.images.subscribe(function (images) {
                if (!self.isImagesChange) {
                    self.images(images);
                }
            });

            gallery.selectAllImages.subscribe(function (selectAllImages) {
                self.selectAllImages(selectAllImages);
            });

            signalRModel.isConnected.subscribe(function (isConnected) {
                console.log('isConnected gallery', isConnected);
                if (editData.opened() && isConnected) {
                    var recordId = product.productId();
                    var storeId = product.storeId();
                    var entityType = 'Product';
                    var identifier = entityType + '_'+ recordId + '_' + storeId;
                    var currentlyGeneratingRecordIdentifiers = currentlyGeneratingModel.recordIdentifiers();
                    if (currentlyGeneratingRecordIdentifiers.includes(identifier)
                        && self.selectedImages().length > 0) {
                        self.getImages(recordId, storeId);
                    }
                }
            }, this);

            gallery.selectedImages.subscribe(function (selectedImages) {
                self.isSelectedChange = true;
                self.selectedImages(selectedImages);
                self.isSelectedChange = false;
            });

            self.selectAllImages.subscribe(function (selectAllImages) {
                var images = selectAllImages ? [ ...self.images().map(image => image.id) ] : [];
                
                if (!self.isSelectAllChange) {
                    self.isSelectedChange = true;
                    self.selectedImages(images);
                    gallery.selectedImages(images);
                    if (selectAllImages !== gallery.selectAllImages()) {
                        gallery.selectAllImages(selectAllImages);
                    }
                    self.isSelectedChange = false;
                }

            });

            self.selectedImages.subscribe(function (selectedImages) {
                var selectAllImages = selectedImages.length === self.images().length;

                if (!self.isSelectedChange) {
                    self.isSelectAllChange = true;
                    self.selectAllImages(selectAllImages);
                    gallery.selectAllImages(selectAllImages);
                    gallery.selectedImages(selectedImages);
                    self.isSelectAllChange = false;

                    self.savePreferences('gallery', selectedImages.length > 0);
                }
            });
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super()
                .observe([
                    'selectedImages',
                    'selectAllImages',
                    'images',
                    'highlighted',
                    'selectedImagesNotPremium',
                    'selectAllImagesNotPremium'
                ]);

            this.isKoRefreshing = ko.pureComputed(function () {
                return Boolean(
                    keywordAnalysisData.refreshingData && keywordAnalysisData.refreshingData()
                );
            });

            this.keywordAnalysisOngoing = ko.computed(function () {
                var isProductOptimizing = Number(keywordAnalysisData.optimizingId()) === Number(product.productId()) &&
                    Number(keywordAnalysisData.optimizingStoreId()) === Number(product.storeId()),
                keywordAnalysisOngoing = (keywordAnalysisData.optimizing() ||
                    keywordAnalysisData.isUploading()) &&
                    !keywordAnalysisData.optimized() &&
                    !keywordAnalysisData.optimizationFailed() &&
                    !keywordAnalysisData.imageUploadFailed();

                return keywordAnalysisOngoing && isProductOptimizing;
            }, this);

            this.isImgAltTextFieldEnabled = ko.computed(function () {
                return function (image_id) {
                    var returnStatus = false;
                    gallery.images().some(function (image) {
                        if (image.id === image_id) {
                            returnStatus = image.writetext_alt !== '' && image.status.generated;
                            return returnStatus;
                        }
                    });
                    return returnStatus;
                };
            }, this);

            this.formalLanguageSupport = ko.computed(function () {
                return settings.formalLanguageSupport();
            });

            this.formalLanguages = ko.computed(function () {
                return settings.formalLanguages();
            });

            this.formal = ko.computed(function () {
                return textfields.formal();
            });

            this.informal = ko.computed(function () {
                return preferences.stylesSelected() === 'Internet-speak';
            });

            this.highlightPronouns = ko.computed(function () {
                return textfields.highlightPronouns();
            });

            this.language = ko.computed(function () {
                return product.language();
            });

            this.galleryImages = ko.computed(function () {
                return gallery.images();
            });

            this.optimizationData = ko.computed(function () {
                return keywordAnalysisData.optimizationData();
            });

            this.selectedKeywords = ko.computed(function () {
                return keywordsData.selectedKeywords();
            });

            return this;
        },

        /**
         * Check if field is not editable.
         *
         * @param {Boolean} status
         * @returns {Boolean}
         */
        isNotEditable: function (status) {
            if (self.keywordAnalysisOngoing()) {
                return true;
            }

            return status;
        },

        /**
         * Preview image.
         *
         * @param {String} image
         * @returns {void}
         */
        preview: function (image) {
            var modalHtml = mageTemplate(
                thumbnailPreviewTemplate,
                {
                    src: image,
                    alt: '',
                    link: '',
                    linkText: ''
                    }
            ),
                previewPopup = $('<div/>').html(modalHtml);

            previewPopup.modal({
                title: '',
                innerScroll: true,
                modalClass: '_image-box',
                buttons: []
            }).trigger('openModal');
        },

        /**
         * Save user preferences
         *
         * @param {String} field
         * @param {String} selected
         *
         * @returns {void}
         */
        savePreferences: function (field, selected) {
            var value = selected;
            
            if (value.length <= 0) {
                value = '';
            }

            $.ajax({
                url: self.saveUrl,
                type: 'POST',
                data: {
                    [field]: value,
                    entity_type: 'product',
                    scope: 'edit'
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

        /**
         * Process click functionality of select all
         * Important to always return true
         * in order for checked binding to continue working
         *
         * @returns {boolean}
         */
        processClick: function () {
            var value = gallery.selectAllImages();
            self.savePreferences('gallery', value);
            return true;
        },


        /**
         * Get char count.
         *
         * @param {String} html
         * @param {Number} limit
         *
         * @returns {Number}
         */
        getCharCount: function (html, limit = null) {
            return textfieldsUtils.getCharCount(html, limit);
        },

        /**
         * Get word count.
         *
         * @param {String} html
         * @returns {Number}
         */
        getWordCount: function (html) {
            return textfieldsUtils.getWordCount(html);
        },

        /**
         * Update image.
         *
         * @param {Object} data
         * @param {Object} event
         * @param {Object} image
         *
         * @returns {void}
         */
        updateImage: function (data, event, image) {
            var images = self.images() || [];
            
            images.forEach(function (img) {
                if (img.id === image.id) {
                    img.writetext_alt = event.target.value;
                }
            });

            self.isImagesChange = true;
            gallery.images([]);
            gallery.images(images);
            self.isImagesChange = false;
            $('#wtaiAlt' + image.id).trigger('focus');
        },

        /**
         * Check if transfer is enabled.
         *
         * @param {Object} data
         * @returns {Boolean}
         */
        isTransferEnabled: function (data) {
            return data.writetext_alt !== '' && data.status.generated;
        },

        /**
         * Transfer image to Magento
         *
         * @param {Object} image
         * @returns {void}
         */
        transfer: function (image) {
            confirm({
                title: $.mage.__('Transfer selected to Magento'),
                content: self.confirmContent,
                modalClass:
                    'wtai-modal wtai-bulk-transfer-popup wtai-transfer wtai-edit',
                actions: {
                    confirm: function () {
                        self._transfer(image);
                    },
                    cancel: function () {
                        return;
                    }
                }
            });
        },

        /**
         * Transfer image to Magento
         *
         * @param {Object} image
         * @returns {void}
         */
        _transfer: function (image) {
            $.ajax({
                url: self.transferUrl,
                type: 'POST',
                data: {
                    image: image,
                    product_id: product.productId(),
                    store_id: product.storeId(),
                    selected_stores: transferSettings.selectedStores()
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showGalleryLoader: true,
                success: function (response) {
                    if (response.success) {
                        if (transferSettings.selectedStores().includes(
                            parseInt(product.storeId())
                        )) {
                            // Find the updated image from response that matches the request image
                            var updatedImage = response.images.find(function(responseImage) {
                                return responseImage.id === image.id;
                            });
                            
                            if (updatedImage) {
                                // Update only the specific image in gallery
                                var currentImages = gallery.images();
                                var updatedImages = currentImages.map(function(currentImage) {
                                    return currentImage.id === image.id ? updatedImage : currentImage;
                                });
                                gallery.images(updatedImages);
                            }
                        }
                        markReviewed.reviewed(response.reviewed);
                    } else {
                        console.error(response.message);
                        errorMessagesModel.messages.push(response.message);
                    }
                }
            });
        },

        /**
         * Initialize feedback popup
         *
         * @param {String} id
         * @returns {void}
         */
        initPopup: function (id) {
            setTimeout(function () {
                this.sendingFeedback[id] = null;
            }.bind(this), 2000);
        },

        /**
         * Send feedback
         *
         * @param {Object} data
         * @param {boolean} closePopup
         *
         * @returns {void}
         */
        sendFeedback: function (data, closePopup = true) {
            if (this.sendingFeedback[data.id] !== null) {
                this.sendingFeedback[data.id].abort();
            }
            
            if (closePopup) {
                $('#wtaiFeedbackLoading' + data.id).removeClass('wtai-no-display');
            }

            this.sendingFeedback[data.id] = $.ajax({
                url: this.feedbackUrl,
                type: 'POST',
                data: {
                    record_id: data.id,
                    store_id: product.storeId(),
                    field_type: '',
                    rating: data.feedback.rating,
                    comment: '',
                    entity_type: this.entityType,
                    value: data.writetext_alt,
                    alt_id: data.writetext_alt_id
                },
                dataType: 'json',
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }.bind(this),
                error: function (xhr, status, error) {
                    if (status !== 'abort') {
                        console.log(error);
                    }
                }
            }).always(function () {
                if (closePopup) {
                    $('#wtaiFeedbackLoading' + data.id).addClass('wtai-no-display');
                }
            }.bind(this));
        },

        /**
         * Check if liked
         *
         * @param {Object} data
         * @returns {Boolean}
         */
        isLiked: function (data) {
            return ko.computed(function () {
                var liked = false;
                self.images().forEach(function (img) {
                    if (img.id === data.id) {
                        if (typeof img.feedback === 'undefined') {
                            return false;
                        }
                        liked = img.feedback.rating === 'thumbs-up';
                    }
                });
                return liked;
            });
        },

        /**
         * Check if disliked
         *
         * @param {Object} data
         * @returns {Boolean}
         */
        isDisliked: function (data) {
            return ko.computed(function () {
                var liked = false;
                self.images().forEach(function (img) {
                    if (img.id === data.id) {
                        if (typeof img.feedback === 'undefined') {
                            return false;
                        }
                        liked = img.feedback.rating === 'thumbs-down';
                    }
                });
                return liked;
            });
        },

        /**
         * Update image rating
         *
         * @param {Object} data
         * @param {String} rating
         * @returns {void}
         */
        updateImageRating: function (data, rating) {
            const images = [...self.images()] || [];
            
            let newImages = [];
            images.forEach(function (img) {
                if (img.id === data.id) {
                    if (typeof img.feedback.rating === 'undefined') {
                        img.feedback = {
                            rating: rating
                        };
                    } else {
                        img.feedback.rating = rating;
                    }
                }
                newImages.push(img);
            });

            self.images(images);
        },

        /**
         * Like
         *
         * @param {Object} data
         * @returns {void}
         */
        like: function (data) {
            if (data.feedback.rating === 'thumbs-up') {
                this.resetFeedback(data);
            } else {
                this.updateImageRating(data, 'thumbs-up');
                data.feedback.rating = 'thumbs-up';
                this.sendFeedback(data, false);
            }
        },

        /**
         * Dislike
         *
         * @param {Object} data
         * @returns {void}
         */
        dislike: function (data) {
            if (data.feedback.rating === 'thumbs-down') {
                this.resetFeedback(data);
            } else {
                this.updateImageRating(data, 'thumbs-down');
                data.feedback.rating = 'thumbs-down';
                this.sendFeedback(data, false);
            }
        },

        /**
         * Count feedback text
         *
         * @param {String} id
         * @returns {String}
         */
        count: function (id) {
            return textfieldsUtils.getCharCount($(id).val(), this.textLimit);
        },

        /**
         * Reset feedback
         *
         * @param {Object} data
         * @returns {void}
         */
        resetFeedback: function (data) {
            this.updateImageRating(data, '');
            data.feedback.rating = '';
            this.deleteFeedback(data);
        },

        
        /**
         * Delete feedback
         */
        deleteFeedback: function (data) {
            if (this.sendingFeedback[data.id] !== null) {
                this.sendingFeedback[data.id].abort();
            }

            this.sendingFeedback[data.id] = $.ajax({
                url: this.deleteFeedbackUrl,
                type: 'POST',
                data: {
                    record_id: data.id,
                    store_id: product.storeId(),
                    field_type: '',
                    rating: data.feedback.rating,
                    comment: '',
                    entity_type: this.entityType,
                    value: data.writetext_alt,
                    alt_id: data.writetext_alt_id
                },
                dataType: 'json',
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }.bind(this),
                error: function (xhr, status, error) {
                    if (status !== 'abort') {
                        console.log(error);
                    }
                }
            });
        },
        
        /**
        * Get images.
        *
        * @param {Number} productId
        * @param {Number} storeId
        * @param {Object} self
        *
        * @returns {void}
        */
        getImages: function (productId, storeId) {
            $.ajax({
                url: self.getImagesUrl,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId
                },
                dataType: 'json',
                showWriteTextAILoader: true,
                showGalleryLoader: true,
                success: function (response) {
                    if (response.success) {
                        gallery.images(response.images);
                    }
                }
            });
        }
    });
});
