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

define([
    'jquery',
    'ko',
    'uiComponent',
    'underscore',
    'WriteTextAI_WriteTextAI/js/model/edit/attributes',
    'WriteTextAI_WriteTextAI/js/model/edit/generate/attributes',
    'WriteTextAI_WriteTextAI/js/model/edit/product',
    'mage/translate',
    'mage/template',
    'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html',
    'Magento_Ui/js/modal/modal'
], function (
    $,
    ko,
    Component,
    _,
    attributes,
    generateAttributes,
    product,
    $t,
    mageTemplate,
    thumbnailPreviewTemplate
) {
    'use strict';

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

    return Component.extend({
        defaults: {
            productId: '',
            storeId: '',
            productAttributes: [],
            productAttributesSelected: [],
            otherProductDetails: '',
            otherProductDetailsChecked: false,
            selectAllValue: null,
            canUpdate: true,
            allAttributes: [],
            productAttributesSelectedNotPremium: [],
            allChildProducts: [],
            visibleChildProducts: [],
            isLoadingChildProducts: false,
            hasChildProductsScroll: false,
            initialChildProductsVisible: 10,
            loadMoreChildProductsCount: 10,
            childProductsMaxRows: 6,
            isChildProductsExpanded: false,
            childProductsUrl: ''
        },

        productDetailsAllowed: false,
        isAttributesChanged: false,
        typingTimer: null,

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

            self = this;

            product.productId.subscribe(function (productId) {
                self.productId(productId);
                self.loadChildProducts();
            });

            product.storeId.subscribe(function (storeId) {
                self.storeId(storeId);
                self.loadChildProducts();
            });

            product.productType.subscribe(function () {
                self.loadChildProducts();
            });

            if (product.childProducts && typeof product.childProducts.subscribe === 'function') {
                product.childProducts.subscribe(function () {
                    self.loadChildProducts();
                });
            }

            self.productId(product.productId());
            self.storeId(product.storeId());
            self.loadChildProducts();

            attributes.otherProductDetails.subscribe(
                function (otherProductDetails) {
                    self.isAttributesChanged = true;
                    self.otherProductDetails(otherProductDetails);
                    self.isAttributesChanged = false;
                }
            );

            attributes.otherProductDetailsChecked.subscribe(
                function (otherProductDetailsChecked) {
                    self.isAttributesChanged = true;
                    self.otherProductDetailsChecked(
                        otherProductDetailsChecked
                    );
                    self.isAttributesChanged = false;
                }
            );

            attributes.productAttributesSelected.subscribe(
                function (productAttributesSelected) {
                    self.isAttributesChanged = true;
                    self.productAttributesSelected(productAttributesSelected);
                    self.isAttributesChanged = false;
                }
            );

            attributes.productAttributes.subscribe(
                function (productAttributes) {
                    var allAttributes = productAttributes.map((object) => ({
                            ...object
                        })),
                        productAttributesSelected = productAttributes.filter(
                            function (productAttribute) {
                                return productAttribute.checked;
                            }
                        );

                    self.productAttributes(productAttributes);
                    self.allAttributes(allAttributes);
                    self.isAttributesChanged = true;
                    self.productAttributesSelected([]);

                    for (let key in productAttributesSelected) {
                        if (productAttributesSelected.hasOwnProperty(key)) {
                            self.productAttributesSelected.push(
                                productAttributesSelected[key].attribute_code
                            );
                        }
                    }
                    self.isAttributesChanged = false;
                }
            );

            self.productAttributesSelected.subscribe(
                function (productAttributesSelected) {
                    generateAttributes.productAttributesSelected([]);
                    for (let key in productAttributesSelected) {
                        if (productAttributesSelected.hasOwnProperty(key)) {
                            generateAttributes.productAttributesSelected.push(
                                productAttributesSelected[key]
                            );
                        }
                    }

                    if (self.canUpdate) {
                        self.updateSelect();
                    }

                    if (!self.isAttributesChanged) {
                        self.savePreferences();
                    }
                }
            );

            self.otherProductDetailsChecked.subscribe(
                function (otherProductDetailsChecked) {
                    generateAttributes.otherProductDetailsChecked(
                        otherProductDetailsChecked
                    );

                    if (!self.isAttributesChanged) {
                        self.savePreferences();
                    }
                }
            );

            self.otherProductDetails.subscribe(function (otherProductDetails) {
                generateAttributes.otherProductDetails(otherProductDetails);
            });

            $(document)
                .off('openModal.wtaiChildProductsInit')
                .on('openModal.wtaiChildProductsInit', '.wtai-edit-modal.wtai-edit-main', function () {
                    if (self.allChildProducts().length > 0) {
                        self.getInitialChildProducts();
                    }
                });

            this.updateSelect();

            // Bind window resize to update list overflow
            $(window).on('resize.wtaiChildProducts', function () {
                self.updateListOverflow();
            });
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'productAttributes',
                'allAttributes',
                'productId',
                'storeId',
                'productAttributesSelected',
                'otherProductDetails',
                'otherProductDetailsChecked',
                'selectAllValue',
                'productAttributesSelectedNotPremium',
                'allChildProducts',
                'visibleChildProducts',
                'isLoadingChildProducts',
                'hasChildProductsScroll',
                'childProductsMaxRows',
                'isChildProductsExpanded'
            ]);

            this.isChildProductListVisible = ko.computed(function () {
                var type = (product.productType && product.productType()) ? String(product.productType()) : '';
                var supported = ['configurable', 'grouped', 'bundle'];
                return supported.indexOf(type) !== -1;
            }, this);

            this.childProductPanelTitle = ko.computed(function () {
                var type = (product.productType && product.productType()) ? String(product.productType()) : '';
                if (type === 'bundle') {
                    return $t('Bundled products');
                }
                if (type === 'configurable') {
                    return $t('Configurable products');
                }
                if (type === 'grouped') {
                    return $t('Grouped products');
                }
                return $t('Child products');
            }, this);

            this.childProductPanelSubtitle = ko.computed(function () {
                var type = (product.productType && product.productType()) ? String(product.productType()) : '';
                if (type === 'bundle') {
                    return $t('The following products are included in this bundle');
                }
                if (type === 'configurable') {
                    return $t('The following variations are associated with this configurable product');
                }
                if (type === 'grouped') {
                    return $t('The following products are associated with this group');
                }
                return '';
            }, this);
            
            this.noChildProductText = ko.computed(function () {
                var type = (product.productType && product.productType()) ? String(product.productType()) : '';
                if (type === 'bundle') {
                    return $t('No products found in this bundle.');
                }
                if (type === 'configurable') {
                    return $t('No variations found.');
                }
                if (type === 'grouped') {
                    return $t('No products found in this group.');
                }
                return $t('No child products found');
            }, this);
            
            this.childProductPanelTooltip = ko.computed(function () {
                var type = (product.productType && product.productType()) ? String(product.productType()) : '';
                if (type === 'bundle') {
                    return $t('Only enabled products in the bundle are shown in this list.'
                                + ' If a product you expect to see is missing,'
                                + ' check that it is enabled in your product catalog settings before returning to this screen.');
                }
                if (type === 'configurable') {
                    return $t('Only enabled configurations are shown in this list.'
                                + ' If a configuration you expect to see is missing,'
                                + ' check that it is enabled in your product settings before returning to this screen.');
                }
                if (type === 'grouped') {
                    return $t('Only enabled products in the group are shown in this list.'
                                + ' If a product you expect to see is missing,'
                                + ' check that it is enabled in your product catalog settings before returning to this screen.');
                }
                return '';
            }, this);

            return this;
        },

        /**
         * Get initial child products.
         */
        getInitialChildProducts: function () {
            self.isChildProductsExpanded(false);
            self.applyChildProductsRowLimit();
            self.updateChildProductsScrollState();
        },

        /**
         * Load more child products.
         */
        loadMoreChildProducts: function () {
            self.isChildProductsExpanded(true);
            self.visibleChildProducts(self.allChildProducts());
            self.updateChildProductsScrollState();
            self.updateListOverflow();
        },

        /**
         * Apply child products row limit (6 rows by default) and show Load more only when needed.
         */
        applyChildProductsRowLimit: function () {
            var maxRows = parseInt(self.childProductsMaxRows(), 10);
            if (!maxRows || maxRows < 1) {
                maxRows = 6;
            }

            if (self.isChildProductsExpanded && self.isChildProductsExpanded()) {
                self.visibleChildProducts(self.allChildProducts());
                self.updateChildProductsScrollState();
                return;
            }

            self.visibleChildProducts(self.allChildProducts());

            setTimeout(function () {
                var list = document.getElementById('wtaiChildProductList');
                if (!list) {
                    return;
                }

                var items = list.querySelectorAll('li');
                if (!items || !items.length) {
                    return;
                }

                var rowTops = [];
                var visibleCount = items.length;

                for (var i = 0; i < items.length; i++) {
                    var top = items[i].offsetTop;
                    if (rowTops.indexOf(top) === -1) {
                        rowTops.push(top);
                        if (rowTops.length > maxRows) {
                            visibleCount = i;
                            break;
                        }
                    }
                }

                if (visibleCount < items.length) {
                    self.visibleChildProducts(self.allChildProducts().slice(0, visibleCount));
                }

                self.updateChildProductsScrollState();
            }, 0);
        },

        /**
         * Update child products scroll state.
         */
        updateChildProductsScrollState: function () {
            setTimeout(function () {
                var list = document.getElementById('wtaiChildProductList');

                if (!list) {
                    self.hasChildProductsScroll(false);
                    return;
                }

                self.hasChildProductsScroll(list.scrollHeight > list.clientHeight + 1);
            }, 0);
        },

        /**
         * Load child products.
         */
        loadChildProducts: function () {
            if (product.childProducts && typeof product.childProducts === 'function') {
                var fromIndex = product.childProducts();
                if (Array.isArray(fromIndex)) {
                    self.isLoadingChildProducts(false);
                    self.allChildProducts(fromIndex);
                    self.getInitialChildProducts();
                    return;
                }
            }

            if (!self.childProductsUrl) {
                self.isLoadingChildProducts(false);
                return;
            }

            if (!self.isChildProductListVisible || !self.isChildProductListVisible()) {
                self.isLoadingChildProducts(false);
                self.allChildProducts([]);
                self.visibleChildProducts([]);
                return;
            }

            var productId = self.productId();
            var storeId = self.storeId();

            if (!productId || !storeId) {
                self.isLoadingChildProducts(false);
                self.allChildProducts([]);
                self.visibleChildProducts([]);
                return;
            }

            self.isLoadingChildProducts(true);

            $.ajax({
                url: self.childProductsUrl,
                type: 'GET',
                data: {
                    product_id: productId,
                    store_id: storeId
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (response && response.success && Array.isArray(response.items)) {
                        self.allChildProducts(response.items);
                        self.getInitialChildProducts();
                    } else {
                        self.allChildProducts([]);
                        self.visibleChildProducts([]);
                    }
                },
                error: function () {
                    self.allChildProducts([]);
                    self.visibleChildProducts([]);
                },
                complete: function () {
                    self.isLoadingChildProducts(false);
                    self.updateChildProductsScrollState();
                }
            });
        },

        /**
         * 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 thumbnail selected.
         *
         * @param {Object} data
         * @param {Event} event
         *
         * @returns {void}
         */
        saveThumbnailSelected: function (data, event) {
            $.ajax({
                url: self.saveSettingsUrl,
                type: 'POST',
                data: {
                    thumbnail: event.target.checked
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

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

        /**
         * Save user preferences
         */
        savePreferences: function () {
            var productId = self.productId(),
                storeId = self.storeId(),
                productAttributesSelected = self.productAttributesSelected(),
                otherProductDetails = self.otherProductDetails(),
                otherProductDetailsChecked = self.otherProductDetailsChecked();
            
            $.ajax({
                url: self.saveUrl,
                type: 'POST',
                data: {
                    product_id: productId,
                    store_id: storeId,
                    product_attributes_selected: productAttributesSelected,
                    other_product_details: otherProductDetails,
                    other_product_details_checked: otherProductDetailsChecked
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

        /**
         * Get other product details length.
         */
        getOtherProductDetailsLength: function () {
            var otherProductDetailsLength = this.otherProductDetails()
                ? this.otherProductDetails().length : 0;

            return (
                otherProductDetailsLength +
                '/' +
                this.rules.maxOtherDetailsLength +
                ' ' +
                $t('Char')
            );
        },

        /**
         * Select all attributes
         */
        selectAllAttributes: function () {
            var productAttributesSelected = self.productAttributes(),
                attributeCodes = productAttributesSelected.map(function (attribute) {
                    return attribute.attribute_code;
                });

            this.canUpdate = false;
            if (this.selectAllValue()) {
                self.productAttributesSelected(attributeCodes);
            } else {
                self.productAttributesSelected([]);
            }
            this.canUpdate = true;

            $.ajax({
                url: self.saveSettingsUrl,
                type: 'POST',
                data: {
                    thumbnail: this.selectAllValue()
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    }
                }
            });
        },

        /**
         * Update select all value
         */
        updateSelect: function () {
            const selectedAttributes = self.productAttributesSelected();
            const allAttributes = self.allAttributes();
            const allSelected = allAttributes.every(
                attr =>
                selectedAttributes.includes(attr.attribute_code)
            );
            this.selectAllValue(allSelected);
        },

        handleChildProductHover: function (data, event) {
            var item = event && event.currentTarget ? event.currentTarget : null;

            if (!item) {
                return;
            }

            item.classList.remove('wtai-hovered-cut');

            window.requestAnimationFrame(function () {
                var list = document.getElementById('wtaiChildProductList');
                var tooltip = item.querySelector('.wtai-hovered');

                if (!list || !tooltip) {
                    return;
                }

                if (list.scrollHeight <= list.clientHeight + 1) {
                    list.style.overflowY = 'unset';
                    item.classList.remove('wtai-hovered-cut');
                    return;
                }

                var listRect = list.getBoundingClientRect();
                var tooltipRect = tooltip.getBoundingClientRect();

                var isCut = tooltipRect.top < listRect.top ||
                    tooltipRect.bottom > listRect.bottom ||
                    tooltipRect.left < listRect.left ||
                    tooltipRect.right > listRect.right;

                if (isCut) {
                    item.classList.add('wtai-hovered-cut');
                }
            });
        },

        /**
         * Update overflow-y on wtaiChildProductList based on window size
         */
        updateListOverflow: function () {
            var list = document.getElementById('wtaiChildProductList');

            if (!list) {
                return;
            }

            if (list.scrollHeight <= list.clientHeight + 1) {
                list.style.overflowY = 'unset';
            } else {
                list.style.overflowY = 'auto';
            }
        },

        handleChildProductLeave: function (data, event) {
            var item = event && event.currentTarget ? event.currentTarget : null;

            if (!item) {
                return;
            }

            item.classList.remove('wtai-hovered-cut');
        },

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

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