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

define([
    'jquery',
    'underscore',
    'mage/translate',
    'WriteTextAI_WriteTextAI/js/model/edit/keywords/keyword-analysis'
], function (
    $,
    _,
    $t,
    keywordAnalysis
) {
    'use strict';

    /**
     * See more details
     *
     * @param {*} self
     * @param {*} data
     * @param {*} event
     *
     * @returns {void}
     */
    function seeMoreData(self, data, event)
    {
        $('.wtai-keyword.active-details')
            .not(event.currentTarget)
            .removeClass('active-details');
        
        if ($(event.currentTarget).hasClass('active-details')) {
            $(event.currentTarget).removeClass('active-details');
            return;
        }
        adjustPositionMoreData(self, $(event.currentTarget));
        $(event.currentTarget).addClass('active-details');
    }

    /**
     * Adjust position of see more keyword data
     *
     * @param {*} self
     * @param {*} liElement
     *
     * @returns {void}
     */
    function adjustPositionMoreData(self, liElement)
    {
        /** Get DOM elements */
        var button = liElement[0];
        var container = document.querySelector('.wtai-pipelines-content');
        var content = liElement.find('.wtai-keyword-more-data');

        /** Get dimensions and positions */
        var buttonRect = button.getBoundingClientRect();
        var containerRect = container.getBoundingClientRect();
        var popupHeight = content.outerHeight(true);
        
        /** Calculate available space */
        var spaceTop = buttonRect.top - containerRect.top;
        var spaceBottom = containerRect.bottom - buttonRect.bottom;

        if (spaceBottom < popupHeight) {
            if (spaceTop > popupHeight) {
                content.addClass("wtai-show-upwards");
            }
        } else {
            content.removeClass("wtai-show-upwards");
        }
    }

    /**
     * Adjust position of serp popup
     *
     * @param {*} self
     * @param {*} activeButton
     *
     * @returns {void}
     */
    function adjustPositionSerp(self, activeButton)
    {
        /** Get DOM elements */
        var keywordContainer = activeButton.closest('.wtai-keyword-data');
        var referenceContainer = keywordContainer[0];
        var container = document.querySelector('.wtai-pipelines-content');
        var content = keywordContainer.find('.wtai-serp-popup');

        /** Get dimensions and positions */
        var referenceRect = referenceContainer.getBoundingClientRect();
        var containerRect = container.getBoundingClientRect();
        var popupWidth = content.outerWidth(true);
        var popupHeight = content.outerHeight(true);
        
        /** Calculate available space */
        var spaceBottom = containerRect.bottom - referenceRect.bottom;
        var spaceRight = containerRect.right - referenceRect.right;

        if (spaceRight < popupWidth) {
            if (spaceBottom < popupHeight) {
                content.addClass("wtai-left-higher");
            } else {
                content.addClass("wtai-left-lower");
            }
        } else {
            if (spaceBottom < popupHeight) {
                content.addClass("wtai-right-higher");
            }
        }
    }

    /**
     * Are all keywords above skipped
     *
     * @param {Object} self
     * @param {string} difficulty
     * @param {Object} keywords
     *
     * @returns {boolean}
     */
    function areAllKeywordsAboveSkipped(self, difficulty, keywords)
    {
        switch (difficulty) {
            case 'High':
                return false;
            case 'MidHigh':
                return keywords['High'] === undefined;
            case 'Mid':
                return keywords['MidHigh'] === undefined &&
                    keywords['High'] === undefined;
            case 'LowMid':
                return keywords['Mid'] === undefined &&
                    keywords['MidHigh'] === undefined &&
                    keywords['High'] === undefined;
            case 'Low':
                return keywords['LowMid'] === undefined &&
                    keywords['Mid'] === undefined &&
                    keywords['MidHigh'] === undefined &&
                    keywords['High'] === undefined;
        }
    }

    /**
     * Is previous 'none'
     *
     * @param {Object} self
     * @param {string} difficulty
     * @param {string} id
     *
     * @returns {boolean}
     */
    function isPreviousNone(self, difficulty, id)
    {
        if (self.historyMode()) {
            return true;
        }

        var pipelineList = keywordAnalysis.optimizationData().pipelines;
        var pipeline = pipelineList.find(pipeline => pipeline.id === id);
        var triggers = pipeline.triggers;
        if (self.isCurrent(difficulty, pipeline.currentLevel)) {
            return false;
        }

        switch (difficulty) {
            case 'High': return true;
            case 'MidHigh':
            case 'Mid':
            case 'LowMid':
                return ['Mid', 'LowMid', 'Low']
                    .slice(['MidHigh', 'Mid', 'LowMid'].indexOf(difficulty))
                    .some(level => triggers[level]?.option === 'None' && pipeline.keywords[level]);
            case 'Low': return false;
        }

        return false;
    }

    /**
     * Is next optimizing
     *
     * @param {Object} self
     * @param {string} difficulty
     * @param {string} currentLevel
     * @param {Array} keywords
     *
     * @returns {boolean}
     */
    function isNext(self, difficulty, currentLevel, keywords = [])
    {
        if (Object.keys(keywords).length) {
            const levels = {
                'High': ['MidHigh', 'Mid', 'LowMid', 'Low'],
                'MidHigh': ['Mid', 'LowMid', 'Low'],
                'Mid': ['LowMid', 'Low'],
                'LowMid': ['Low'],
                'Low': []
            };
            
            if (levels[difficulty]) {
                for (const level of levels[difficulty]) {
                    if (keywords[level] !== undefined) {
                        return currentLevel === level;
                    }
                }
            }

            return false;
        }

        return !self.isCurrent(difficulty, currentLevel) && !isPrevious(difficulty, currentLevel);
    }

    /**
     * Count skipped keywords directly before the current difficulty
     *
     * @param {Object} self
     * @param {string} difficulty
     * @param {Array} keywords
     *
     * @returns {number}
     */
    function countSkippedKeywords(self, difficulty, keywords)
    {
        var totalCount = 0;
        for (var i = 0; i < self.pipelineDifficulties.length; i++) {
            if (self.pipelineDifficulties[i] === difficulty) {
                break;
            }

            if (keywords[self.pipelineDifficulties[i]] === undefined) {
                totalCount++;
            }

            if (keywords[self.pipelineDifficulties[i]] !== undefined) {
                totalCount = 0;
            }
        }
        return totalCount;
    }

    /**
     * Is previous keyword in pipeline skipped
     *
     * @param {Object} self
     * @param {string} difficulty
     * @param {Object} keywords
     *
     * @returns {boolean}
     */
    function isPreviousSkipped(self, difficulty, keywords)
    {
        switch (difficulty) {
            case 'High':
                return false;
            case 'MidHigh':
                return keywords['High'] === undefined;
            case 'Mid':
                return keywords['MidHigh'] === undefined;
            case 'LowMid':
                return keywords['Mid'] === undefined;
            case 'Low':
                return keywords['LowMid'] === undefined;
        }
    }

    /**
     * Get current state
     *
     * @param {string} apiState
     * @returns {string}
     */
    function getCurrentState(apiState)
    {
        switch (apiState) {
            case 'Unused':
                return '';
            case 'ForGeneration':
                return $t('Not applied in text');
            case 'Generated':
                return $t('Applied in text');
            case 'Published':
                return $t('Transferred to Magento');
            case 'Optimized':
                return $t('Optimized');
        }
    }

    /**
     * Is previous optimized
     *
     * @param {string} difficulty
     * @param {string} currentLevel
     *
     * @returns {boolean}
     *
     */
    function isPrevious(difficulty, currentLevel)
    {
        switch (difficulty) {
            case 'High':
                return false;
            case 'MidHigh':
                return 'High' === currentLevel;
            case 'Mid':
                return 'MidHigh' === currentLevel ||
                    'High' === currentLevel;
            case 'LowMid':
                return 'Mid' === currentLevel ||
                    'MidHigh' === currentLevel ||
                    'High' === currentLevel;
            case 'Low':
                return 'LowMid' === currentLevel ||
                    'Mid' === currentLevel ||
                    'MidHigh' === currentLevel ||
                    'High' === currentLevel;
        }
    }

    return {
        seeMoreData: seeMoreData,
        adjustPositionSerp: adjustPositionSerp,
        areAllKeywordsAboveSkipped: areAllKeywordsAboveSkipped,
        isPreviousNone: isPreviousNone,
        isNext: isNext,
        countSkippedKeywords: countSkippedKeywords,
        isPreviousSkipped: isPreviousSkipped,
        getCurrentState: getCurrentState,
        isPrevious: isPrevious
    };
});
