define([
	'Global',
	'User',
    'PatientContext',
	'Clinic',
	'BookedAppointments'
],
	function(Global, user, PatientContext, Clinic, BookedAppointments) {
		'use strict';
		var CalendarData = Backbone.Model.extend({
			defaults: {
				apptLength: 30,
				availableSlots: [],
				calendarDate: setTimeToZero(new Date()),
				calendarView: "month",
				clinic: new Backbone.Model(),
				clinicIds: [],
				clinicsLegend: {},
                clinicNames: [],
				clinicUrls: [],
				nomenclature: true,
				patientAppts: [],
				SDOBKey: false,
				SDMOBKey: false,
				startTime: "8",
				today: setTimeToZero(new Date()),
				valid: false,
				yearFromDate: ""
			},

			initialize: function () {
				var that = this,
					SDOBKey = this.getSecurityKeyByName("SDOB") ? true : false,
					SDMOBKey = this.getSecurityKeyByName("SDMOB") ? true : false;

				this.bookedAppointments = BookedAppointments.instance();

				this.findYearFromDate();

				this.listenTo(this.bookedAppointments, "sync", function () {
						that.setPatientAppts(that.bookedAppointments.noCancelledAppts().toJSON())
							.trigger('refreshCalendar');
						var $slideBtn = $('#slide-btn');
						if ($slideBtn.css('display') !== 'none' && !!document.querySelectorAll('.hide-pane-when-tablet').length) {
							$slideBtn.click();
						}
					})
					.listenTo(Global.getUtilities().eventAggregator, "refreshPatientAppts", function() {
						that.bookedAppointments.fetch({
                            cache: false
                        });
					})
					.listenTo(Global.getUtilities().eventAggregator, "clearPatientAppts", function () {
						this.setPatientAppts([]);

                        if ($('#calendar').length) {
                            this.getClinicSlots();
                        }
					})
					.listenTo(Global.getUtilities().eventAggregator, "clearAndRefreshCalendar", function() {
						this.refreshCalendar();
					});

				this.set({
					SDOBKey: SDOBKey,
					SDMOBKey: SDMOBKey
				})
			},

			refreshCalendar: function () {
				var callBack,
					that = this;

				if (PatientContext.instance().isValid()) {
					callBack = function () {
						that.bookedAppointments.fetch({
							cache: false
						});
					}
				}

				this.clearClinic();

				this.getClinicSlots(callBack);
			},

			getClinicSlots: function (callBack) {
				var dateRange = ["?startDate=", this.getRequestDate(new Date()), "&endDate=", this.getRequestDate(this.get('yearFromDate'))].join(''),
					that = this,
                    d = new Date(),
					clinicUrl = this.get('clinicUrl') + dateRange + "?r=" + d.getTime();

				that.set({valid: false})
					.trigger('refreshCalendar');

				Clinic.instance().fetch({
					url: clinicUrl,
					success: function () {
						var data = {
							clinic: Clinic.instance(),
							valid: true,
                            startTime: Clinic.instance().get('clinicDisplayStartTime')
						};

						that.set(data)
							.setAvailableSlots();

						if ($.isFunction(callBack)) {
							callBack();
						} else {
							that.trigger('refreshCalendar');
						}
					},
					error: function (response) {
						var data = {
                            clinicName: that.get('clinicName'),
                            invalidCallResponse: response.responseText
                        };

						that.trigger('invalidClinic', data);
					}
				});
			},

			getClinicsForLegend: function () {
				var clinics = this.get('clinics'),
					keys = Object.keys(clinics),
					clinicsLegend = {},
					clinic;

				_.each(keys, function (key) {
					clinic = clinics[key];

					clinicsLegend[clinic.className] = clinic.clinicName;
				});

				var data = {
					clinicsLegend: clinicsLegend
				};

				this.set(data);

				return this;
			},

			setAvailableSlots: function (refresh) {
				var clinic = this.get('clinic'),
					slots = clinic.get('timeSlots') || [];

				var data = {
					availableSlots: slots
				};

				this.set(data);

				if (refresh) {
					this.trigger('refreshCalendar');
				}

				return this;
			},

			setCalendarDate: function (date) {
				var data = {
					calendarDate: date
				};

				this.set(data);

				return this;
			},

			setCalendarView: function (view) {
				var data = {
					calendarView: view
				};

				this.set(data);

				return this;
			},

			setClinicUrl: function (clinicUrl) {
				var data = {
					clinicUrl: clinicUrl
				};

				this.set(data);

				this.getClinicIdFromUrl();

				return this;
			},

            setClinicName: function (clinicName){
                this.set({clinicName: clinicName});

                return this;
            },

			setNomenclature: function (nomenclature) {
				this.set({nomenclature: nomenclature});

				return this;
			},

			setPatientAppts: function (patientAppts) {
				var data = {
					patientAppts: patientAppts
				};

				this.set(data);

				return this;
			},

			setValid: function (valid) {
				var data = {
					valid: valid
				};

				this.set(data);

				return this;
			},

			getClinicIdFromUrl: function () {
				var url = this.get('clinicUrl');
                var split = url.split("/");
                var id = parseInt(split[split.length - 1]);

				var data = {
					clinicId: id
				};

				this.set(data);

				return this;
			},

			getRequestDate: function (date) {
				var month = addLeadingZero(date.getMonth() + 1),
					day = addLeadingZero(date.getDate()),
					year = date.getFullYear(),
					requestDate = month + "/" + day + "/" + year;

				return requestDate;
			},

			getSecurityKeyByName: function (name) {
				var securityKeys = user.get('mdwsInfo').keys;

				return _.find(securityKeys, function (key) {
					return key.name === name;
				});
			},

			findYearFromDate: function () {
				var yearFromDate = setTimeToZero(new Date());

				yearFromDate.setFullYear(yearFromDate.getFullYear() + 1);

				var data = {
					yearFromDate: yearFromDate
				};

				this.set(data);

				return this;
			},

			getApptLength: function () {
				return this.get('apptLength');
			},

			getAvailableSlots: function () {
				return this.get('availableSlots');
			},

			getCalendarDate: function () {
				return this.get('calendarDate');
			},

			getCalendarView: function () {
				return this.get('calendarView');
			},

			getClinic: function () {
				return this.get('clinic');
			},

			getClinicsLegend: function () {
				return this.get('clinicsLegend');
			},

			getClinicId: function () {
				return this.get('clinicId');
			},

            getClinicName: function (){
                return this.get('clinicName');
            },

			getNomenclature: function () {
				return this.get('nomenclature');
			},

            getNumClinics: function () {
                return 1;
            },

			getPatientAppts: function () {
				return this.get('patientAppts');
			},

			getSDOBKey: function () {
				return this.get('SDOBKey');
			},

			getSDMOBKey: function () {
				return this.get('SDMOBKey');
			},
			getStartTime: function () {
				return this.get('startTime');
			},

			getToday: function () {
				return this.get('today');
			},

			getValid: function () {
				return this.get('valid');
			},

			getYearFromDate: function () {
				return this.get('yearFromDate');
			},

			clearClinic: function () {
				Clinic.clearInstance();
			},

			clearData: function () {
				var data = {
					apptLength: 30,
					availableSlots: [],
					calendarDate: setTimeToZero(new Date()),
					calendarView: "month",
					clinic: new Backbone.Model(),
					clinicId: '',
					clinicsLegend: {},
                    clinicName: '',
					clinicUrl: '',
					patientAppts: [],
					startTime: "8",
					valid: false
				};

				this.set(data);

				this.clearClinic();

				this.trigger('refreshCalendar');

				return this;
			}
			
		});

		CalendarData.singleInstance = null;

		CalendarData.instance = function () {
			CalendarData.singleInstance = CalendarData.singleInstance || new CalendarData();
			return CalendarData.singleInstance;
		};

		return CalendarData;
	}
);