/*
 * Link Generator jQuery Plugin
 * Copyright (c) 2018 WEBimpuls Sp. z o. o. - https://www.webimpuls.pl/
 */
(function($) {
    var template = '<div class="link-generator-container">' +
        '<div class="link-generator-container-header">' +
            '<span>Insert link</span>' +
            '<span class="close" data-view="close">&times;</span>' +
        '</div>' +
        '<div class="link-generator-container-content">' +
            '<div class="link-generator-row" data-view="module">' +
                '<div class="link-generator-col-name" data-view="header-module">Moduł:</div>' +
                '<div class="link-generator-col-content">' +
                    '<select data-view="select-module">' +
                    '</select>' +
                '</div>' +
            '</div>' +
            '<div class="link-generator-row" data-view="module-link-to">' +
                '<div class="link-generator-col-name" data-view="header-link-to">link do:</div>' +
                '<div class="link-generator-col-content">' +
                    '<select data-view="select-link-to">' +
                    '</select>' +
                '</div>' +
            '</div>' +
            '<div class="link-generator-row" data-view="module-item">' +
                '<div class="link-generator-col-name" data-view="header-item">Element:</div>' +
                '<div class="link-generator-col-content">' +
                    '<select data-view="select-item">' +
                    '</select>' +
                '</div>' +
            '</div>' +
        '</div>' +
        '<div class="link-generator-container-footer">' +
            '<button class="submit" data-view="confirm">Ok</button>' +
            '<button class="cancel" data-view="cancel">Cancel</button>' +
        '</div>' +
    '</div>';

    var defaults = {
        link: '',
        linkModules: '',
        logger: false,
        template: template,
        container: {
            class: 'link-generator-container'
        },
        position: {
            top: 0,
            left: 0,
        },
    };

    /*
     * Logowanie zdarzeń.
     */
    function log(log) {
        if (defaults.logger) {
            console.log('[Link Generator] ' + log);
        }
    }

    /*
     * Pobieranie elementu widoku.
     */
    function selectorOf(view) {
        return '[data-view="' + view + '"]';
    }

    /*
     * Wysyłanie Ajax'a z żądzaniami.
     */
    function ajax(link, params = {}, method = 'GET') {
        var results = null;

        $.ajax({
            async: false,
            url: link,
            global: false,
            data: params,
            dataType: 'JSON',
            method: method,
            success: function (response) {
                results = response;
            }
        });

        return results;
    }

    /*
     * Pokazywanie/ukrywanie listy elementów.
     */
    function toggleItems(generator, $items) {
        $items.find('select').html('');

        if (typeof generator.items !== 'undefined' && generator.items.length > 0) {
            $items.removeClass('hide');

            $.each(generator.items, function (key, item) {
                $items.find('select').append('<option value="' + item.id + '">' + item.title + '</option>');
            });
        } else {
            $items.addClass('hide');
        }
    }

    function Plugin(element, options) {
        this.el = $(element);
        this.options = $.extend({}, defaults, options);
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            log('Init plugin.');

            var generator = this;
                generator.modules = this.getModules();

            generator.createContainer();

            var onFocusInEvent = function (e) {
            };
            var onFocusOutEvent = function (e) {
            };
            var onPasteEvent = function (e) {
               generator.close();
            };
            var onKeypressEvent = function (e) {
               generator.close();
            };
            var onClickEvent = function (e) {
               generator.show(e);
            };

            this.el.on('focusin', onFocusInEvent);
            this.el.on('focusout', onFocusOutEvent);
            this.el.on('paste', onPasteEvent);
            this.el.on('keypress', onKeypressEvent);
            this.el.on('click', onClickEvent);
        },

        close: function () {
            var container = $('.'+this.options.container.class);
                container.addClass('hide');

            this.reset();

            return container;
        },

        show: function (e) {
            var generator = this;
                generator.setPosition(e);
                var $input = e.target;
            var container = $('.'+generator.options.container.class+'[generatorid="'+generator.el.attr('generatorId')+'"]');
            container
                .css({
                    top: generator.options.position.top,
                    left: generator.options.position.left
                })
                .removeClass('hide')
            ;
        },

        createContainer: function () {
            var generator = this;
            var container = $(generator.options.template).addClass('hide');
            var generatorId = new Date().getTime();
            container.attr('generatorId', generatorId);
            generator.el.attr('generatorId', generatorId);
                container.find(selectorOf('close')).click(function (e) {
                    generator.close();
                });
                container.find(selectorOf('cancel')).click(function (e) {
                    generator.close();
                });

            var item = container.find(selectorOf('select-item'));
            var itemDiv = container.find(selectorOf('module-item'));
            var linkTo = container.find(selectorOf('select-link-to'));
            var linkToDiv = container.find(selectorOf('module-link-to'));
                linkToDiv.addClass('hide');
                itemDiv.addClass('hide');
            var module = container.find(selectorOf('select-module'));
                module
                    .html('')
                    .change(function (e) {
                        generator.items = generator.getItems({ 'module': $(this).val(), 'link_to': linkTo.val() });

                        item.html('');
                        linkTo.html('');

                        if (typeof generator.items !== 'undefined') {
                            if (generator.items.link_to.length > 0) {
                                linkToDiv.removeClass('hide');

                                $.each(generator.items.link_to, function (key, val) {
                                    var option = $('<option value="' + val.id + '">' + val.title + '</option>');

                                    if (val.id == generator.items.link_to_active) {
                                        option.prop('selected', true);
                                    }

                                    linkTo.append(option);
                                });
                            } else {
                                linkToDiv.addClass('hide');
                            }

                            if (generator.items.items.length > 0) {
                                itemDiv.removeClass('hide');

                                $.each(generator.items.items, function (key, val) {
                                    var option = $('<option value="' + val.id + '">' + val.title + '</option>');

                                    if (key == 0) {
                                        option.prop('selected', true);
                                    }

                                    item.append(option);
                                });
                            } else {
                                itemDiv.addClass('hide');
                            }
                        } else {
                            itemDiv.addClass('hide');
                            linkToDiv.addClass('hide');
                        }
                    });
                ;
                linkTo.change(function (e) {
                    module.change();
                });

            $.each(generator.modules, function (key, value) {
                module.append('<option value="' + key + '">' + value + '</option>');
            });
            container.find(selectorOf('confirm')).click(function (e) {
                var link = generator.generate({
                    'module': module.val(),
                    'item': item.val(),
                    'link_to': linkTo.val(),
                });

                $(generator.el).val(link);
                generator.close();
            });

            $('body').append(container);

            return container;
        },

        setPosition: function (e) {
            var position = $(e.target).offset();
            this.options.position.top = position.top + $(e.target).outerHeight();
            this.options.position.left = position.left;
        },

        reset: function () {
            this.options.position.top = 0;
            this.options.position.left = 0;
        },

        getModules: function () {
            log('Get modules.');

            return ajax(this.options.linkModules);
        },

        getItems: function (params) {
            log('Get items.');

            return ajax(this.options.linkItems, params, 'POST');
        },

        generate: function (params) {
            log('Generate link.');

            var results = ajax(this.options.link, params, 'POST');

            if (results.url) {
                return results.url;
            }

            return null;
        }
    };

    $.fn.linkGenerator = function(params) {
        var generators  = this,
            retval      = this;

        generators.each(function() {
            var plugin = $(this).data('linkGenerator');
            if (! plugin) {
                $(this).data('linkGenerator', new Plugin(this, params));
                $(this).data('linkGenerator-id', new Date().getTime());
            } else {
                if (typeof params === 'string' && typeof plugin[params] === 'function') {
                    retval = plugin[params]();
                }
            }
        });

        return retval || generators;
    };
}(jQuery));
