var SocialNetworkPlanner = (function ($) {

    var calendar,
        currentLocales = [],
        currentSocialNetworks = [],
        page = 1,
        searchKeyUpTimeout = null,
        options = {},
        socialNetworksToFilterBy = []
    ;

    /*
     * Constructor
     */
    function SocialNetworkPlanner() {
        this.locale = document.documentElement.lang;
    }

    SocialNetworkPlanner.prototype.init = function (calendarOptions) {
        this.initCalendar(calendarOptions);
        this.initDraggable();
        var _this = this;

        bindSearch(function () {
            _this.initDraggable();
        });

        bindConfig();
    };

    SocialNetworkPlanner.prototype.initDraggable = function () {
        $('[data-item]').each(function () {

            $(this).data('eventObject', $(this).data('item'));

            $(this).draggable({
                zIndex: 999,
                revert: true,
                revertDuration: 0
            });
        });
    };

    SocialNetworkPlanner.prototype.initCalendar = function (options) {

        calendar = $('#calendar');

        var defaultOptions = {
            header: {
                left: 'title',
                center: '',
                right: 'prev,next,agendaDay, agendaWeek, month, listWeek'
            },
            defaultView: 'agendaWeek',
            slotDuration: '00:30:00',
            slotLabelInterval: '00:30:00',
            snapDuration: '00:30:00',
            slotLabelFormat: "H:mm",
            scrollTime: moment().format("HH:mm:ss"),
            editable: true,
            droppable: true,
            locale: this.locale,
            allDaySlot: false,
            eventLimit: true,
            slotEventOverlap: false,
            allDay: false,
            forceEventDuration: false,
            viewRender: function () {
                updateCalendarEvents();
            },
            drop: function (date, jsEvent, ui, resourceId) {
                var isPastDate = date.isBefore(new Date());

                if (isPastDate === false) {
                    dropCalendarEventProcess(date, jsEvent, $(this));
                } else {
                    var el = $('<div></div>')
                        .css({"position": "absolute", "top": jsEvent.clientY, "left": jsEvent.clientX, "z-index": 9999})
                        .addClass('forbidden-message')
                        .text(Translator.trans('social_network.planner.forbidden_drop'))
                    ;

                    $("body").append(el)

                    setTimeout(function () {
                        el.fadeOut(1000, function () {
                            $(this).remove();
                        })
                    }, 1500);

                }
            },
            eventDragStart: function (date, jsEvent, ui, resourceId) {
                if (jsEvent.shiftKey === false) return;
            },
            events: function (start, end, timezone, callback) {
                $.ajax({
                    url: Routing.generate("cs_admin_social_network_planner_events", {
                        start: start.format("YYYY-MM-DD"),
                        end: end.format("YYYY-MM-DD"),
                        snToFilterBy: fetchSnToFilterBy(),
                        "_": Math.random()
                    }),
                    method: "GET",
                    success: function (response) {
                        callback(response);
                    }
                });
            },
            loading: function (isLoading, view) {
                if (isLoading) {
                    ComitiumUtils.showSpinner();
                } else {
                    ComitiumUtils.hideSpinner();
                }
            },
            eventRender: function (event, element, view) {
                if (view.name !== "listWeek") {

                    var eventObject = {
                        viewOptions: {
                            displayInterval: false,
                            displayFutureInfoShape: event.isPublishedForFuture,
                            forcedStartDate: event.isPublishedForFuture ? moment(event.entityPublishDate, moment.ISO_8601) : ""
                        },
                        entityId: event.entityId,
                        entityClass: event.entityClass
                    };

                    var date = moment(event.start, moment.ISO_8601);

                    var toolTipContent = event.title;
                    toolTipContent += " - ";
                    toolTipContent += date.format("HH:mm");

                    element.attr("data-toggle", "popover");
                    element.attr("data-content", toolTipContent);
                    element.attr("data-item-in-calendar", "");
                    element.attr("data-eventObject", JSON.stringify(eventObject));
                    element.html('<div class="fc-event-inner">' +
                        '<span class="fc-event-type">' +
                        htmlProfileIcons(event.profiles) +
                        '</span>' +
                        '</div>'
                    );

                    if (event.standBy) {
                        element.addClass("standby");
                    }
                    if (event.hasError) {
                        element.addClass("event-has-error");
                        element.attr("data-error-message", event.errorMessage);
                    }

                    $(".popover").remove();

                    element.popover({
                        trigger: "hover",
                        placement: "bottom",
                        delay: {"show": 800, "hide": 100}
                    });
                }

                if (view.name === "listWeek") {
                    var ael = element.find('.fc-list-item-marker');
                    ael.append(htmlProfileIcons(event.profiles));
                }
            },
            eventClick: function (event) {
                editCalendarEventProcess(event);
            },
            eventDrop: function (event, delta, revertFunc, jsEvent, ui, view) {
                if (jsEvent.shiftKey === true) {
                    copyCalendarEventProcess(event, moment(event.start), $(this), revertFunc);
                }
                updateCalendarEventProcess(event);
            }
        };

        options = $.extend(defaultOptions, options);

        calendar.removeAttr("data-events");
        calendar.fullCalendar('destroy');
        calendar.fullCalendar(options);
    };

    SocialNetworkPlanner.prototype.triggerEdit = function (data, options) {
        editIsolatedProcess(data, options);
    };

    SocialNetworkPlanner.prototype.triggerCreate = function (data, options) {
        createIsolatedProcess(data, options);
    };

    function bindConfig() {
        var configEl = $('[data-action="update-calendar-config"]');

        configEl.each(function () {
            var configParams = $(this).data("value").split(",");
            var defaultValue = $(this).data("default") || null;
            var _this = $(this);

            $.each(configParams, function (k, configParam) {
                var data = calendar.fullCalendar('option', configParam);

                if (data) {
                    _this.val(data);
                } else if (defaultValue) {
                    _this.val(defaultValue);
                }
            });
        });


        configEl.on("change", function () {
            var configParams = $(this).data("value").split(",");
            var value = $(this).val();

            if (value) {
                $.each(configParams, function (k, configParam) {
                    calendar.fullCalendar('option', configParam, value);
                    $.cookie('fullCalendar.' + configParam, value)
                });
            }
        });

        configEl.each(function () {
            var configParams = $(this).data("value").split(",");
            var defaultValue = $(this).data("default");
            var _this = $(this);

            $.each(configParams, function (k, configParam) {
                var value = $.cookie('pagination.' + configParam) || defaultValue;

                if (value) {
                    _this.val(value);
                }
            });
        });

        configEl.on("change", function () {
            var configParams = $(this).data("value").split(",");
            var value = $(this).val();

            if (value) {
                $.each(configParams, function (k, configParam) {
                    $.cookie('pagination.' + configParam, value)
                });
            }
        });
    }

    function handleLocaleDependingElements(form) {
        currentLocales = [];
        currentSocialNetworks = [];
        var triggerTab = true;

        $('[data-tab], [data-tab-content]', form).addClass("disabled");
        $('[data-id="charCounterFb"],[data-id="charCounterTw"]').hide();

        $('[name*="[socialNetworkProfiles]"]', form).each(function () {
            var locale = $(this).data("locale");
            var socialNetwork = $(this).data("socialNetwork");
            var isChecked = $(this).is(":checked");

            if (isChecked) {
                if ($.inArray(locale, currentLocales) === -1) {
                    currentLocales.push(locale);

                    if (triggerTab === true) {
                        $('[data-tab=' + locale + ']').trigger('click');
                        triggerTab = false;
                    }
                }

                if ($.inArray(socialNetwork, currentSocialNetworks) === -1) {
                    currentSocialNetworks.push(socialNetwork);

                    if (socialNetwork == "facebook") {
                        $('[data-id="charCounterFb"]').show();
                        updateCounters($('[name$="[message]"]'));
                    }

                    if (socialNetwork == "twitter") {
                        $('[data-id="charCounterTw"]').show();
                        updateCounters($('[name$="[message]"]'));
                    }
                }
            }

            $('[data-tab]', form).each(function () {
                var tabLocale = $(this).data("tab");

                if (currentLocales.length && $.inArray(tabLocale, currentLocales) !== -1) {
                    $(this).removeClass("disabled");
                    $('[data-tab-content="' + tabLocale + '"]').removeClass("disabled");
                }
            });
        });

        if (triggerTab === true) {
            $('[data-tab]', form)
                .first()
                .trigger('click');
        }

        $('[name$="[message]"]').each(function () {
            $(this).on("keyup", function () {
                updateCounters($(this));
            });
        });
    }

    function updateCounters(element) {
        var length = Number($.trim(element.val()).length) || 0;

        element.parents(".form-group").next().find("[data-sn-limit]").each(function () {
            var limit = Number($(this).data("snLimit"));
            var currentValue = Number($(this).text());
            var socialNetwork = $(this).data("socialNetwork");
            var value = limit - length;

            if ($.inArray(socialNetwork, currentSocialNetworks) !== -1) {
                if (value < 0) {
                    $(this).parent().css("color", "red");
                    toggleSubmit(true);
                } else {
                    $(this).parent().css("color", "inherit");
                    toggleSubmit(false);
                }

                $(this).text(value);
            }
        });
    }

    function toggleConfig() {
        $("#social-planner-config").slideToggle();
        $("#social-planner-config-btn").toggleClass('active');
    }

    function toggleSubmit(enabled) {
        $('button[data-btn-type="save"]', ".modal-planner").attr("disabled", enabled);
    }

    function htmlProfileIcons(profiles) {
        var html = "<span class='sn-icons'>";

        $.each(profiles, function (k, profile) {
            html += '<i class="fa fa-' + profile.name + '" style="color:' + profile.color + '"></i>';
        });

        html += "</span>";

        return html;
    }

    function getPaginationLimit() {
        return $.cookie('pagination.pagination-limit') || 5
    }

    function resetSearchInput() {
        $("#planner-search-input").val('');
    }

    function getSearchValue() {
        return $.trim($("#planner-search-input").val());
    }

    function getStatusValue() {
        var val = $('#status_search_field').val();
        return val !== null ? val.join(",") : "";
    }

    function updateCalendarEvents() {
        calendar.fullCalendar('removeEvents');
        calendar.fullCalendar('refetchEvents');
    }

    var snFilterTimeout = null;

    $("[data-sn-filter]").on("click", function (e) {
        if (snFilterTimeout != null) {
            clearTimeout(snFilterTimeout);
        }

        handleSocialNetworkFilter($(this));
        snFilterTimeout = setTimeout(function () {
            updateCalendarEvents();
        }, 600)
    });

    function handleSocialNetworkFilter(element) {
        var val = element.val();
        if (socialNetworksToFilterBy.includes(val)) {
            removeSocialNetworkFromFilter(val);
            removeActiveClass(element);
            element.checked = false;
        } else {
            addSocialNetworkToFilter(val);
            addActiveClass(element);
            element.checked = true;
        }
    }

    function addSocialNetworkToFilter(val) {
        socialNetworksToFilterBy.push(val);
    }

    function removeSocialNetworkFromFilter(val) {
        var position = socialNetworksToFilterBy.indexOf(val);

        if (position !== -1) {
            socialNetworksToFilterBy.splice(position, 1);
        }
    }

    function addActiveClass(elem) {
        elem.parent('label').addClass('active');
    }

    function removeActiveClass(elem) {
        elem.parent('label').removeClass('active');
    }

    function fetchSnToFilterBy() {
        return socialNetworksToFilterBy;
    }

    function bindSearch(callBack) {

        $("#planner-search-button-clear").on("click", function (e) {
            e.preventDefault();
            page = 1;
            resetSearchInput();

            initSearch({
                term: getSearchValue(),
                //type: '102,103,104,108,117,127',
                type: '102',
                state: getStatusValue(),
                limit: getPaginationLimit(),
            }, callBack);
        });

        $("#planner-search-input").on("keyup", function (e) {
            e.preventDefault();

            if (searchKeyUpTimeout) {
                clearTimeout(searchKeyUpTimeout);
            }

            searchKeyUpTimeout = setTimeout(function () {
                var term = getSearchValue();

                if (term) {
                    page = 1;
                    initSearch({
                        term: term,
                        //type: '102,103,104,108,117,127',
                        type: '102',
                        state: getStatusValue(),
                        limit: getPaginationLimit(),
                    }, callBack);
                }
            }, 600);

        });

        $('#status_search_field').on("change", function (e) {
            e.preventDefault();

            var term = getSearchValue();

            page = 1;
            initSearch({
                term: term,
                //type: '102,103,104,108,117,127',
                type: '102',
                state: getStatusValue(),
                limit: getPaginationLimit(),
            }, callBack);
        });

        $("#planner-search-lasted").on("click", function (e) {
            e.preventDefault();
            resetSearch();

            initSearch({
                term: getSearchValue(),
                //type: '102,103,104,108,117,127',
                type: '102',
                state: getStatusValue(),
                limit: getPaginationLimit(),
            }, callBack);
        });

        $("#planner-search-clear").on("click", function (e) {
            e.preventDefault();
            resetSearch();
        });

        $('[data-action="search-more"]').on("click", function (e) {
            e.preventDefault();

            var behaviour = $(this).data('behaviour');

            if (behaviour === 'prev') {
                if (page > 1) {
                    --page;
                }
            } else {
                ++page
            }

            initSearch({
                term: getSearchValue(),
                //type: '102,103,104,108,117,127',
                type: '102',
                state: getStatusValue(),
                limit: getPaginationLimit(),
                page: page
            }, callBack);
        });

        $("#social-planner-config-btn").on("click", function (e) {
            e.preventDefault();
            toggleConfig();
        });

    }

    function resetSearch() {
        page = 1;
        $('[data-container="search-results"]').empty();
        resetSearchInput();
        $(".calendar .portlet-body").removeClass("show-items");
    }

    function initSearch(data, callBack) {

        $.ajax({
            url: Routing.generate("cs_admin_social_network_planner_search", {'order': 'date'}),
            data: data,
            dataType: "json",
            method: "get",
            beforeSend: function () {
                ComitiumUtils.showSpinner();
            },
            complete: function () {
                ComitiumUtils.hideSpinner();
            },
            success: function (response) {
                if (response.count === 0) {
                    $('.social-planner-items .info').hide();
                    $('.social-planner-items-paginator').hide();
                } else {
                    $('.social-planner-items .info').show();
                    $('.social-planner-items-paginator').show();
                }
                $('[data-container="search-results"]').html(response.html);
                $(".calendar .portlet-body").addClass("show-items");
                $('[data-behaviour="next"]').attr('disabled', response.isLast);
                $('[data-behaviour="prev"]').attr('disabled', page <= 1);

                callBack.call(this);
            },
            error: function () {

            }
        });
    }

    /*
     * Error handler for all exceptions
     */
    function errorHandler(anError) {
        showToastrNotification('error', anError.message);
    }

    /*
     * Edit calendar event promises
     * When an event has been clicked
     */
    function createIsolatedProcess(data, options) {

        this.options = options;

        Q.fcall(createEventForm, moment(), null, data, 0)
            .then(displayModalForm)
            .then(bindUrlFetchToInput)
            .then(initFormActions)
            .then(function (data) {
                var deferred = Q.defer();

                handleFormWellKnownErrors(data, function (data) {
                    closeModal();

                    if (typeof this.options.onCreateCallback === 'function' && data.action === 'create') {
                        this.options.onCreateCallback.call(this, data);
                    }
                });

                return deferred.promise;
            })
            .catch(function (anError) {
                ComitiumUtils.hideSpinner();
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Edit calendar event promises
     * When an event has been clicked
     */
    function editIsolatedProcess(data, options) {

        this.options = options;

        Q.fcall(editEventForm, data, 0)
            .then(displayModalForm)
            .then(bindUrlFetchToInput)
            .then(initFormActions)
            .then(function (data) {
                var deferred = Q.defer();

                handleFormWellKnownErrors(data, function (data) {
                    closeModal();

                    if (typeof this.options.onCreateCallBack === 'function' && data.action === 'create') {
                        this.options.onCreateCallBack.call(this, data);
                    }

                    if (typeof this.options.onEditCallBack === 'function' && data.action === 'edit') {
                        this.options.onEditCallBack.call(this, data);
                    }

                    if (typeof this.options.onDeleteCallback === 'function' && data.action === 'delete') {
                        this.options.onDeleteCallback.call(this, data);
                    }
                });

                return deferred.promise;
            })
            .catch(function (anError) {
                ComitiumUtils.hideSpinner();
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Drop calendar promises
     * When a new event has been dropped from side bar
     */
    function dropCalendarEventProcess(date, event, element) {
        var elementData = element.data("eventObject");
        var options = {};

        /**
         * Control for dropping date. If we are dropping in a date wich is
         * gratter than content publish date we reset options to avoid force
         * date and future shape displaying
         */
        if (elementData.viewOptions.forcedStartDate !== "") {
            var dropDateIsGratter = date.isAfter(elementData.viewOptions.forcedStartDate);

            if (dropDateIsGratter) {
                options.forcedStartDate = "";
                options.displayFutureInfoShape = false;
                options.forceStartConstraint = elementData.viewOptions.forcedStartDate;
            }
        }

        this.options = Object.assign({}, elementData.viewOptions, options);

        Q.fcall(createEventForm, date, event, elementData, 1)
            .then(displayModalForm)
            .then(bindUrlFetchToInput)
            .then(initFormActions)
            .then(handleCalendarEventResponse)
            .catch(function (anError) {
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Edit calendar event promises
     * When an event has been clicked
     */
    function editCalendarEventProcess(event) {

        this.options = {
            displayInterval: false,
            displayFutureInfoShape: event.forcedStartDate !== '',
            forcedStartDate: event.forcedStartDate
        };

        Q.fcall(editEventForm, event, 1)
            .then(displayModalForm)
            .then(bindUrlFetchToInput)
            .then(initFormActions)
            .then(handleCalendarEventResponse)
            .catch(function (anError) {
                ComitiumUtils.hideSpinner();
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Update calendar event date promises
     * When an event has been dropped
     */
    function updateCalendarEventProcess(event) {
        Q.fcall(updateEventDate, event)
            .catch(function (anError) {
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Drop calendar promises
     * When a new event has been dropped from an existing event
     */
    function copyCalendarEventProcess(event, date, element, revertFunct) {
        var elementData = element.data("eventobject");
        var options = {};
        /**
         * Control for dropping date. If we are dropping in a date wich is
         * gratter than content publish date we reset options to avoid force
         * date and future shape displaying
         */
        if (elementData.viewOptions.forcedStartDate !== "") {
            var dropDateIsGratter = date.isAfter(elementData.viewOptions.forcedStartDate);

            if (dropDateIsGratter) {
                options.forcedStartDate = "";
                options.displayFutureInfoShape = false;
                options.forceStartConstraint = elementData.viewOptions.forcedStartDate;
            }
        }

        this.options = Object.assign({}, elementData.viewOptions, options);

        Q.fcall(copyEventForm, date, event, elementData, 1)
            .then(displayModalForm)
            .then(bindUrlFetchToInput)
            .then(initFormActions)
            .then(handleCalendarEventResponse)
            .catch(function (anError) {
                ComitiumUtils.hideSpinner();
                errorHandler(anError);
            })
            .done();
        revertFunct();
    }

    /*
     * Process to fetch url og content and populate form
     */
    function fetchContentFromUrlProcess(data) {
        Q.fcall(sendFetchRequest, data)
            .then(parseAndAssignOpenGraphData)
            .catch(function (anError) {
                errorHandler(anError);
            })
            .done();
    }

    /*
     * Action to render form to create new entity
     */
    function createEventForm(date, event, element, blocked) {
        var _this = this;
        var deferred = Q.defer();
        var aFormatedDate = date.format('YYYY-MM-DD') + ' ' + date.format('HH:mm:ss');
        var displayInterval = _this.options.displayInterval !== 'undefined' ? _this.options.displayInterval : 0;

        $.ajax({
            url: Routing.generate(
                'cs_admin_social_network_planner_create_queue',
                {
                    date: _this.options.forcedStartDate !== "" ? _this.options.forcedStartDate : aFormatedDate,
                    entity: {
                        entityId: element.entityId,
                        entityClass: element.entityClass
                    },
                    blocked: blocked,
                    contentLocale: ComitiumUtils.getURLParameter('contentLocale'),
                    viewOptions: {
                        displayInterval: Number(displayInterval),
                        forcedStartDate: _this.options.forcedStartDate,
                        displayFutureInfoShape: Number(_this.options.displayFutureInfoShape),
                    }
                }
            ),
            method: "get",
            dataType: "json",
            beforeSend: function () {
                ComitiumUtils.showSpinner();
            },
            complete: function () {
                ComitiumUtils.hideSpinner();
            },
            success: function (data) {
                deferred.resolve({
                    data: data.html,
                    event: event,
                    element: data.queueData
                });
            },
            error: function () {
                deferred.reject(new Error("New error"));
            }
        });

        return deferred.promise;
    }

    /*
     * Action to render form to edit some entity
     */
    function editEventForm(event, blocked) {
        var _this = this;
        var deferred = Q.defer();

        $.ajax({
            url: Routing.generate(
                'cs_admin_social_network_planner_edit_queue',
                {
                    id: event.id,
                    blocked: blocked,
                    contentLocale: ComitiumUtils.getURLParameter('contentLocale'),
                    viewOptions: {
                        displayInterval: Number(_this.options.displayInterval),
                        forcedStartDate: _this.options.forcedStartDate,
                        displayFutureInfoShape: Number(_this.options.displayFutureInfoShape),
                    }
                }
            ),
            method: "get",
            dataType: "json",
            beforeSend: function () {
                ComitiumUtils.showSpinner();
            },
            complete: function () {
                ComitiumUtils.hideSpinner();
            },
            success: function (data) {
                deferred.resolve({
                    data: data.html,
                    element: data.queueData
                });
            },
            error: function () {
                deferred.reject(new Error("New error"));
            }
        });

        return deferred.promise;
    }

    /*
     * Action to update entity publish date
     */
    function updateEventDate(event) {
        var deferred = Q.defer();

        $.ajax({
            url: Routing.generate('cs_admin_social_network_planner_update_queue_date', {id: event.id}),
            method: "post",
            data: {date: event.start.format('YYYY-MM-DD HH:mm:ss')},
            dataType: "json",
            error: function () {
                deferred.reject(new Error("New error"));
            }
        });

        return deferred.promise;
    }


    /*
     * Action to render form to create new entity
     */
    function copyEventForm(date, event, element, blocked) {
        var _this = this;
        var deferred = Q.defer();
        var aFormatedDate = date.format('YYYY-MM-DD') + ' ' + date.format('HH:mm:ss');
        var displayInterval = _this.options.displayInterval !== 'undefined' ? _this.options.displayInterval : 0;

        $.ajax({
            url: Routing.generate(
                'cs_admin_social_network_planner_copy_queue',
                {
                    id: event.id,
                    date: _this.options.forcedStartDate !== "" ? _this.options.forcedStartDate : aFormatedDate,
                    entity: {
                        entityId: element.entityId,
                        entityClass: element.entityClass
                    },
                    blocked: blocked,
                    contentLocale: ComitiumUtils.getURLParameter('contentLocale'),
                    viewOptions: {
                        displayInterval: Number(displayInterval),
                        forcedStartDate: _this.options.forcedStartDate,
                        displayFutureInfoShape: Number(_this.options.displayFutureInfoShape),
                    }
                }
            ),
            method: "get",
            dataType: "json",
            beforeSend: function () {
                ComitiumUtils.showSpinner();
            },
            complete: function () {
                ComitiumUtils.hideSpinner();
            },
            success: function (data) {
                deferred.resolve({
                    data: data.html,
                    event: event,
                    element: data.queueData,
                });
            },
            error: function () {
                deferred.reject(new Error("New error"));
            }
        });

        return deferred.promise;
    }


    /*
     * Action to display form in a modal
     * Create and edit actions call this action
     */
    function displayModalForm(data) {
        var deferred = Q.defer();
        var formElement = $(data.data);
        var entity = data.element;
        var form = $('form', formElement);
        var _this = this;

        $('.modal-planner').remove();

        if (form.length <= 0) {
            deferred.reject(new Error("Form not found!"));
        }

        var modal = bootstrap.createModal();
        var submitLabel = data.element.id ? 'cs_core.action.save.default' : 'social_network.planner.publications.modal.submit';
        var displaySubmit = typeof data.element.editable != "undefined" ? !data.element.editable : false;

        if (!entity.isSent) {
            formElement.prepend("<div class='alert alert-info is-copy-container' data-is-copy='true' style='display: none' ></div>");
            checkForAlreadySentContent(formElement, entity.entityId, entity.entityClass);
        }

        modal = modal.show(
            Translator.trans('social_network.planner.publications.modal.title.new'),
            formElement,
            Translator.trans(submitLabel),
            displaySubmit,
            false,
            data.element.id && data.element.editable ? true : false
        ).addClass('modal-planner fade');

        /**
         * Drop modal on hidden.bs.modal
         */
        $(modal).on('hidden.bs.modal', function (e) {
            closeModal();
        })

        initFormComponents(formElement,entity);

        deferred.resolve({
            form: form,
            modal: modal,
            formElement: formElement,
            event: data.event,
            element: data.element,
        });

        return deferred.promise;
    }

    /*
     * Action to bind submit to form
     * Create and edit actions call this action
     * A json response will be fetch and delegating the
     * handle to next promise
     */
    function initFormActions(data) {
        var deferred = Q.defer();
        var form = data.form;
        var modal = data.modal;
        var element = data.element;
        // var event = data.event;
        modal.find('[data-dismiss="modal"]').on("click", function () {
            closeModal();
        });

        modal.find('button[data-btn-type="save"]').on("click", function () {
            var _this = $(this);
            _this.attr('disabled', true);

            updateMessageBeforeSubmit(function () {
                $.ajax({
                    url: form.attr("action"),
                    data: form.serialize(),
                    method: form.attr("method"),
                    dataType: "json",
                    success: function (response) {
                        deferred.resolve({
                            response: response,
                            form: form,
                            modal: modal,
                            event: data.event,
                            element: data.element,
                            action: element.id ? 'edit' : 'create'
                        });
                    },
                    error: function () {
                        deferred.reject(new Error("New error"));
                    },
                    complete: function () {
                        _this.attr('disabled', false);
                    }
                });
            });
        });

        modal.find('button[data-action="delete"]').on("click", function () {
            $.ajax({
                url: Routing.generate("cs_admin_social_network_planner_delete_queue_date", {id: element.id}),
                method: "post",
                dataType: "json",
                success: function (response) {
                    deferred.resolve({
                        response: response,
                        form: form,
                        modal: modal,
                        event: data.event,
                        element: data.element,
                        action: 'delete'
                    });
                },
                error: function () {
                    deferred.reject(new Error("New error"));
                }
            });
        });

        return deferred.promise;
    }

    /*
     * Action to bind some form plugins as switch
     * datetime pickers
     */
    function initFormComponents(form, entity) {
        //$('.make-switch', form).bootstrapSwitch();
        new SpellText.constructor();

        initTabs(form);
        //bindPreviewImage(form);

        var $messageInput = $("textarea[data-locale='" + this.options.entityLocale + "']", form);

        if ($messageInput.length === 1 && typeof this.options.messageSelector !== "undefined" && this.options.messageSelector !== '') {
            $messageInput.val($(this.options.messageSelector).val());
        }

        var startDate = typeof this.options.forceStartConstraint !== 'undefined' ?
            this.options.forceStartConstraint : this.options.forcedStartDate ?
                this.options.forcedStartDate : moment().format('YYYY-MM-DD HH:mm:ss');

        $('[data-role="datetimepicker"]', form).datetimepicker({
            'format': 'dd/mm/yyyy - hh:ii',
            'autoclose': true,
            'startDate': startDate
        });

        $('[name*="[socialNetworkProfiles]"]', form).on("change", function () {
            handleLocaleDependingElements(form);
            if (!entity.isSent) {
                setTimeout(function () {
                    checkForAlreadySentContent(form, entity.entityId, entity.entityClass);
                }, 700)
            }
        });

        $('#dismiss-future-message', form).on("click", function () {
            $('#future-container').fadeOut();
        });
    }

    /*
     * Action to bind tabs clicks
     */
    function initTabs(form) {
        $('[data-tab]', form).on('click', function () {
            $('[data-tab]').removeClass('active');

            var tabId = $(this)
                .addClass('active')
                .data('tab');

            $('[data-tab-content]').hide();

            $('[data-tab-content="' + tabId + '"]').show();
        });

        handleLocaleDependingElements(form);
    }

    function updateMessageBeforeSubmit(callback) {

        var containers = $('[data-tab-content]');

        containers.each(function () {
            var container = $(this);
            var ogImage = $('[data-open-graph="image"]', container)
                .find("img")
                .attr('src');

            var ogTitle = $('[data-open-graph="title"]', container).html();
            var ogDescription = $('[data-open-graph="description"]', container).html();

            $('[id^="social_network_queue_langs_"][id*="resize"]', container).val(ogImage);
            $('[id^="social_network_queue_langs_"][id*="title"]', container).val(ogTitle);
            $('[id^="social_network_queue_langs_"][id*="description"]', container).val(ogDescription);
        });

        callback.call(this);
    }

    function bindPreviewImage(form) {
        $('[data-open-graph="image"]', form).on("click", function () {
            var imgElement = $(this).find("img");
            var csAsset = CsAsset.init("image");
            var image = csAsset.createAsset();

            image.id = imgElement.attr("data-id");
            image.resize = imgElement.attr("data-resize");
            image.src = imgElement.attr("src");
            image.title = imgElement.attr("title");

            csAsset.exec(image, function (element) {
                imgElement.attr("src", element.asset.src);
                imgElement.attr("title", element.asset.title);
                imgElement.attr("data-id", element.asset.id);
                imgElement.attr("data-resize", element.asset.resize);
            });
        });
    }

    /*
     * Action to bind fetch url on input change
     */
    function bindUrlFetchToInput(data) {
        var deferred = Q.defer();
        var timeout = null;
        var form = data.formElement;

        $('[data-url]', form).on('change', function () {
            var _this = $(this);

            if (timeout !== null) {
                clearTimeout(timeout);
            }

            timeout = setTimeout(function () {
                var url = _this.val();

                if (url) {
                    data.url = url;
                    fetchContentFromUrlProcess(data);
                }
            }, 600);
        });

        deferred.resolve(data);

        return deferred.promise;
    }

    /*
     * Action to handle a new entity
     */
    function handleCalendarEventResponse(data) {
        handleFormWellKnownErrors(data, function (data) {
            if (typeof data.action === 'string' && data.action === 'delete') {
                calendar.fullCalendar('removeEvents', [data.element.id], true);
            } else {
                addCalendarEvent(data.response.data);
            }

            closeModal();
        });
    }

    function handleFormWellKnownErrors(data, successCallBack, errorCallback) {
        if (data.response.status === 400) {
            if (typeof errorCallback === 'function') {
                errorCallback.call(this, data);
            } else {
                var message = data.response.errors[0] ? data.response.errors[0].message : data.response.message;
                errorHandler({message: message});
            }
        } else {
            if (typeof successCallBack === 'function') {
                successCallBack.call(this, data);
            }
        }
    }

    function closeModal() {
        $('.modal-planner,.modal-backdrop').remove();
    }

    /*
     * Action to add edit event to calendar
     * The current element will be remove before
     * Used after edit actions
     */
    function addCalendarEvent(calendarEvent) {
        calendar.fullCalendar('removeEvents', [calendarEvent.id], true);
        calendar.fullCalendar('renderEvent', calendarEvent, true);
    }

    /*
     * Action to fetch content from any url
     */
    function sendFetchRequest(data) {
        var deferred = Q.defer();

        /**
         * Make call only if is external
         */
        if (!data.element.entityId) {
            $.get(Routing.generate('cs_admin_social_network_planner_fetch_open_graph'), {url: data.url}, function (response) {
                if (response.status === 404) {
                    deferred.reject(new Error(Translator.trans("social_network.form.messages.url_not_found")));
                }

                data.response = response;

                deferred.resolve(data);
            }, 'json');
        }

        return deferred.promise;
    }


    /*
     * Action to populate form with og data
     */
    function parseAndAssignOpenGraphData(promiseData) {

        var data = promiseData.response;

        if (!data['og:image'] && data['og:title']) {
            deferred.reject(new Error("Invalid data"));
        }

        var container = $('[data-tab-content="' + $('[data-tab].active').data('tab') + '"]');

        if (data['og:image']) {
            var ogImage = data['og:image'];
            $('[data-open-graph="image"]', container).html($('<img>').attr('src', ogImage));
            $('[id^="social_network_queue_langs_"][id*="resize"]', container).val(ogImage);
        }

        if (data['og:title']) {
            var ogTitle = data['og:title'];
            $('[data-open-graph="title"]', container).html(ogTitle);
            $('[id^="social_network_queue_langs_"][id*="title"]', container).html(ogTitle);
        }

        /*if (data['og:description']) {
            var ogDescription = data['og:description'];
            $('[data-open-graph="description"]', container).html(ogDescription);
            $('[id^="social_network_queue_langs_"][id*="description"]', container).val(ogDescription);
        }*/

        if (data.url) {
            $('[data-open-graph="url"]', container).html(data.url);
        }

        if (data.status === 200) {
            $('[data-role="og-fields"]', container).show();
        }
    }

    function createCalendarEventObject() {
        var originalEventObject = $(this).data('eventObject');
        var copiedEventObject = $.extend({}, originalEventObject);

        copiedEventObject.start = date;
        copiedEventObject.end = date.clone().add(5, 'minute');

        copiedEventObject.className = $(this).attr("data-class");

        copiedEventObject.durationEditable = false;

        $('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
    }

    function initSocialNetworksCounters() {

    }

    /**
     *
     * @param modal
     * @param contentUuid
     * @param contentClass
     */
    function checkForAlreadySentContent(modal, contentUuid, contentClass) {
        var selectedProfiles = fetchProfilesSelected(modal);

        $.ajax({
            url: Routing.generate("cs_admin_social_network_planner_check_content_profiles_sent_to"),
            method: "get",
            dataType: "json",
            data: {
                profiles: selectedProfiles.join(","),
                contentUuid: contentUuid,
                contentClass: contentClass,
            },
            success: function (response) {
                if (response.isContentSent === true) {
                    addIsAlreadySentReminder(modal,response.profiles.join(", "));
                } else {
                    eraseIsAlreadySentReminder(modal);
                }
            },
            error: function () {
                console.warn("error checking content!")
            }
        });

    }

    /**
     *
     * @param modal
     * @returns {Array}
     */
    function fetchProfilesSelected(modal) {
        var modalActiveSocialMedia = modal.find('[data-toggle="buttons"] .btn.active input');

        var modalpids = [];
        modalActiveSocialMedia.each(function (i, el) {
            return modalpids.push(parseInt($(el).val()));
        });

        return modalpids;
    }

    /**
     *
     * @param html
     */
    function addIsAlreadySentReminder(html, profilesText) {
        var copyInfo = html.find("div[data-is-copy='true']");
        copyInfo.html(
            $("<span class='is-copy-message' data-copy-text >"+ Translator.trans('social_network.planner.publications.modal.copy_alert', {profiles : profilesText }) + "</span>")
        );
        copyInfo.fadeIn();
    }

    /**
     *
     * @param html
     */
    function eraseIsAlreadySentReminder(html) {
        html.find("div[data-is-copy='true']").fadeOut();
        html.find("span[data-copy-text]").remove();
    }


    return SocialNetworkPlanner;
}(jQuery));
