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

define([
    'jquery',
    'WriteTextAI_WriteTextAI/js/model/edit/textfields',
    'WriteTextAI_WriteTextAI/js/categories/model/edit/textfields',
    'mage/translate',
    'wysiwygAdapter'
], function ($, textfields, categoryTextFields, $t, wysiwygAdapter) {
    'use strict';

    /**
     * Ensure numerical.
     *
     * @param {String} keyValue
     * @returns {Boolean}
     */
    function ensureNumerical(keyValue)
    {
        if (keyValue.match(/[0-9]/g)) {
            return true;
        }

        return false;
    }

    /**
     * Update current fields.
     *
     * @param {Object} fields
     * @param {Array} selectedFields
     * @param {Object} writeTextFields
     *
     * @returns {Void}
     */
    function updateCurrentFields(fields, selectedFields, writeTextFields)
    {
        var statuses = textfields.statuses();

        if (selectedFields.includes('page_title') && writeTextFields.page_title) {
            textfields.mgPageTitle(fields.page_title);
            textfields.pageTitle(writeTextFields.page_title);
            textfields.originalPageTitle(writeTextFields.page_title);
            statuses['pageTitleTransferStatus'] = true;
        }
        if (selectedFields.includes('page_description') && writeTextFields.page_description) {
            textfields.mgPageDescription(fields.page_description);
            textfields.pageDescription(writeTextFields.page_description);
            textfields.originalPageDescription(writeTextFields.page_description);
            statuses['pageDescriptionTransferStatus'] = true;
        }
        if (selectedFields.includes('product_description') && writeTextFields.product_description) {
            textfields.mgProductDescription(fields.product_description);
            textfields.productDescription(writeTextFields.product_description);
            textfields.originalProductDescription(writeTextFields.product_description);
            statuses['productDescriptionTransferStatus'] = true;
        }
        if (selectedFields.includes('short_product_description')
            && writeTextFields.short_product_description) {
            textfields.mgProductShortDescription(
                fields.short_product_description
            );
            textfields.productShortDescription(writeTextFields.short_product_description);
            textfields.originalProductShortDescription(writeTextFields.short_product_description);
            statuses['productShortDescriptionTransferStatus'] = true;
        }
        if (selectedFields.includes('open_graph')  && writeTextFields.open_graph) {
            textfields.mgOpenGraph(fields.open_graph);
            textfields.openGraph(writeTextFields.open_graph);
            textfields.originalOpenGraph(writeTextFields.open_graph);
            statuses['openGraphTransferStatus'] = true;
        }
        textfields.statuses(statuses);
    }

    /**
     * Update current fields.
     *
     * @param {Object} fields
     * @param {Array} selectedFields
     * @param {Object} writeTextFields
     *
     * @returns {Void}
     */
    function updateCategoryCurrentFields(fields, selectedFields, writeTextFields)
    {
        var statuses = categoryTextFields.statuses();

        if (selectedFields.includes('page_title') && writeTextFields.page_title) {
            categoryTextFields.mgPageTitle(fields.page_title);
            categoryTextFields.originalPageTitle(writeTextFields.page_title);
            statuses['pageTitleTransferStatus'] = true;
        }
        if (selectedFields.includes('page_description') && writeTextFields.page_description) {
            categoryTextFields.mgPageDescription(fields.page_description);
            categoryTextFields.originalPageDescription(writeTextFields.page_description);
            statuses['pageDescriptionTransferStatus'] = true;
        }
        if (selectedFields.includes('category_description') && writeTextFields.category_description) {
            categoryTextFields.mgCategoryDescription(fields.category_description);
            categoryTextFields.originalCategoryDescription(writeTextFields.category_description);
            statuses['categoryDescriptionTransferStatus'] = true;
        }
        categoryTextFields.statuses(statuses);
    }

    /**
     * Get char count.
     *
     * @param {String} html
     * @param {Number} limit
     * @param {Boolean} unit
     *
     * @returns {Number}
     */
    function getCharCount(html = '', limit = null, unit = true)
    {
        var br2nl = html.replace(/<br\s*\/?>/g, '\n'),
            parseHtml = $($.parseHTML(br2nl)).text(),
            noHtmlTags = parseHtml.replace(/<[^>]*>/g, ''),
            count = noHtmlTags ? noHtmlTags.length : 0;

        if (!unit) {
            return count;
        }
        
        return count + (limit ? '/' + limit : '') + ' ' + $t('Char');
    }

    /**
     * Get word count.
     *
     * @param {String} html
     * @param {Boolean} unit
     *
     * @returns {Number}
     */
    function getWordCount(html = '', unit = true)
    {
        var br2nl = html.replace(/<br\s*\/?>/g, '\n'),
            parseHtml = $($.parseHTML(br2nl)).text(),
            noHtmlTags = parseHtml.replace(/<[^>]*>/g, ''),
            words = noHtmlTags.toLowerCase().match(/\b(?:[\w'‘’′]+(?:[.-][\w'‘’′]+)*|[\w'‘’′]+)\b/g),
            count = words ? words.length : 0;

        if (!unit) {
            return count;
        }

        return count + ' ' + $t('word/s');
    }

    /**
     * Count keyword occurences.
     *
     * @param {String} html
     * @param {String} keyword
     *
     * @returns {Number}
     */
    function countKeywordOccurences(html, keyword)
    {
        var br2nl = html.replace(/<br\s*\/?>/g, '\n'),
            parseHtml = $($.parseHTML(br2nl)).text(),
            noHtmlTags = parseHtml.replace(/<[^>]*>/g, '');
        var escapedString = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        return (noHtmlTags.match(new RegExp(escapedString, "mgi")) || []).length;
    }

    /**
     * Check if text is over limit.
     *
     * @param {String} html
     * @param {Number} limit
     *
     * @returns {Boolean}
     */
    function isOverLimit(html, limit)
    {
        let tempDiv = document.createElement("div");
            tempDiv.innerHTML = html;
        let renderedText = tempDiv.textContent || tempDiv.innerText;

        return renderedText.length > limit;
    }

    function highlightWords(element, valueAccessor)
    {
        try {
            var values = valueAccessor(),
                id = $(element).prop('id'),
                allKeywords = values.keywords,
                formalLanguages = values.formalLanguages(),
                formalLanguageSupport = values.formalLanguageSupport(),
                language = values.language(),
                formal = values.formal() ? 'Informal' : '',
                highlightPronouns = values.highlightPronouns(),
                isGallery = values.gallery || false,
                text = isGallery ? values.text : values.text(),
                galleryImages = isGallery ? values.galleryImages() : {}, /** used to trigger highlight if alt text is changed */
                formalLanguage =
                    typeof formalLanguages === 'object' && formalLanguages
                        ? formalLanguages.find((item) => item.id === formal)
                        : null,
                pronouns = formalLanguage ? formalLanguage.pronouns : [],
                escapedKeywords = '',
                escapedPronouns = '',
                pattern = '',
                ppattern = '',
                highlightedText = '',
                isHighlighted = true; /** values.highlighted(). force true */

            if (!Array.isArray(pronouns)) {
                pronouns = [];
            } else if (pronouns.length === 1 && (pronouns[0] === '' || pronouns[0] === null || pronouns[0] === undefined)) {
                pronouns = [];
            }

            allKeywords = values.selectedKeywords() || [];
            if (values.optimizationData()) {
                if (values.optimizationData().optimizingKeywords !== undefined
                    && values.optimizationData().optimizingKeywords.length > 0
                ) {
                    allKeywords = values.optimizationData().optimizingKeywords;
                }
            }

            function escapeRegex(str)
            {
                return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
            }

            if (typeof allKeywords !== 'undefined' && allKeywords.length > 0) {
                /* Escape special characters in words to avoid issues with regex */
                /** escapedKeywords = allKeywords.map(function (keyword) {
                    return keyword.replace(
                        /[-\/\\^$*+?.()|[\]{}]/g,
                        '\\$&'
                    );
                }); */
                
                escapedKeywords = allKeywords.map(escapeRegex);
            }

            /** escapedPronouns = pronouns.map(function (pronoun) {
                return pronoun.replace(
                    /[-\/\\^$*+?.()|[\]{}]/g,
                    '\\$&'
                );
            }); */
            escapedPronouns = pronouns.map(escapeRegex);

            if (typeof allKeywords !== 'undefined' && allKeywords.length > 0) {
                /* Create a regular expression pattern to match the phrases */
                pattern = new RegExp(
                    '(?:[^\\p{L}]|^)(' + escapedKeywords.join('|') + ')(?:[^\\p{L}]|$)',
                    'giu'
                );
            }

            ppattern = new RegExp(
                '(?:[^\\p{L}]|^)(' + escapedPronouns.join('|') + ')(?:[^\\p{L}]|$)',
                'gu'
            );

            highlightedText = text;
            if (typeof allKeywords !== 'undefined' && allKeywords.length > 0) {
                if (isHighlighted) {
                    if (allKeywords.length > 0) {
                        highlightedText = highlightedText.replace(pattern, function (match, group1) {
                            return match.replace(group1, `<span class="wtai-highlight-keyword">${group1}</span>`);
                        });
                    }
                }
            }
                
            if (highlightPronouns &&
                formalLanguageSupport.includes(language) &&
                pronouns.length > 0
            ) {
                highlightedText = highlightedText.replace(ppattern, function (match, group1) {
                    return match.replace(group1, `<span class="wtai-highlight-pronoun">${group1}</span>`);
                });
            }

            highlightedText =  '<span class="wtai-highlighted-text">' + highlightedText + '</span>';
            
            if (['wtaiPageTitleMask',
                'wtaiPageDescMask',
                'wtaiOpenGraphMask'
            ].includes(element.id)) {
                $(element).html(highlightedText);
            }

            if (element.classList.contains('wtai-gallery-mask')) {
                $(element).html(highlightedText);
            }

            if (wysiwygAdapter.get(id)) {
                wysiwygAdapter.get(id).setContent(highlightedText);
            }
        } catch (e) {
            console.log('highilight failed', e);
        }
    }

    /**
     * Convert new lines to <br> tags.
     *
     * @param {String} text
     *
     * @returns {String}
     */
    function convertNewLinesToBr(text)
    {
        if (!/<br\s*\/?>/i.test(text) && !text.includes('<li>') && !text.includes('<ul>')) {
            text = text.replace(/(\r\n|\n\r|\r|\n)/g, '<br />');
        }

        return text;
    }

    return {
        ensureNumerical: ensureNumerical,
        updateCurrentFields: updateCurrentFields,
        updateCategoryCurrentFields: updateCategoryCurrentFields,
        getCharCount: getCharCount,
        getWordCount: getWordCount,
        countKeywordOccurences: countKeywordOccurences,
        isOverLimit: isOverLimit,
        highlightWords: highlightWords,
        convertNewLinesToBr: convertNewLinesToBr
    };
});
