var AutoCompletionHelper = (function () {
    var resolveOptions = function (customOptions) {
        var defaultOptions = {
            originTitleElement: null,
            targetTitleElements: [],
            originDescriptionElement: null,
            targetDescriptionElements: [],
            allowOverrideData: false,
            slugElement: null,
            forceSlugBehaviour: false,
            multipleElementSeparator: " ",
            toasterMessage: Translator.trans('cs_common_base.form.toaster_message.default'),
            toasterInfoMessage: Translator.trans('cs_common_base.form.toaster_multioption_message.info'),
            cutSeoFields: 1,
            targetTitleLength: 60,
            targetDescriptionLength: 120,
            stopWords: [],
            multipleOptions: []
        };

        return Object.assign(defaultOptions, customOptions);
    };

    var resolveTitleCompletion = function (options) {
        options.originTitleElement.on("change", function () {
            if (options.allowOverrideData === true) {
                copy(
                    options.originTitleElement,
                    options.targetTitleElements,
                    options.targetTitleLength,
                    options
                );

                makeSlug(options.originTitleElement, options);
            } else if (options.forceSlugBehaviour === true) {
                makeSlug(options.originTitleElement, options);
            } else {
                buildToaster(options.originTitleElement, options);
            }
        });
    };

    var resolveMultipleTitleCompletion = function (options) {
        for (var i = 0; i < options.originTitleElement.length; i++) {
            options.originTitleElement[i].on("change", function () {
                if (options.allowOverrideData === true) {
                    copy(
                        options.originTitleElement,
                        options.targetTitleElements,
                        options.targetTitleLength,
                        options
                    );

                    makeSlug(options.originTitleElement, options);
                } else {
                    buildToaster($(this), options);
                }
            });
        }
    };

    var resolveDescriptionCompletion = function (options) {
        if (options.originDescriptionElement) {
            var descriptionElementForEvent = options.originDescriptionElement;

            if (CKEDITOR.instances[options.originDescriptionElement.attr("id")]) {
                descriptionElementForEvent = CKEDITOR.instances[options.originDescriptionElement.attr("id")];
            }

            descriptionElementForEvent.on("blur", function () {
                copy(
                    options.originDescriptionElement,
                    options.targetDescriptionElements,
                    options.targetDescriptionLength,
                    options
                );
            });
        }
    };

    var copy = function (
        originElement,
        targetElements,
        targetElementsLength,
        options
    ) {
        if (!originElement || !targetElements) {
            return;
        }

        for (var i = 0; i < targetElements.length; i++) {
            var targetElement = targetElements[i];
            var originData;

            if (originElement instanceof Array) {
                originData = originElement;
            } else {
                originData = $.trim(ComitiumUtils.getElementData(originElement));
            }

            if (originData.length > 0) {
                AutoFieldCompletion.copy({
                    originElement: originElement,
                    targetElement: targetElement,
                    multipleElementSeparator: options.multipleElementSeparator,
                    beforeCopy: function (data) {
                        data = ComitiumUtils.htmlEncode(data);
                        data = ComitiumUtils.stripTags(data);

                        if (hasToCutText(options)) {
                            if (originElement instanceof Array) {
                                data = cutText(data, originElement[0], targetElementsLength);
                            } else {
                                data = cutText(data, originElement, targetElementsLength);
                            }
                        }

                        return data;
                    }
                });
            }
        }
    };

    var cleanStopWords = function (data, options) {
        for (var i = 0; i < options.stopWords.length; i++) {
            data = data.replace(options.stopWords[i], " ");
        }

        return data;
    };

    var hasToCutText = function (options) {
        return Boolean(options.cutSeoFields);
    };

    var cutText = function (data, element, length) {
        var elementDataCut = Number(element.data("cut"));

        if (elementDataCut > 0) {
            return ComitiumUtils.cutText(data, elementDataCut);
        }

        return ComitiumUtils.cutText(data, length);
    };

    var makeSlug = function (element, options) {
        if (options.forceSlugBehaviour === true) {
            ComitiumUtils.displaySlugMessage(element);
        }

        var text = "";

        if (element instanceof Array) {
            for (var i = 0; i < element.length; i++) {
                text = text + element[i].val() + options.multipleElementSeparator;
            }
        } else {
            text = element.val();
        }

        if (options.slugElement) {
            text = cleanStopWords(text, options);

            ComitiumUtils.makeSlug(text, function (slugResult) {
                options.slugElement.val(slugResult);
            });
        }
    };

    var makeSlugs = function (elements, options) {
        for (var i = 0; i < elements.length; i++) {
            options.slugElement = elements[i];

            makeSlug(options.originTitleElement, options);
        }
    };

    var buildToaster = function (element, options) {
        function createFunction (i) {
            return function () {
                if (typeof options.multipleOptions[i].targetTitleElements !== "undefined") {
                    copy(
                        options.originTitleElement,
                        options.multipleOptions[i].targetTitleElements,
                        options.targetTitleLength,
                        options
                    );

                    if (typeof options.multipleOptions[i].sluggableElements !== "undefined" && options.multipleOptions[i].sluggableElements.length > 0) {
                        makeSlugs(options.multipleOptions[i].sluggableElements, options);
                    }
                }
            };
        }

        if (options.multipleOptions.length > 0) {
            var toasterMultipleOptions = [];

            for (var i = 0; i < options.multipleOptions.length; i++) {
                toasterMultipleOptions.push({
                    id: options.multipleOptions[i].id,
                    message: options.multipleOptions[i].message,
                    callBack: createFunction(i)
                });
            }

            ComitiumUtils.displayMultiOptionToaster(element, options.toasterMessage, options.toasterInfoMessage, toasterMultipleOptions);
        } else {
            ComitiumUtils.displayToasterMessage(element, options.toasterMessage, function () {
                copy(
                    options.originTitleElement,
                    options.targetTitleElements,
                    options.targetTitleLength,
                    options
                );
            });
        }
    };

    return {
        handleTitle: function (customOptions) {
            var options = resolveOptions(customOptions);

            if (options.originTitleElement instanceof Array) {
                resolveMultipleTitleCompletion(options);
            } else {
                resolveTitleCompletion(options);
            }
        },
        handleDescription: function (customOptions) {
            var options = resolveOptions(customOptions);

            resolveDescriptionCompletion(options);
        }
    };
})();
