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

define([
    'jquery',
    'ko',
    'uiComponent',
    'WriteTextAI_WriteTextAI/js/model/grid/prompt',
    'WriteTextAI_WriteTextAI/js/utils/edit/textfields',
    'mage/translate'
], function (
    $,
    ko,
    Component,
    prompt,
    textfieldsUtils,
    $t
) {
    'use strict';

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

    return Component.extend({
        defaults: {
            tooltipSelector: '.wtai-bulk-generate-form .admin__field-tooltip-action',
            clusterCount: 4,
            isLoading: true,
            searchIntent: [],
            searchIntents: [
                'transactional',
                'commercial',
                'navigational',
                'informational'
            ],
            autoTextOptimizationSelected: 'flag',
            triggerActionNPositionLow: 1,
            triggerActionNPositionLowMid: 1,
            triggerActionNPositionMid: 1,
            triggerActionNPositionMidHigh: 1,
            triggerActionNDaysLow: 1,
            triggerActionNDaysLowMid: 1,
            triggerActionNDaysMid: 1,
            triggerActionNDaysMidHigh: 1,
            subTitleLow: 'Ranking 1 - 10',
            subTitleLowMid: 'Ranking 1 - 10',
            subTitleMid: 'Ranking 1 - 10',
            subTitleMidHigh: 'Ranking 1 - 10',
            allProductFieldsSelected: false,
            productFields: [],
            allProductFields: [],
            triggerActionChanged: {
                low: ko.observable(false),
                low_mid: ko.observable(false),
                mid: ko.observable(false),
                mid_high: ko.observable(false)
            },
            isAcknowledgedHeadsUp: false,
            messageHeadsUp: '',
            positionHeadsUp: 'top',
            targetElementHeadsUp: null,
            isVisibleHeadsUp: false,
            buttonTextHeadsUp: $t('Yes, I understand'),
            headsupVisibility: {
                'transactional': ko.observable(false),
                'commercial': ko.observable(false),
                'navigational': ko.observable(false),
                'informational': ko.observable(false)
            },
            rules: {},
            maxClusterCount: 0,
            minClusterCount: 0,
            isCronAvailable: false,
            triggerActions: {},
            minTriggerActionNPosition: 0,
            maxTriggerActionNPosition: 0,
            minTriggerActionNDays: 0,
            maxTriggerActionNDays: 0,
            automaticTextOptimizationOptions: [],
            isRestoreGlobalLoading: false,
        },
        
        isSpinning: false,
        isReopening: false,
        isRestoring: false,

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

            $('.wtai-bulk-keyword-analysis-form-container > *').applyBindings(this);

            self = this;

            /*
            self.autoTextOptimizationSelected.subscribe(function (autoTextOptimizationSelected) {
                self.savePreferences('automatic_text_optimization', autoTextOptimizationSelected);
            });
            */

            self.searchIntent.subscribe(function (searchIntent) {
                if (!self.isReopening) {
                    self.savePreferences('search_intent', searchIntent.join(','));
                }
            });

            /*
            self.clusterCount.subscribe(function (clusterCount) {
                if (!self.isSpinning) {
                    self.savePreferences('cluster_count', clusterCount);
                }
            });
            */

            self.getSettings();
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super()
                .observe([
                    'isLoading',
                    'searchIntent',
                    'searchIntents',
                    'clusterCount',
                    'autoTextOptimizationSelected',
                    'triggerActionNPositionLow',
                    'triggerActionNPositionLowMid',
                    'triggerActionNPositionMid',
                    'triggerActionNPositionMidHigh',
                    'triggerActionNDaysLow',
                    'triggerActionNDaysLowMid',
                    'triggerActionNDaysMid',
                    'triggerActionNDaysMidHigh',
                    'subTitleLow',
                    'subTitleLowMid',
                    'subTitleMid',
                    'subTitleMidHigh',
                    'allProductFieldsSelected',
                    'productFields',
                    'isAcknowledgedHeadsUp',
                    'messageHeadsUp',
                    'positionHeadsUp',
                    'targetElementHeadsUp',
                    'isVisibleHeadsUp',
                    'rules',
                    'maxClusterCount',
                    'minClusterCount',
                    'isCronAvailable',
                    'triggerActions',
                    'minTriggerActionNPosition',
                    'maxTriggerActionNPosition',
                    'minTriggerActionNDays',
                    'maxTriggerActionNDays',
                    'allProductFields',
                    'automaticTextOptimizationOptions',
                    'isRestoreGlobalLoading'
                ]);

            this.searchIntentCommadSeparated = ko.computed(function () {
                return this.searchIntent().join(', ');
            }, this);

            this.allProductFieldsSelected = ko.computed({
                read: function () {
                    const productFields = this.productFields() || [];
                    const allProductFields = [...this.allProductFields()] || [];
                    return productFields.length === allProductFields.length;
                }.bind(this),
                write: function (value) {
                    const allProductFields = [...this.allProductFields()]|| [];
                    const fields = value ? allProductFields : [];
                    this.productFields(fields);
                }.bind(this)
            }, this);

            this.isOffsetRight = ko.computed(function () {
                if (this.headsupVisibility.informational() &&
                    this.searchIntent().length >= 2
                ) {
                    return true;
                }

                return false;
            }, this);

            return this;
        },

        /**
         * Initialize bulk tabs
         */
        initBulkTabs: function () {
            setTimeout(function () {
                $('.wtai-tabs').tabs({
                    active: 0
                });
            }, 100);
        },
        
        /**
         * Show loader
         */
        showLoader: function () {
            self.isLoading(true);
        },

        /**
         * Remove loader
         */
        removeLoader: function () {
            setTimeout(function () {
                self.isLoading(false);
            }, 100);
        },

        /**
         * Get settings
         */
        getSettings: function () {
            self.showLoader();
            $.ajax({
                url: self.getSettingsUrl,
                type: 'GET',
                data: {
                    getTemplateSettings: false
                },
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    } else {
                        console.log(response);

                        self.isReopening = true;
                        self.rules(response.data.rules);
                        self.autoTextOptimizationSelected(response.data.autoTextOptimizationSelected);
                        self.searchIntent(response.data.searchIntent);
                        self.clusterCount(response.data.clusterCount);
                        self.maxClusterCount(response.data.maxClusterCount);
                        self.minClusterCount(response.data.minClusterCount);
                        self.isCronAvailable(response.data.isCronAvailable);
                        self.triggerActions(response.data.triggerActions);
                        self.triggerActionNPositionLow(response.data.triggerActionNPositionLow);
                        self.triggerActionNDaysLow(response.data.triggerActionNDaysLow);
                        self.triggerActionNPositionLowMid(response.data.triggerActionNPositionLowMid);
                        self.triggerActionNDaysLowMid(response.data.triggerActionNDaysLowMid);
                        self.triggerActionNPositionMid(response.data.triggerActionNPositionMid);
                        self.triggerActionNDaysMid(response.data.triggerActionNDaysMid);
                        self.triggerActionNPositionMidHigh(response.data.triggerActionNPositionMidHigh);
                        self.triggerActionNDaysMidHigh(response.data.triggerActionNDaysMidHigh);
                        self.minTriggerActionNPosition(response.data.minTriggerActionNPosition);
                        self.maxTriggerActionNPosition(response.data.maxTriggerActionNPosition);
                        self.minTriggerActionNDays(response.data.minTriggerActionNDays);
                        self.maxTriggerActionNDays(response.data.maxTriggerActionNDays);
                        self.productFields(response.data.productFields);
                        self.allProductFields(response.data.allProductFields);
                        self.automaticTextOptimizationOptions(response.data.automaticTextOptimizationOptions);
                        self.isReopening = false;

                        self.initBulkTabs();
                        self.initTooltip();
                        self.initSpinner();
                        self.initPreferences();
                        self.initTriggerActionsLabels();
                        self.bindHeadsUpClickOutside();
                    }
                }
            }).always(function () {
                self.removeLoader();
            });
        },

        /**
         * Initialize preferences
         *
         * Set model values on page load.
         * Model values updates on change.
         * Retain selected fields when reopening the modal.
         */
        initPreferences: function () {
            if (!prompt.keywordAnalysisPromptInitialized()) {
                prompt.keywordAnalysisPromptInitialized(true);
            } else {
                this.isReopening = true;

                /* Reset the tooltip acknowledgement status when reopening the modal */
                this.isAcknowledgedHeadsUp(false);
                this.headsupVisibility.transactional(false);
                this.headsupVisibility.commercial(false);
                this.headsupVisibility.navigational(false);
                this.headsupVisibility.informational(false);
                
                this.isReopening = false;
            }
        },

        /**
         * Show restore global loader
         */
        showRestoreGlobalLoader: function () {
            self.isRestoreGlobalLoading(true);
        },

        /**
         * Remove restore global loader
         */
        removeRestoreGlobalLoader: function () {
            setTimeout(function () {
                self.isRestoreGlobalLoading(false);
            }, 100);
        },

        /**
         * Get trigger action name
         */
        getTriggerActionName: function (triggerAction) {
            switch (triggerAction) {
                case 'low':
                    return 'LOW - LOW MID';
                case 'low_mid':
                    return 'LOW MID - MID';
                case 'mid':
                    return 'MID - MID HIGH';
                case 'mid_high':
                    return 'MID HIGH - HIGH';
            }
        },

        /**
         * Format trigger action name
         */
        formatTriggerActionName: function (triggerAction) {
            switch (triggerAction) {
                case 'low':
                    return this.subTitleLow();
                case 'low_mid':
                    return this.subTitleLowMid();
                case 'mid':
                    return this.subTitleMid();
                case 'mid_high':
                    return this.subTitleMidHigh();
            }
        },

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

            if (self.isRestoring || self.isReopening) {
                return;
            }

            var scope = 'grid';

            if (field === 'search_intent') {
                scope = '';
            }

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

        /**
         * Restore user preferences
         */
        restore: function () {
            this.showRestoreGlobalLoader();

            $.ajax({
                url: this.restoreUrl,
                type: 'GET',
                dataType: 'json',
                showLoader: false,
                success: function (response) {
                    if (!response.success) {
                        console.log(response);
                    } else {
                        console.log(response);
                        self.isRestoring = true;
                        self.autoTextOptimizationSelected(response.data.automatic_text_optimization);
                        self.searchIntent([...response.data.search_intent]);
                        self.clusterCount(response.data.cluster_count);
                        self.triggerActionNPositionLow(self.triggerActions().low.trigger_action_n_position);
                        self.triggerActionNPositionLowMid(self.triggerActions().low_mid.trigger_action_n_position);
                        self.triggerActionNPositionMid(self.triggerActions().mid.trigger_action_n_position);
                        self.triggerActionNPositionMidHigh(self.triggerActions().mid_high.trigger_action_n_position);
                        self.triggerActionNDaysLow(self.triggerActions().low.trigger_action_n_days);
                        self.triggerActionNDaysLowMid(self.triggerActions().low_mid.trigger_action_n_days);
                        self.triggerActionNDaysMid(self.triggerActions().mid.trigger_action_n_days);
                        self.triggerActionNDaysMidHigh(self.triggerActions().mid_high.trigger_action_n_days);
                        self.productFields([...response.data.product_fields]);
                        
                        /**
                         * Select default trigger action for each position and restore nPosition/nDays values
                         */
                        ['low', 'low_mid', 'mid', 'mid_high'].forEach(function (position) {
                            var defaultAction = self.triggerActions()[position].trigger_action;
                            var radioSelector = 'input[name="trigger_action_' + position + '"][value="' + defaultAction + '"]';
                            $(radioSelector).prop('checked', true).trigger('change');

                            /**
                             * Restore nPosition value
                             */
                            var nPositionInput = $('.wtai-trigger-action-n-position-' + position);
                            if (nPositionInput.length) {
                                nPositionInput.val(self.triggerActions()[position].trigger_action_n_position).trigger('change');
                            }

                            /**
                             * Restore nDays value
                             */
                            var nDaysInput = $('.wtai-trigger-action-after-n-days-' + position);
                            if (nDaysInput.length) {
                                nDaysInput.val(self.triggerActions()[position].trigger_action_n_days).trigger('change');
                            }
                        });

                        self.initTriggerActionsLabels();
                        self.isRestoring = false;
                    }
                }
            }).always(function () {
                self.removeRestoreGlobalLoader();
            });
        },

        /**
         * Initialize spinner
         */
        initSpinner: function () {
            setTimeout(
                function () {
                    $('.wtai-bulk-keyword-analysis-popup .wtai-cluster-count').spinner({
                        numberFormat: 'n',
                        min: this.minClusterCount(),
                        max: this.maxClusterCount(),
                        spin: function (event, ui) {
                            self.isSpinning = true;
                            self.clusterCount(ui.value);
                            self.isSpinning = false;
                        },
                        change: function (event) {
                            self.clusterCount(event.target.value);
                        }
                    });

                    /** Define spinner configurations */
                    const positionSpinners = [
                        { selector: 'low', action: 'when_page_is_ranking' },
                        { selector: 'low_mid', action: 'when_page_is_ranking' },
                        { selector: 'mid', action: 'when_page_is_ranking' },
                        { selector: 'mid_high', action: 'when_page_is_ranking' }
                    ];

                    const daysSpinners = [
                        { selector: 'low', action: 'after_n_days' },
                        { selector: 'low_mid', action: 'after_n_days' },
                        { selector: 'mid', action: 'after_n_days' },
                        { selector: 'mid_high', action: 'after_n_days' }
                    ];

                    /** Helper function to initialize spinners */
                    const initSpinner = (type, config) => {
                        const isPosition = type === 'position';
                        const prefix = isPosition ? 'n-position' : 'after-n-days';
                        const min = isPosition ? this.minTriggerActionNPosition() : this.minTriggerActionNDays();
                        const max = isPosition ? this.maxTriggerActionNPosition() : this.maxTriggerActionNDays();
                        const selectorCased = config.selector.split('_').map(
                            word =>
                            word.charAt(0).toUpperCase() + word.slice(1)
                        ).join('');
                        const valueProperty = isPosition ?
                            `triggerActionNPosition${selectorCased}` :
                            `triggerActionNDays${selectorCased}`;

                        $(`.wtai-trigger-action-${prefix}-${config.selector}`).spinner({
                            numberFormat: 'n',
                            min: min,
                            max: max,
                            spin: function (event, ui) {
                                self.isSpinning = true;
                                self[valueProperty](ui.value);
                                self.isSpinning = false;
                            },
                            change: function (event) {
                                self[valueProperty](event.target.value);
                                self.selectTriggerAction(config.selector, config.action);
                                $(`input[name="trigger_action_${config.selector}"][value="${config.action}"]`).prop('checked', true).trigger('change');
                            }
                        });
                    };

                    /** Initialize all spinners */
                    positionSpinners.forEach(config => initSpinner('position', config));
                    daysSpinners.forEach(config => initSpinner('days', config));
                }.bind(this),
                100
            );
        },

        /**
         * Initialize tooltip
         */
        initTooltip: function () {
            $(self.tooltipSelector).dropdown({
                parent: '.admin__field-tooltip',
                autoclose: true
            });
        },

        /**
         * Initialize trigger actions labels
         */
        initTriggerActionsLabels: function () {
            this.triggerActionChanged.low(false);
            this.triggerActionChanged.low_mid(false);
            this.triggerActionChanged.mid(false);
            this.triggerActionChanged.mid_high(false);
            this.selectTriggerAction('low', this.triggerActions().low.trigger_action);
            this.selectTriggerAction('low_mid', this.triggerActions().low_mid.trigger_action);
            this.selectTriggerAction('mid', this.triggerActions().mid.trigger_action);
            this.selectTriggerAction('mid_high', this.triggerActions().mid_high.trigger_action);
        },

        /**
         * Is intent selected
         */
        isIntentSelected: function (intent) {
            return this.searchIntent().indexOf(intent) !== -1;
        },

        /**
         * Get tooltip text search intent
         *
         * @param {String} intent
         * @return {String}
         */
        getTooltipTextSearchIntent: function (intent) {
            
            if (this.searchIntent().length === 1 && this.searchIntent().indexOf(intent) !== -1) {
                return $t('You need at least one search intent');
            }
            switch (intent) {
                case 'transactional':
                    return $t('Users aim to complete a transaction, such as making a purchase or signing up for a service.');
                case 'commercial':
                    return $t('Users are researching products or services with the intention of making a purchase decision soon.');
                case 'informational':
                    return $t('Users seek information on a specific topic, intending to learn something.');
                case 'navigational':
                    return $t('Users have a specific website or web page in mind and are using search engines to navigate there directly.');
                default:
                    return '';
            }
        },

        /**
         * Select search intent
         *
         * @param {String} intent
         * @return {void}
         */
        selectIntent: function (intent) {
            var searchIntent = this.searchIntent();

            if (searchIntent.length <= 1 &&
                searchIntent.indexOf(intent) !== -1
            ) {
                return;
            }

            if (searchIntent.indexOf(intent) === -1) {
                searchIntent.push(intent);
            } else {
                searchIntent = _.without(searchIntent, intent);
            }

            this.searchIntent(searchIntent);
        },

        /**
         * Validate min and max fields.
         *
         * @param {Object} data
         * @param {Object} event
         *
         * @return {void}
         */
        validateMinMax: function (data, event) {
            var target = event.target,
                value = Number(target.value),
                min = Number(target.min),
                max = Number(target.max),
                name = target.name;

            const mapping = {
                cluster_count: self.clusterCount,
                trigger_action_n_position_low: self.triggerActionNPositionLow,
                trigger_action_n_position_low_mid: self.triggerActionNPositionLowMid,
                trigger_action_n_position_mid: self.triggerActionNPositionMid,
                trigger_action_n_position_mid_high: self.triggerActionNPositionMidHigh,
                trigger_action_n_days_low: self.triggerActionNDaysLow,
                trigger_action_n_days_low_mid: self.triggerActionNDaysLowMid,
                trigger_action_n_days_mid: self.triggerActionNDaysMid,
                trigger_action_n_days_mid_high: self.triggerActionNDaysMidHigh,
            };

            if (value < min || value > max) {
                const func = mapping[name],
                    val = value < min ? min : max;

                $(target).val(val);
                func(val);
            }
        },

        /**
         * Validate number.
         *
         * @param {Object} data
         * @param {Object} event
         *
         * @return {Boolean}
         */
        ensureNumerical: function (data, event) {
            return textfieldsUtils.ensureNumerical(event.key);
        },

        /**
         * Select trigger action
         *
         * @param {String} triggerAction
         * @param {String} value
         *
         * @return {void}
         */
        selectTriggerAction: function (triggerAction, value) {
            const actionMap = {
                low: {
                    position: this.triggerActionNPositionLow(),
                    days: this.triggerActionNDaysLow(),
                    subtitle: this.subTitleLow
                },
                low_mid: {
                    position: this.triggerActionNPositionLowMid(),
                    days: this.triggerActionNDaysLowMid(),
                    subtitle: this.subTitleLowMid
                },
                mid: {
                    position: this.triggerActionNPositionMid(),
                    days: this.triggerActionNDaysMid(),
                    subtitle: this.subTitleMid
                },
                mid_high: {
                    position: this.triggerActionNPositionMidHigh(),
                    days: this.triggerActionNDaysMidHigh(),
                    subtitle: this.subTitleMidHigh
                }
            };

            const action = actionMap[triggerAction];
            if (!action) {
                return;
            }

            const { position, days, subtitle } = action;

            /* Get the initial value from triggerActions */
            const initialValue = this.triggerActions()[triggerAction].trigger_action;
            const initialPosition = this.triggerActions()[triggerAction].trigger_action_n_position || 2;
            const initialDays = this.triggerActions()[triggerAction].trigger_action_n_days || 1;
            
            /* Update the changed state */
            if (value !== initialValue ||
                (value === 'when_page_is_ranking' && parseInt(position) !== parseInt(initialPosition)) ||
                (value === 'after_n_days' && parseInt(days) !== parseInt(initialDays))) {
                this.triggerActionChanged[triggerAction](true);
            } else {
                this.triggerActionChanged[triggerAction](false);
            }

            if (value === 'when_page_is_ranking') {
                subtitle($t('Ranking 1 - %1').replace('%1', position));
            } else if (value === 'after_n_days') {
                subtitle($t('After %1 day/s').replace('%1', days));
            } else {
                subtitle($t('None'));
            }
        },

        /**
         * Show educational tooltip for non-transactional intent selection
         *
         * @param {String} intent
         * @return {void}
         */
        showEducationalTooltipForIntent: function (intent) {
            if (self.isAcknowledgedHeadsUp()) {
                return;
            }

            var searchIntent = self.searchIntent();
            if (searchIntent.length > 0 && searchIntent.indexOf(intent) !== -1) {
                self.selectIntent(intent);
                return;
            }

            var message = $t('Heads up! Product pages are typically intended for transactional search intent—users looking to make a purchase or take action. Using other intent types may be less effective unless your content is intentionally designed to inform, guide, or compare. Make sure it fits your overall SEO and content strategy.');

            /** Only show tooltip for non-transactional intents */
            if (intent === 'transactional') {
                return;
            }
            

            /** Find the target element for the selected intent */
            const targetSelector = '.wtai-search-intent-option:contains("' + intent + '")';
            const $targetElement = $(targetSelector);

            if ($targetElement.length > 0) {
                this.showHeadsUp(
                    message,
                    'top',
                    intent,
                    $targetElement
                );
            }
        },

        /**
         * Show the tooltip
         *
         * @param {string} message - The message to display
         * @param {string} position - Position of the tooltip
         * @param {jQuery|string} targetElement - Target element or selector
         * @returns {void}
         */
        showHeadsUp: function (message, position = 'top', intent = 'transactional', targetElement = null) {
            this.headsupVisibility.transactional(false);
            this.headsupVisibility.commercial(false);
            this.headsupVisibility.navigational(false);
            this.headsupVisibility.informational(false);

            if (this.isAcknowledgedHeadsUp()) {
                return;
            }

            this.messageHeadsUp(message);
            this.positionHeadsUp(position);
            this.targetElementHeadsUp = targetElement;
            this.headsupVisibility[intent](true);
        },

        /**
         * Acknowledge the heads up
         *
         * @param {string} intent - The intent to select
         * @returns {void}
         */
        acknowledgeHeadsUp: function (intent) {
            self.headsupVisibility.transactional(false);
            self.headsupVisibility.commercial(false);
            self.headsupVisibility.navigational(false);
            self.headsupVisibility.informational(false);
            self.selectIntent(intent);
        },

        /**
         * Bind click-outside handler for heads-up popup.
         */
        bindHeadsUpClickOutside: function () {
            $(document).on('click', function (event) {
                // Don't close if clicking on the intent button itself
                if ($(event.target).closest('.wtai-search-intent-option').length) {
                    return;
                }
                
                // Check if any heads-up popup is visible
                var isAnyHeadsUpVisible = self.headsupVisibility.transactional() ||
                                        self.headsupVisibility.commercial() ||
                                        self.headsupVisibility.navigational() ||
                                        self.headsupVisibility.informational();
                
                if (isAnyHeadsUpVisible && !$(event.target).closest('.wtai-educational-tooltip').length) {
                    // Close all heads-up popups
                    self.headsupVisibility.transactional(false);
                    self.headsupVisibility.commercial(false);
                    self.headsupVisibility.navigational(false);
                    self.headsupVisibility.informational(false);
                }
            });
        }
    });
});
