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

define([
    'jquery',
    'ko',
    'Magento_Ui/js/form/element/ui-select',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/representative-products',
    'WriteTextAI_WriteTextAI/js/categories/model/edit',
    'WriteTextAI_WriteTextAI/js/model/total-credits',
    'Magento_Ui/js/block-loader',
    'Magento_Ui/js/lib/key-codes',
    'underscore',
    'mage/translate'
], function (
    $,
    ko,
    Select,
    representativeProducts,
    editData,
    totalCredits,
    blockLoader,
    keyCodes,
    _,
    $t
) {
    'use strict';

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

    try {
        blockLoader();
    } catch (e) {
        console.log("blockloader failed", e);
    }

    return Select.extend({
        defaults: {
            filterInputSelector: '.wtai-representative-products-field .admin__action-multiselect-search',
            isLoading: false,
            totalSize: 0,
            page: 1,
            filterPlaceholder: $t('Search products'),
            filterOptions: true,
            selectedPlaceholders: {
                defaultPlaceholder: $t('Select or enter product name')
            },
            otherDetails: '',
            otherDetailsChecked: false,
            emptyText: $t("We couldn't find any items in this category."),
        },
        typingTimer: null,
        isSelectedChanged: false,
        isReset: false,
        productResearchData: false,
        productResearchPreference: false,
        syncProductResearchDataAvailability: function () {
            var allowed = this.value() && this.value().length > 0;

            if (!allowed) {
                if (this.productResearchData()) {
                    this.isSelectedChanged = true;
                    this.productResearchData(false);
                    this.isSelectedChanged = false;
                }
                return;
            }

            if (this.productResearchData() !== this.productResearchPreference) {
                this.isSelectedChanged = true;
                this.productResearchData(this.productResearchPreference);
                this.isSelectedChanged = false;
            }
        },
        /** @inheritdoc */
        initialize: function () {
            this._super();

            self = this;

            editData.currentCategory.subscribe(function () {
                self.page(1);
                self.resetSearch();
                self.filterOptionsAction(false);
            });

            this.otherDetails.subscribe(function (otherDetails) {
                representativeProducts.otherDetails(otherDetails);
            }, this);

            this.otherDetailsChecked.subscribe(function (otherDetailsChecked) {
                representativeProducts.otherDetailsChecked(otherDetailsChecked);
                if (!this.isSelectedChanged) {
                    this.saveRepresentative();
                }
            }, this);

            representativeProducts.representativeProducts.subscribe(function (representativeProducts) {
                this.options(representativeProducts);
                this.page(1);
            }, this);

            representativeProducts.totalSize.subscribe(function (totalSize) {
                this.totalSize(totalSize);
            }, this);

            representativeProducts.selected.subscribe(function (selected) {
                this.isSelectedChanged = true;
                this.value(selected);
                this.isSelectedChanged = false;

                this.syncProductResearchDataAvailability();
            }, this);

            representativeProducts.otherDetails.subscribe(function (otherDetails) {
                this.otherDetails(otherDetails);
            }, this);

            representativeProducts.otherDetailsChecked.subscribe(function (otherDetailsChecked) {
                this.isSelectedChanged = true;
                this.otherDetailsChecked(otherDetailsChecked);
                this.isSelectedChanged = false;
            }, this);

            representativeProducts.productResearchData.subscribe(function (productResearchData) {
                this.isSelectedChanged = true;
                this.productResearchData(productResearchData);
                this.isSelectedChanged = false;

                this.productResearchPreference = productResearchData;

                this.syncProductResearchDataAvailability();
            }, this);

            this.value.subscribe(function (value) {
                if (!self.isSelectedChanged) {
                    self.saveRepresentative();
                    representativeProducts.selected(value);

                    self.syncProductResearchDataAvailability();
                }
            });

            this.productResearchData.subscribe(function (productResearchData) {
                if (!self.isSelectedChanged) {
                    self.saveProductResearchDataSelected(productResearchData);
                    representativeProducts.productResearchData(productResearchData);

                    self.productResearchPreference = productResearchData;
                }
            });

            this.syncProductResearchDataAvailability();
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'isLoading',
                'totalSize',
                'page',
                'otherDetails',
                'otherDetailsChecked',
                'emptyText',
                'productResearchData'
            ]);

            this.isProductResearchDataAllowed = ko.computed(function () {
                return this.value() && this.value().length > 0;
            }, this);

            this.otherDetailsLength = ko.computed(function () {
                var otherDetailsLength = this.otherDetails() ? this.otherDetails().length : 0;
                return `${otherDetailsLength}/${this.rules.maxOtherDetailsLength} ${$t('Char')}`;
            }, this);

            this.maxOptionsSelected = ko.computed(function () {
                return this.value().length >= this.rules.maxRepresentativeProducts;
            }, this);

            return this;
        },

        /**
         * Toggle activity list element
         *
         * @param {Object} data - selected option data
         * @returns {Object} Chainable
         */
        toggleOptionSelected: function (data) {
            var isSelected = this.isSelected(data.value);
            
            if (this.maxOptionsSelected() && !this.isSelectedValue(data)) {
                return;
            }
            
            if (!isSelected) {
                this.value.push(data.value);
            } else {
                let newValue = this.value.filter(function (value) {
                    return value.value !== data.value.value;
                });
                this.value(newValue);
            }

            return this;
        },

        /**
         * Reset
         */
        resetValue: function () {
            self.isSelectedChanged = true;
            self.value([]);
            self.isSelectedChanged = false;
        },

        /**
         * Reset search
         */
        resetSearch: function () {
            self.isReset = true;
            self.filterInputValue('');

            $('.wtai-representative-products .admin__action-multiselect-search').prop('disabled', false);
            $('.wtai-representative-products .admin__action-multiselect-search').removeClass('_disabled');
            
            self.emptyText($t("We couldn't find any items in this category."));
        },
        
        /** @inheritdoc */
        filterOptionsKeydown: function (data, event) {
            var key = keyCodes[event.keyCode];

            if (key === 'enterKey') {
                self.filterOptionsList(false, false);
            }
            
            return this._super(data, event);
        },

        /**
         * Filtered options list by value from filter options list
         *
         * @param {Boolean} showMore
         * @param {Boolean} clear
         * @param {Boolean} delay
         *
         * @returns {void}
         */
        filterOptionsList: function (showMore = false, delay = true) {
            if (self.isReset) {
                self.isReset = false;
                return;
            }

            clearTimeout(self.typingTimer);
            if (delay) {
                self.typingTimer = setTimeout(function () {
                    self.filterOptionsAction(showMore);
                }, 2000);
            } else {
                self.filterOptionsAction(showMore);
            }
        },

        /**
         * Load more options on scroll down
         *
         * @param {Object} data
         * @param {Event} event
         *
         * @returns {void}
         */
        onScrollDown: function (data, event) {
            var clientHight = event.target.scrollTop + event.target.clientHeight,
                scrollHeight = event.target.scrollHeight;

            if (this.totalSize() <= this.options().length) {
                return;
            }

            if (clientHight > scrollHeight - this.deviation) {
                self.page(self.page() + 1);
                self.filterOptionsAction(true);
            }
        },
        
        /**
         * Remove selected option
         *
         * @param {Object} data
         * @returns {void}
         */
        removeOptionSelected: function (data) {
            var newData = {
                value: data
            };

            for (var prop in data) {
                if (data.hasOwnProperty(prop) && prop !== 'value') {
                    newData[prop] = data[prop];
                }
            }

            return this.toggleOptionSelected(newData);
        },

        /**
         * Check selected option
         *
         * @param {String} data - option value
         * @return {Boolean}
         */
        isSelected: function (data) {
            return this.multiple ? this.value().some(selected => selected.value === data.value) : this.value() === data;
        },

        /**
         * Filtered options list by value from filter options list
         *
         * @param {Boolean} showMore
         * @returns {void}
         */
        filterOptionsAction: function (showMore) {
            var url = self.representativeProductsUrl,
                categoryId = (editData.currentCategory() && editData.currentCategory().categoryId) ? editData.currentCategory().categoryId : '',
                storeId = (editData.currentCategory() && editData.currentCategory().storeId) ? editData.currentCategory().storeId : 0,
                page = self.page(),
                search = self.filterInputValue().trim().toLowerCase();

            self.isLoading(true);

            if (!showMore) {
                self.page(1);
            }

            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    search: search,
                    category_id: categoryId,
                    store_id: storeId,
                    page: page
                },
                dataType: 'json',
                success: function (response) {
                    if (response.success) {
                        self.options(response.options);
                        self.totalSize(response.total);

                        if (response.total <= 0 && search !== '') {
                            self.emptyText($t("No product/s found."));
                        } else {
                            self.emptyText($t("We couldn't find any items in this category."));
                        }

                        setTimeout(function () {
                            $(self.filterInputSelector).trigger('focus');
                        });
                    }
                }
            }).always(function () {
                self.isLoading(false);
            });
        },

        /**
         * Save user representative
         */
        saveRepresentative: function () {
            var categoryId = (editData.currentCategory() && editData.currentCategory().categoryId) ? editData.currentCategory().categoryId : '',
                storeId = (editData.currentCategory() && editData.currentCategory().storeId) ? editData.currentCategory().storeId : 0,
                productsSelected = self.value(),
                otherDetails = self.otherDetails(),
                otherDetailsChecked = self.otherDetailsChecked();
            
            $.ajax({
                url: self.saveUrl,
                type: 'POST',
                data: {
                    category_id: categoryId,
                    store_id: storeId,
                    products_selected: productsSelected,
                    other_details: otherDetails,
                    other_details_checked: otherDetailsChecked
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

        /**
         * Handle input custom audience.
         */
        handleInputOtherProductDetails: function () {
            clearTimeout(self.typingTimer);

            self.typingTimer = setTimeout(function () {
                if (!self.isAttributesChanged) {
                    self.saveRepresentative();
                }
            }, 2000);
        },

        /**
         * Save product research data selected.
         *
         * @param {Boolean} value
         *
         * @returns {void}
         */
        saveProductResearchDataSelected: function (value) {
            $.ajax({
                url: self.saveSettingsUrl,
                type: 'POST',
                data: {
                    wtai_product_research_data: value,
                    entity_type: '',
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },
    });
});
