define([
    'Global',
	'MessagePopupView',
    'AppointmentRequestMessage',
    'AppointmentRequests',
    'User',
    'Text!../html/templates/messaging.html',
	'moment'
],
    function (Global, MessagePopupView, AppointmentRequestMessage, AppointmentRequests, user, MessagingTemplate) {
        'use strict';
        return Backbone.View.extend({
            tagName: 'div',
            initialize: function (options) {
                this.options = options || {};
	            this.id = options && options.id ? options.id : "";
                this.messagingTemplate = _.template(MessagingTemplate);
                this.appointmentRequest = this.getAppointmentRequestForViewing();
                this.aptMessages = null;
                this.newMessage = null;
                this.messagesUrl = null;
            },

            render: function () {
                var messagingTemplate = this.messagingTemplate(),
                    $container = this.$el.append(messagingTemplate),
                    $messages = $container.find('.messages'),
                    messages,
                    messagesUrl,
                    messageDateTime,
                    lastSent = null,
                    today = moment(),
                    appointmentDate = this.appointmentRequest.get('bookedApptDateTime'),
	                that = this;

                this.newMessage = $container.find('#new-message');
                Global.getUtilities().flattenLinks(this.appointmentRequest);
                messagesUrl = this.messagesUrl = this.appointmentRequest.get('appointment-request-messages').href;

                this.aptMessages = new AppointmentRequestMessage({url: messagesUrl });

                this.aptMessages.fetch({
                    async: false,
                    cache: false,
                    url: messagesUrl
                });

                messages = this.aptMessages.get('appointmentRequestMessage');

                $.ajax({
                    type: "POST",
                    url: this.appointmentRequest.get('appointment-request-new-message-flag').href,
                    data: "{}",
                    contentType: "application/json",
                    success: function (data) {
                    },
                    error: function (err) {
                        MessagePopupView({title: "Error", alertMessage: 'Error clearing read messages flag for appointment request' + that.appointmentRequest.get('dataIdentifier').uniqueId + ". Error was " + err}).render();
                    }
                });

                //Needs to be templated!!
                _.each(messages, function (message) {
                    messageDateTime = message.messageDateTime.split(':').splice(0, 2).join(':');
                    $messages
                        .append(
                            '<span class="center">' + [messageDateTime !== lastSent ? messageDateTime : ''] + '</span>' +
                                '<div class="' + [message.senderId === user.get('id') ? 'sent' : 'received'] +
                                '"><p>' + message.messageText + '</p></div>'
                        );
                    lastSent = messageDateTime;
                });

                if (appointmentDate !== "") {
                    this.preventMessageScenarios(moment(new Date(appointmentDate)), today);
                }

                return this;
            },

            events: {
                'focus #new-message': 'enableDisableNewMessageTextFieldBasedOnMessageCountAndStatus',
                'keyup #new-message': 'enableDisableNewMessageFieldBasedOnCharCount',
	            'change #new-message': 'enableDisableNewMessageFieldBasedOnCharCount',
                'click #send-message': 'sendMessage'
            },

            preventMessageScenarios: function (appointmentDate, today) {
                var dayOfWeek = parseInt(appointmentDate.format('e')),
                    considerWeekend = dayOfWeek === 1 ? 3 : 1,
                    oneBusinessDaysBefore = moment(appointmentDate),
                    twoBusinessDaysBefore = moment(appointmentDate),
                    initiatingMessage = $('.received').length <= $('.sent').length,
                    newMessage = this.newMessage;

	            oneBusinessDaysBefore.subtract(considerWeekend, 'days');
	            twoBusinessDaysBefore.subtract(considerWeekend + 1, 'days');

                if (this.appointmentRequest.get('status') === 'Cancelled') {
                    return this.disabledExplanation(newMessage, 'Appointment has been cancelled');
                }
                if (today > appointmentDate) {
                    return this.disabledExplanation(newMessage, 'Appointment Date has passed');
                }
                if (today > twoBusinessDaysBefore) {
                    return this.disabledExplanation(newMessage, 'Please Call. Two business days required to initiate a message');
                }
                if (!initiatingMessage && today >= oneBusinessDaysBefore && today <= appointmentDate) {
                    return this.disabledExplanation(newMessage, 'Please Call. One business day required to respond to a message');
                }

                this.disableMessagingBasedOnStatusAndMessagingFlow(newMessage);
            },

            sendMessage: function (e) {
                var doubleDigit = function (digit) {
                        return ('0' + digit).slice(-2);
                    },
                    getDateTime = function () {
                        var d = new Date(),
                            date = [doubleDigit(d.getMonth() + 1), doubleDigit(d.getDate()), d.getFullYear()].join('/'),
                            time = [doubleDigit(d.getHours()), doubleDigit(d.getMinutes()), doubleDigit(d.getSeconds())].join(':');

                        return [date, time].join(' ');
                    },
                    messageText = this.newMessage.val().trim(),
                    messageDetails,
                    messagesUrl = this.messagesUrl;

                e.currentTarget.disabled = true;

                if (messageText.length) {
                    messageDetails = {
                        messageDateTime: getDateTime(),
                        messageText: messageText,
                        senderId: user.get('id'),
                        AppointmentRequestId: this.appointmentRequest.get('dataIdentifier').uniqueId
                    };

                    this.aptMessages.save(messageDetails, {
                        url: messagesUrl,
                        success: function () {
                            var messageDateTime = messageDetails.messageDateTime.split(':').splice(0, 2).join(':'),
                                $messages = $('.messages'),
                                lastSent = $messages.find('span').eq(0).text(),
                                time = messageDateTime !== lastSent ? '<span class="center">' + messageDateTime + '</span>' : '';
                            $messages
                                .prepend(time + '<div class="sent"><p>' + messageDetails.messageText + '</p></div>');
                        },

                        error: function () {
                        },

                        statusCode: {
                            302: function () {
                                loginRedirect();
                            }
                        }
                    });
                }

	            this.newMessage.val('');
            },

            enableDisableNewMessageTextFieldBasedOnMessageCountAndStatus: function (e) {
                //in case user just cancelled appointment e.currentTarget = textarea
                this.disableMessagingBasedOnStatusAndMessagingFlow($(e.currentTarget));
            },

            disableMessagingBasedOnStatusAndMessagingFlow: function ($textarea) {
                if (this.appointmentRequest.get('status') === 'Cancelled') {
                    return this.disabledExplanation($textarea, 'Appointment has been cancelled');
                }
                //prevent Excessive Messages From Sender
                if ($('.sent').length >= 2) {
                    return this.disabledExplanation($textarea, 'Can\'t send more than two messages...');
                }
                //prevent Consecutive Messages From Sender
                if ($('.messages div:first-of-type').hasClass('sent')) {
                    return this.disabledExplanation($textarea, 'Must wait for response before sending another message');
                }
            },

            enableDisableNewMessageFieldBasedOnCharCount: function (e) {
                var $textField = $(e.currentTarget),
	                value = $textField.val(),
                //have to use attr() not data(), for CSS3 content injection
                    max = $textField.attr('data-maxlength'),
                    len = $textField.val().trim().length,
	                balance;

	            if (max - len < 0) {
		            $textField.val(value.substr(0, max));
		            len = $textField.val().trim().length;
	            }

	            balance = max - len;

                $textField
                    .parent()
                    .attr('data-balance', balance);

                $('#send-message')[0].disabled = len === 0;
            },

            disabledExplanation: function ($textarea, reason) {
                return $textarea.prop({
                    placeholder: reason,
                    disabled: true
                }).val('');
            },

            getAppointmentRequestForViewing: function () {
                var appointmentRequestId = this.id,
                    appointmentRequests = AppointmentRequests.instance();
                return appointmentRequests.findByAppointmentRequestId(appointmentRequestId);
            }
        });
    }
);