define([
        'Global',
        'App',
        'MainView',
        'LocationServiceResources',
        'Clinics',
        'Clinic',
        'VAACCollapsibleView',
        'DesiredDate',
        'AppointmentRequest',
        'CalendarData',
        'Text!../html/templates/calendar-filter.html',
        'jquery.refresher',
        'jquery.mobile-datepicker',
        'moment'
    ],
    function (Global, App, MainView, LocationServiceResources, Clinics, Clinic, VAACCollapsibleView, DesiredDate, AppointmentRequest, CalendarData, template) {
        'use strict';

        var thisView;

        return Backbone.View.extend({

            attributes: {'class': 'filter'},

            initialize: function () {
                this.template = _.template(template);
                this.calendarData = CalendarData.instance();
                thisView = this;

                this.listenTo(Global.getUtilities().eventAggregator, "showApptLength", function () {
                    $('#appt-length').removeClass('hidden');
                });

                this.listenTo(Global.getUtilities().eventAggregator, "clearAndRefreshCalendar", function () {
                    thisView.render();
                });

                this.listenTo(Global.getUtilities().eventAggregator, "updateDesiredDate", function () {
                    var $desiredDate = thisView.$el.find('#desired-date');

                    $desiredDate.val(thisView.populateDesiredDate());

                    $desiredDate[0].disabled = !!$desiredDate.val();
                });
            },

            render: function () {
                var that = this;

                MainView.instance().clearPopups();

                if ($('#calendar-clinics-form').length) {

//                    this.clearEWLDetails();

                    that.afterDraw(that);
                } else {
                    this.getClinics(that.afterDraw);
                }

                return this;
            },

            populateDesiredDate: function () {
                var desiredDateContext = DesiredDate.instance().get('desiredDate'),
                    apptRequestDate = AppointmentRequest.instance().get('optionDate1'),
//                    waitListEntry = WaitListEntry.instance(),
//                    EWLRequestDate = waitListEntry.get('desiredDate'),
//                    RecallRequestDate = waitListEntry.get('recallDate'),
//                    NEARRequestDate = waitListEntry.get('requestDate'),
                    desiredDate = desiredDateContext || apptRequestDate || /*EWLRequestDate || RecallRequestDate || NEARRequestDate ||*/ null;

                return desiredDate ? formatDate(desiredDate) : "";
            },

            afterDraw: function (context) {
                var $desiredDate = context.$el.find('#desired-date');
                var maxDate = moment().add(90, 'days');
                var calendarData = CalendarData.instance();

                context.setAttributesToJQMinput(context.$calendarClinic);

                $desiredDate.val(context.populateDesiredDate());

                context.$el.find('#date-picker-btn').mobile508datepicker({
                    onClose: context.closeDatePicker,
                    "leading-zero": true,
                    MIN: new Date(),
                    MAX: maxDate.toDate()
                });

                $desiredDate[0].disabled = !!$desiredDate.val();

                context.$el.find('#calendar-clinics-form input').val(calendarData.getClinicName());

                context.clinicName = calendarData.getClinicName();
                context.clinicUrl = calendarData.get('clinicUrl');

                context.enableDisableAvailabilityButton();

                context.delegateEvents();

                if (AppointmentRequest.instance().isValid()) {
                    new VAACCollapsibleView().render();
                }
            },

            closeDatePicker: function () {
                var $this = $('#calendar-clinic-listbox'),
                    value = $('#date-picker-btn').val(),
                    $desiredDate = $('#desired-date');

                $this
                    .popup()
                    .popup('open', {positionTo: $($this.jqmData('callElement'))});

                if (value) {
                    $desiredDate
                        .val(value)
                        .trigger('change');

                    $desiredDate.trigger('blur');
                }
            },

            setAttributesToJQMinput: function ($ul) {
                var attr, key, value,
                    attributes = $ul.data('attributes').split(','),
                    props = ['autofocus', 'disabled', 'readonly', 'required', 'selected'],
                    $calendarClinic =
                        $ul.prev('form')
                            .attr('id', [$ul[0].id, 'form'].join('-'))
                            .find('input')
                            .attr('id', [$ul[0].id, 'input'].join('-'));

                $('.ui-input-search').prop('title', 'Search...');

                for (var i = 0; i < attributes.length; i++) {
                    attr = attributes[i].split('=');
                    key = attr[0];
                    value = attr[1] || true;

                    $calendarClinic[props.indexOf(key) >= 0 ? "prop" : "attr"](key, value);
                }
            },

            events: {
                'keyup #calendar-clinics-form input': 'showAutocompleteList',
                'tap #calendar-clinics-form .ui-input-clear': 'handleClear',
                'keydown #calendar-clinics-form .ui-input-clear': 'handleKeyDown',
                'tap #calendar-clinics li a': 'selectClinic',
                'keydown #calendar-clinics li a': 'handleKeyDown',
                'keydown #desired-date:not(:disabled)': 'handleDateInput',
                'blur #desired-date': 'enableDisableAvailabilityButton',
                'click #availability-btn': 'viewAvailability'
            },

            selectClinic: function (e) {
                e.preventDefault();

                var $target = $(e.currentTarget);
                var $clinicInput = $('#calendar-clinics-form input');
                this.clinicName = $target.text();
                this.clinicUrl = $target.data('url');

                $clinicInput.val(this.clinicName);

                this.$calendarClinic.addClass('hidden');

                this.enableDisableAvailabilityButton();

                this.$el.find('#desired-date').focus();
            },

            enableDisableAvailabilityButton: function () {
                var $clinic = this.$el.find('#calendar-clinics-form input');
                var $availabilityBtn = this.$el.find('#availability-btn');
                var $desiredDate = this.$el.find('#desired-date');
                var validDate = ($desiredDate.val() !== "" && $desiredDate.is(':disabled')) || this.validateDesiredDate();

                $availabilityBtn[0].disabled = !($clinic.val() && validDate);
            },

            handleKeyDown: function (e) {
                if (e.which === 13) {
                    e.preventDefault();

                    $(e.currentTarget).trigger('tap');
                }
            },

            showAutocompleteList: function (e) {
                var $input = $('#calendar-clinics-form input');

                if ((e.which === 8 || e.which === 46) && !$input.val()) {
                    this.$calendarClinic.addClass('hidden');
                } else if (e.which !== 13 && e.which !== 9 && e.which !== 16) {
                    this.$calendarClinic.removeClass('hidden');
                }
            },

            handleClear: function (e) {
                var activeClinic = Clinic.instance().get('id');

                if (activeClinic) {
                    var calendarData = this.calendarData;

                    this.clinicName = "";
                    this.clinicUrl = "";
                    Clinic.clearInstance();
                    calendarData.clearData(true);
//                    WaitListEntry.clearInstance();
                    DesiredDate.clearInstance();
                    thisView.render();

                } else {
                    thisView.hideAutocompleteList(e);
                }
            },

            hideAutocompleteList: function (e) {
                this.$calendarClinic.addClass('hidden');

                $(e.currentTarget).trigger('click');
            },

            getClinics: function (callBack) {
                var linkBlock = LocationServiceResources.instance().get('specialties-operational'),
                    url,
                    clinics = Clinics.instance(),
                    that = this;

                if (linkBlock) {
                    url = linkBlock.get('href');

                    if (!clinics.length) {
                        this.showLoadingSpinner();
                        clinics.fetch({
                            url: url,
                            success: function () {
                                that.hideLoadingSpinner();
                                if (Backbone.history.getHash() === 'booking') {
                                    that.drawClinics(callBack);
                                }
                            },
                            cache: false
                        });
                    } else {
                        this.drawClinics(callBack);
                    }
                }
            },

            drawClinics: function (callBack) {
                var $container = getSidebarContent(),
                    clinics = Clinics.instance().toJSON(),
                    list = "",
                    that = this;

                $.each(clinics, function (key, value) {
                    list += "<li><a href='#' data-url='" + value.link[0].href + "'>" + value.name + "</a></li>";
                });

                this.$el
                    .empty()
                    .append(this.template);

//                this.drawEWLDetails();

                this.$calendarClinic = this.$el.find('#calendar-clinics');

                this.$calendarClinic
                    .empty()
                    .append(list);

                $container
                    .empty()
                    .append(this.$el)
                    .trigger('create');

                if ($.isFunction(callBack)) {
                    callBack(that);
                }
            },

            handleDateInput: function (e) {
                var $target = $(e.currentTarget),
                    code = e.which,
                    value = $target.val(),
                    length;

                if (code !== 9) {
                    e.preventDefault();
                    if (code >= 48 && code <= 57) {
                        value += code - 48;

                        length = value.length;

                        if (length === 2 || length === 5) {
                            value += "/";
                        }

                        if (value.length <= 10) {
                            $target.val(value);
                        }
                    } else if (code === 8) {
                        var lastChar = value.charAt(value.length - 1);

                        value = value.substr(0, value.length - 1);

                        length = value.length;

                        if ((length === 2 || length === 5) && lastChar === "/") {
                            value = value.substr(0, value.length - 1);
                        }

                        $target.val(value);
                    } else if (code === 32 || code === 13) {
                        this.enableDisableOk(e);
                    }
                }
            },

            validateDesiredDate: function () {
                var $desiredDate = $('#desired-date'),
                    $dateError = $('.date-error'),
                    dateString = $desiredDate.val(),
                    date = new Date(dateString),
                    today = setTimeToZero(new Date()),
                    maxDate = setTimeToZero(new Date());

                maxDate.setDate(today.getDate() + 90);

                if (!isValidDate(dateString) || date < today || date > maxDate) {
                    if (dateString.length) {
                        $dateError.removeClass('hidden');
                        $desiredDate.focus();
                    } else {
                        $dateError.addClass('hidden');
                    }

                    return false;
                } else {
                    $dateError.addClass('hidden');

                    return true;
                }
            },

            setDesiredDateContext: function () {
                var appointmentRequest = AppointmentRequest.instance();

                DesiredDate.clearInstance();

                DesiredDate.instance({
                    desiredDate: $('#desired-date').val()
                });

                if (appointmentRequest.isValid() && appointmentRequest.get('optionDate1') === "No Date Selected") {
                    appointmentRequest.set({
                        "optionDate1": $('#desired-date').val()
                    });
                }
            },

            viewAvailability: function () {
                this.setDesiredDateContext();
                CalendarData.instance()
                    .setClinicName(this.clinicName)
                    .setClinicUrl(this.clinicUrl)
                    .getClinicSlots();
            },

//            drawEWLDetails: function () {
//                var details = WaitListEntry.instance();
//                if (details.get('waitListType') === 'EWL') {
//                    var data = $.extend({collapsibleClass: "ui-collapsible-content"}, details.toJSON()),
//                        template = _.template(EWLDetailsTemplate, data);
//                    this.$el.find('#below-filter').append(template);
//                }
//            },

//            clearEWLDetails: function () {
//                var $details = $('.details');
//                if ($details.length) {
//                    $details.remove();
//                }
//            },

            showLoadingSpinner: function () {
                $.mobile.loading('show', App.getSpinnerOptions());
                $('.ui-loader').css('display', 'block');
                $('#dialog-screen').removeClass('hidden');
            },

            hideLoadingSpinner: function () {
                $.mobile.loading('hide');
                $('.ui-loader').removeAttr('style');
                $('#dialog-screen').addClass('hidden');
            }

        });
    }
);