define([
	'Global',
	'App',
	'ApptRequestDetails',
	'AppointmentRequest',
	'SendAppointment',
    'PatientContext',
	'User',
    'BookingPurposes',
    'CancelApptReasons',
	'SchedulingResourceDirectory',
	'DesiredDate',
	'Text!../html/templates/booking-dialog.html',
	'Text!../html/templates/booking-result.html',
    'Text!../html/templates/request-result.html',
    'Text!../html/templates/appt-details.html',
    'Text!../html/templates/book-appt.html',
    'Text!../html/templates/cancel-appt.html',
	'Text!../html/templates/VAAC-request-item.html',
    'Text!../html/templates/VAAC-after-book.html'
],
	function (Global, App, ApptRequestDetails, AppointmentRequest, SendAppointment, PatientContext, user, BookingPurposes, CancelApptReasons,
			  SchedulingResourceDirectory, DesiredDate,
			  template, resultTemplate, requestResultTemplate, apptDetailsTemplate, bookApptTemplate, cancelApptTemplate,
			  VAACRequestItemTemplate, VAACAfterBookTemplate) {
		'use strict';

		return Backbone.View.extend({
			tagName: "div",
			id: "book-appointment",
			attributes: {
				"data-role": "dialog",
				"data-corners": "false",
				"data-overlay-theme": "d"
			},

			initialize: function (options) {
                this.options = options || {};
				this.template = _.template(template);
				this.resultTemplate = _.template(resultTemplate);
                this.apptDetailsTemplate = _.template(apptDetailsTemplate);
                this.bookAppt = _.template(bookApptTemplate);
                this.cancelApptTemplate = _.template(cancelApptTemplate);
				this.requestResultTemplate = _.template(requestResultTemplate);
//                this.waitListContextItemTemplate = _.template(waitListContextItemTemplate);
				this.VAACRequestItemTemplate = _.template(VAACRequestItemTemplate);
                this.VAACAfterBookTemplate = _.template(VAACAfterBookTemplate);
//                this.waitListEntry = WaitListEntry.instance().toJSON();
				this.VAACRequestItem = AppointmentRequest.instance();
                this.cancel = options ? options.cancel : false;
				this.notesMax = options && options.notesMax ? options.notesMax : 160;
			},

			render: function () {
				var options = this.setDialogOptions(),
                    $container = $('body'),
					that = this;

                options.maxLength = this.notesMax;

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

                var $dropDownMenus = this.$el.find('.drop-down-menus'),
                    $apptDetails = this.$el.find('#book-appt-content');

                $dropDownMenus
                    .empty()
                    .append(this.dropDownTemplate);

				this.$characterCount = this.$el.find('.counter').eq(0);

//				this.showWaitListEntry();

				this.showVAACRequestItem();

                $apptDetails.prepend(this.apptDetailsTemplate(ApptRequestDetails.instance().toJSON()));

				$container.append(this.$el);

				$('#book-appointment').animationComplete(function () {
					var $firstInput = $('.ui-dialog input').eq(0);

					$('#booking-notes').trigger('change');

                    that.generateDropdown(options.listSource);

					if ($firstInput.length) {
						$firstInput.focus();
					} else {
						$('#appt-purpose-button').focus();
					}

					$('.ui-dialog .ui-header .ui-btn').off('click');
				});

				this.delegateEvents();

				return this;
			},

            events: {
				"tap .ui-header .ui-btn": "closeDialog",
				"keydown .ui-header .ui-btn, #appt-purpose-button, #appt-type-button": "handleKeydown",
				"click #cancel-btn, #close-book-appt": "closeDialog",
	            "tap #appt-purpose-button, #appt-type-button": "openSelectMenu",
				"change #appt-purpose, #appt-type": "changeBookButton",
	            "change #appt-purpose": "showRebookWarning",
				"keyup #appt-type": "changeBookButton",
                "change #request-date-time input": "changeBookButton",
				"click #submit-btn": "submitRequest",
				"keyup #booking-notes": "validateBookingNotes",
				"change #booking-notes": "validateBookingNotes",
	            "click #go-to-VAAC-btn": "goToVAAC"
			},
			openSelectMenu: function(e) {
				var $target = $(e.currentTarget),
					popupId = $target.attr('id').replace('-button', '-listbox'),
					$selectMenuPopup = $('#' + popupId);

				e.preventDefault();

				$selectMenuPopup.popup('open', {positionTo: $target});
			},
            submitRequest: function(e){
	            $(e.currentTarget).blur();

                this.handleRequest();
            },
            generateDropdown: function(listSource){
                this.handleGenerateDropdown(listSource);
            },
            cancelAppt: function(){
                var purpose = $('#appt-purpose').val(),
                    type = $('#appt-type').val(),
                    notes = $('#booking-notes').val(),
                    data = {
                        "cancelCode": purpose,
                        "cancelReason": type,
                        "remarks": notes
                    },
                    apptRequestDetails = ApptRequestDetails.instance(),
                    that = this;

                apptRequestDetails.set(data);

				this.showLoadingSpinner();

				this.onCloseCallback = function () {
					Global.getUtilities().eventAggregator.trigger('clearAndRefreshCalendar');
				};

				$.ajax({
					url: apptRequestDetails.get('cancel-appointment').href,
					contentType: "application/json; charset=utf-8",
					data: JSON.stringify(apptRequestDetails.toCancelRequestJSON()),
					dataType: "json",
					headers: {
						"Content-Type": "application/json",
						"Accept": "application/json"
					},
					type: "PUT",
					statusCode: {
						200 : function () {
							that.showResult("200", "Appointment successfully cancelled!", purpose);
							$(document).jqmData("noRedraw", "");
						},
						500 : function () {
							that.showResult("500", "ERROR: An error occurred while cancelling the appointment");
						}
					}
				});
            },

			bookAppointment: function () {
				var purpose = $('#appt-purpose').val(),
					type = $('#appt-type').val(),
					notes = $('#booking-notes').val() || "",
					data = {
						"purpose": purpose,
						"apptType": type,
						"bookingNotes": notes,
						"desiredDate": DesiredDate.instance().get('desiredDate')
					},
					apptRequestDetails = ApptRequestDetails.instance(),
					that = this,
//					removeFromWaitList = this.waitListEntry.waitListId,
					updateVAACRequest = this.VAACRequestItem.get("uniqueId"),
					videoToPhone = $('#videoToPhone').val(),
                        patientGetPatient = PatientContext.instance().getPatient();
                    this.requestFullDate = $('#request-date-time input:checked').val();


				apptRequestDetails.set(data);

				this.showLoadingSpinner();

				this.onCloseCallback = function () {
					$(document).jqmData("noRedraw", true);
					Global.getUtilities().eventAggregator.trigger('clearAndRefreshCalendar');
				};

				new SendAppointment(apptRequestDetails.toBookRequestJSON()).save({}, {
					url: patientGetPatient.get('book-new-appointment').href,
					statusCode: {
						200 : function () {
							that.showResult("200", "Appointment successfully booked!", purpose);

//							if (removeFromWaitList) {
//								that.removeFromWaitlist();
//							}

							if (updateVAACRequest) {
								that.updateVAACRequest.call(that,videoToPhone,apptRequestDetails);
							}

							DesiredDate.clearInstance();
						},
						500 : function (response) {
                            var text = response.responseText || "An error occurred while booking the appointment.";

							that.showResult("500", "ERROR: " + text);
						}
					}
				});
			},
//            removeFromWaitlist: function(){
//                var that = this;
//
//                that.showLoadingSpinner();
//                $('.ui-loader').css('display', 'block');
//
//                $.ajax({
//                    url: that.getRemoveWaitlistURL(),
//                    contentType: "application/json; charset=utf-8",
//                    data: that.getWaitListParameters(),
//                    dataType: "json",
//                    headers: {
//                        "Content-Type": "application/json",
//                        "Accept": "application/json"
//                    },
//                    type: that.getRequestType(),
//                    statusCode: {
//                        200 : function () {
//                            WaitListEntry.clearInstance();
//                            that.showResult("200", "Wait List Item successfully removed!");
//                        },
//                        500 : function () {
//                            that.showResult("500", "ERROR: An error occurred while removing the Wait List Item");
//                        }
//                    }
//                })
//            },
            updateVAACRequest: function(videoToPhone, apptRequestDetails){


                this.showLoadingSpinner();
                $('.ui-loader').css('display', 'block');

                var that = this,
                    ardc = that.VAACRequestItem.get('appointmentRequestDetailCode'),
                    detailCode,
                    url = that.VAACRequestItem.get('self').href,
                    requestFullDate = this.requestFullDate;

                if (requestFullDate === "DETCODE2" || requestFullDate === "DETCODE12"){
                    detailCode = requestFullDate;
                } else {
                    detailCode = "DETCODE1";
                    var requestSplitDate = requestFullDate.split(" ");

                    that.VAACRequestItem.set({
                        appointmentDate: requestSplitDate[0],
                        appointmentTime: requestSplitDate[1]
                    })
                }

                that.VAACRequestItem.set({
                    bookedApptDateTime: apptRequestDetails.get('dateTime')
                });

                if (videoToPhone === "on") {
                    switch(detailCode) {
                        case "DETCODE2":
                            detailCode = "DETCODE11";
                            break;
                        case "DETCODE12":
                            detailCode = "DETCODE13";
                            break;
                        default:
                            detailCode = "DETCODE10";
                    }
                }

                ardc.unshift({
                    userId: user.get('id'),
                    detailCode: {
                        code: detailCode
                    }
                });

                if(that.VAACRequestItem.has('bestTimetoCall') && (that.VAACRequestItem.get('bestTimetoCall') || []).length == 0){
                    that.VAACRequestItem.unset('bestTimetoCall');
                }

                that.VAACRequestItem.save({
                    id: that.VAACRequestItem.get("uniqueId"),
                    status: "Booked"
                }, {
                    url: url,
                    statusCode: {
                        200 : function () {
                            AppointmentRequest.clearInstance();
                            that.showResult("200", "Veteran Request successfully booked!");
                        },
                        500 : function () {
                            that.showResult("500", "ERROR: Veteran Request was not updated.");
                        }
                    }
                });
            },
//            getRequestType: function(){
//
//                var type = this.waitListEntry.waitListType,
//                    requestType;
//
//                switch(type){
//	                case "EWL":
//                    case "NEAR":
//                        requestType = "PUT";
//                        break;
//
//                    case "RECALL":
//                        requestType = "DELETE";
//                        break;
//                }
//
//                return requestType;
//
//            },
//            getRemoveWaitlistURL: function(){
//                var type = this.waitListEntry.waitListType,
//                    url,
//                    patientGetPatient = PatientContext.instance().getPatient();
//
//                switch(type){
//
//                    case "NEAR":
//                        url = patientGetPatient.get('update-near-list').href + "/F";
//                    break;
//
//	                case "EWL":
//		                url = patientGetPatient.get('update-ewl-entry').href;
//		            break;
//
//                    case "RECALL":
//                        url = patientGetPatient.get('remove-waitlist').href + "?waitListType=" + type;
//                    break;
//
//                }
//
//                return url;
//
//            },
            setDialogOptions: function(){
                var options = {};

                if (this.cancel){
                    this.handleRequest = this.cancelAppt;
                    this.handleGenerateDropdown = this.generatePurposeDropdown;
                    options.listSource = "cancel-reasons-list";
                    options.title = "Cancel Appointment";
                    options.cancelBtnTxt = "Do Not Cancel Appointment";
                    options.submitBtnTxt = "Cancel Appointment";
                    this.dropDownTemplate = this.cancelApptTemplate;
                } else {
                    this.handleRequest = this.bookAppointment;
                    this.handleGenerateDropdown = this.generateReasonDropdown;
                    options.listSource = "purpose-list";
                    options.title = "Book Appointment";
                    options.cancelBtnTxt = "Cancel";
                    options.submitBtnTxt = "Book Appointment";
//                    options.waitListId = this.waitListEntry.waitListId;
	                options.VAACRequestId = this.VAACRequestItem.get("uniqueId");
                    this.dropDownTemplate = this.bookAppt;
                }

                return options;
            },
			validateBookingNotes: function (e) {
				var maxLength = this.notesMax,
					$target = $(e.currentTarget),
					value = $target.val(),
					length = value.length,
                    difference = maxLength - length;

				if (length > maxLength) {
					$target.val(value.substr(0, maxLength));
				}

				this.$characterCount.attr("data-balance", difference >= 0 ? difference : 0);

				if (value.indexOf("^") !== -1) {
					$('.warning').removeClass('hidden');
				} else {
					$('.warning').addClass('hidden');
				}

				this.changeBookButton();
			},

			handleKeydown: function (e) {
				if (e.which === 13 || e.which === 32) {
					$(e.currentTarget).trigger('tap');
				}
			},

			generatePurposeDropdown: function (listSourceURL) {
				var $apptPurpose = this.$el.find('#appt-type'),
					url = SchedulingResourceDirectory.instance().get(listSourceURL).href,
					that = this;

                new CancelApptReasons().fetch({
                    cache: false,
                    url: url,
                    success: function (response){
                        var purposes = response.toJSON();

                        _.each(purposes, function(purpose) {
                            $apptPurpose.append("<option value='" + purpose.number + "'>" + purpose.text + "</option>");
                        });

                        $apptPurpose.selectmenu("refresh");
                    }
                });

				this.showLoadingSpinner();
			},
            generateReasonDropdown: function(listSourceURL){
                var $apptReason = this.$el.find('#appt-purpose'),
                    url = SchedulingResourceDirectory.instance().get(listSourceURL).href,
                    that = this;

                new BookingPurposes().fetch({
                    cache: false,
                    url: url,
                    success: function (response) {
                        var reasons = response.toJSON();

                        _.each(reasons, function(reason) {
                            $apptReason.append("<option value='" + reason.id + "'>" + reason.name + "</option>");
                        });

                        $apptReason.selectmenu("refresh");

                        that.hideLoadingSpinner();
                    }
                 });
            },
			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');
			},

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

				var callback = this.onCloseCallback;

				ApptRequestDetails.clearInstance();

				$('#main').animationComplete(function () {
					if ($.isFunction(callback)) {
						callback();
						callback = function () {};
					}
				});

				history.back();
			},

			changeBookButton: function () {
                var requestFullDate = $('#request-date-time input:checked').val() || "",
                    purpose = $('#appt-purpose').val(),
					type = $('#appt-type').val(),
                    notes = $('#booking-notes').val(),
					$bookButton = $('#submit-btn'),
                    requestFullDateCheck = (requestFullDate.length !== 0 || $('#request-date-time').length === 0);

				purpose = purpose === "Select Purpose" || purpose === "Select Status" ? "" : purpose;
				type = type === "Select Type" || type === "Select Reason" ? "" : type;

				if ( requestFullDateCheck && purpose.length && type.length && notes.indexOf("^") == -1) {
					$bookButton.button('enable');
				} else {
					$bookButton.button('disable');
				}
			},

			showResult: function (result, message, currentStatus) {
				this.hideLoadingSpinner();
				this.showRequestResultDialog(currentStatus, result);
				this.showResultMessage(result, message);
			},

			showRequestResultDialog: function (currentStatus, result) {
				if (!$('.request-results').length) {
					var options = this.setDialogOptions();

					currentStatus = this.checkCurrentStatus(currentStatus);

					this.$el
						.find('#book-appt-content')
						.empty()
						.append(this.resultTemplate($.extend({currentStatus: currentStatus, result: result}, options)))
						.trigger('create');

					$('#close-book-appt').focus();

					var $apptDetails = this.$el.find('.appt-details');

					$apptDetails.append(this.apptDetailsTemplate(ApptRequestDetails.instance().toJSON()));

//					this.showWaitListEntry();

					this.showVAACResults();
				}
			},

			showResultMessage: function (result, message) {
				this.$el
					.find(".request-results")
					.append(this.requestResultTemplate({result: result, message: message}));
			},

//			showWaitListEntry: function () {
//				var $waitListItem = this.$el.find('.wait-list-item');
//
//				$waitListItem.empty().append(this.waitListContextItemTemplate(this.waitListEntry));
//			},

			showVAACRequestItem: function () {
				var $VAACRequestItem = this.$el.find('.VAAC-request-item'),
					requestInfo = this.VAACRequestItem.toJSON();

                $VAACRequestItem.empty().append(this.VAACRequestItemTemplate(requestInfo));
			},

            showVAACResults: function(){
                var $VAACRequestResults = this.$el.find('.VAAC-request-results'),
                    requestInfo = this.VAACRequestItem.toJSON(),
                    requestFullDate = this.requestFullDate,
                    originalDateTime = requestInfo.optionDate1 + (requestInfo.optionTime1 !== "No Time Selected" ? requestInfo.optionTime1 : "");

                if (requestFullDate === "DETCODE2"){
                    requestFullDate = "Booked from alternate after contacting patient";
                } else if (requestFullDate === "DETCODE12") {
                    requestFullDate = "Booked from alternate";
                }

                if ($VAACRequestResults.length){
                    $VAACRequestResults.empty().append(this.VAACAfterBookTemplate($.extend(requestInfo, {
                        requestDateTime: requestFullDate,
                        originalDateTime: originalDateTime
                    })));
                }
            },

            checkCurrentStatus: function(currentStatus){
                switch (currentStatus){
                    case "N":
                        currentStatus = "No-Show";
                        break;
                    case "C":
                        currentStatus = "Cancelled by Clinic";
                        break;
                    case "NA":
                        currentStatus = "No-Show & Auto Re-Book";
                        break;
                    case "CA":
                        currentStatus = "Cancelled by Clinic & Auto Re-Book";
                        break;
                    case "I":
                        currentStatus = "Inpatient Appointment";
                        break;
                    case "PC":
                        currentStatus = "Cancelled by Patient";
                        break;
                    case "PCA":
                        currentStatus = "Cancelled by Patient & Auto Re-Book";
                        break;
                    case "NT":
                        currentStatus = "No Action Taken";
                        break;
                    default:
                        currentStatus = "Booking";
                }
                return currentStatus;
            },

//			getWaitListParameters: function () {
//				var apptRequestDetails = ApptRequestDetails.instance().toJSON(),
//					waitListEntry = this.waitListEntry,
//					type = waitListEntry.waitListType,
//					parameters = {};
//
//				switch (type) {
//					case "RECALL":
//						parameters.clinicId = waitListEntry.clinicId;
//						parameters.provider = waitListEntry.provider;
//						parameters.recallDate = waitListEntry.recallDate;
//
//						if (waitListEntry.recallDate1) {
//							parameters.recallDate1 = waitListEntry.recallDate1;
//						}
//
//						break;
//					case "EWL":
//						parameters.ien = waitListEntry.ewlIen;
//						parameters.appointmentTime = apptRequestDetails.dateTime;
//						parameters.dispositionCode = "SA";
//						parameters.code = "R";
//						parameters.clinicId = apptRequestDetails.clinicId;
//						parameters.stopCode = apptRequestDetails.stopCode;
//						parameters.creditCode = apptRequestDetails.creditCode;
//				}
//
//				return JSON.stringify(parameters);
//			},

			goToVAAC: function () {
				ApptRequestDetails.clearInstance();
				Global.getUtilities().eventAggregator.trigger('veteran-requests');
			},

			showRebookWarning: function (e) {
				if (this.cancel) {
					var val = $(e.currentTarget).val(),
						$rebookWarning = $('.rebook-warning');

					switch (val) {
						case "C":
						case "CA":
						case "PC":
						case "PCA":
							$rebookWarning.addClass('hidden');
							break;
						default:
							$rebookWarning.removeClass('hidden');
					}
				}
			}
		});
	}
);