// Form components are namespaced under 'fba' = 'Feedback Analytics'
'use strict';

function FBAform(d, N) {
	return {
		formId: "4f8d19c2",
		formComponent: function() {
			return document.querySelector("[data-touchpoints-form-id='" + this.formId + "']")
		},
		formElement: function() {
			return this.formComponent().querySelector("form");
		},

		// enable Javascript experience
		javscriptIsEnabled: function() {
			var javascriptDisabledMessage = document.getElementsByClassName("javascript-disabled-message")[0];
			var touchpointForm = document.getElementsByClassName("touchpoint-form")[0];
			if (javascriptDisabledMessage) {
				javascriptDisabledMessage.classList.add("hide");
			}
			if (touchpointForm) {
				touchpointForm.classList.remove("hide");
			}
		},
		init: function(options) {
			this.javscriptIsEnabled();

			this.options = options;
			this.loadHtml();
					this.loadButton();
			this.bindEventListeners();
			this.dialogOpen = false; // initially false
			this.successState = false; // initially false
			this.pagination();
			return this;
		},
		bindEventListeners: function() {
			var self = this;
			d.addEventListener('keyup', function (event) {
				var x = event.keyCode;
				if( x == 27 && self.dialogOpen == true) {
					self.closeDialog();
				}
			});
			d.addEventListener('click', function (event) {
				self.handleClick(event);
			});
		},
		loadHtml: function()
		{

			this.dialogEl = document.createElement('div');
			this.dialogEl.setAttribute("hidden", true);
			this.dialogEl.setAttribute('class', 'fba-modal');
			this.dialogEl.setAttribute('role', 'dialog');
			this.dialogEl.setAttribute('aria-modal', 'true');

			this.dialogEl.innerHTML = "<div id=\"fba-modal-dialog\" class=\"fba-modal-dialog\">\n  <div class=\"touchpoints-form-wrapper\" data-touchpoints-form-id=\"4f8d19c2\">\n  <div class=\"wrapper\">\n      <h3 id=\"fba-modal-title\">\n        Help improve tsp.gov\n      <\/h3>\n      <a class=\"fba-modal-close\" type=\"button\" href=\"#\">×<\/a>\n\n    <p class=\"fba-instructions\">\n      <strong>DO NOT<\/strong> submit personally identifiable information such as your account number, email address, or Social Security number.\n    <\/p>\n    <div class=\"fba-alert usa-alert usa-alert--success\" hidden=\"true\">\n  <div class=\"usa-alert__body\">\n    <h3 class=\"usa-alert__heading\">Success<\/h3>\n    <p class=\"usa-alert__text\">\n      alert message\n    <\/p>\n  <\/div>\n<\/div>\n<div class=\"fba-alert-error usa-alert usa-alert--error\" hidden=\"true\">\n  <div class=\"usa-alert__body\">\n    <h3 class=\"usa-alert__heading\">Error<\/h3>\n    <p class=\"usa-alert__text\">\n      alert message\n    <\/p>\n  <\/div>\n<\/div>\n\n    \n<form class=\"touchpoints-form\" action=\"https://touchpoints.app.cloud.gov/touchpoints/4f8d19c2/submissions.json\" method=\"POST\">\n  <div class=\"touchpoints-form-body\">\n    <input type=\"hidden\" name=\"fba_location_code\" id=\"fba_location_code\" />\n\n      <div class=\"white-bg section visible\">\n\n\n\n        <div class=\"question well\">\n            <div class=\"radios\" role=\"group\" aria-labelledby=\"answer_01\">\n  <label class=\"usa-label\" for=\"answer_01\">\n  What were you trying to do, and how can we improve it?\n<\/label>\n\n    <textarea name=\"answer_01\" id=\"answer_01\" class=\"usa-textarea\" required=\"required\" maxlength=\"100000\">\n<\/textarea>\n<\/div>\n\n        <\/div>\n\n          <p class=\"submit-button\">\n            <button type=\"submit\" class=\"usa-button\">Submit<\/button>\n          <\/p>\n      <\/div>\n  <\/div>\n<\/form>\n<script>\n  // Set \'other\' type checkbox option values when associated option text field is updated\n  \$(\'.usa-input.other-option\').keyup(function() {\n    // strip commas\n    var val = \$(this).val().replace(/,/g, \'\');\n    // if user has cleared custom text, then reset checkbox value to \"other\"\n    if (val == \'\') { val = \'other\'; }\n    // set the value of the checkbox option to the custom text as entered\n    var option_selector = \"#\" + \$(this).attr(\"data-option-id\");\n    \$(option_selector).prop(\'checked\',true);\n    \$(option_selector).val(val);\n  });\n<\/script>\n\n  <\/div>\n  \n    \n<div class=\"usa-banner\">\n  <header class=\"usa-banner__header\">\n    <div class=\"usa-banner__inner\">\n      <div class=\"grid-col-auto\">\n        <img class=\"usa-banner__header-flag\" src=\"https://touchpoints.app.cloud.gov/assets/us_flag_small-9c507b1ff21f65c4b8f0c45d0e0d0a10bb5c9864c1a76e07aa3293da574968a1.png\" alt=\"U.S. flag\">\n      <\/div>\n      <div class=\"grid-col-fill tablet:grid-col-auto\">\n        <p class=\"usa-banner__header-text\">\n          An official form of the United States government.\n          Powered by\n          <a href=\"https://touchpoints.app.cloud.gov/\" target=\"_blank\" rel=\"noopener\">Touchpoints<\/a>\n          <br>\n\n        <\/p>\n      <\/div>\n    <\/div>\n  <\/header>\n<\/div>\n\n\n<\/div>\n<\/div>\n";
			d.body.appendChild(this.dialogEl);

			d.querySelector('.fba-modal-close').addEventListener('click', this.handleDialogClose.bind(this), false);


			var formElement = this.formElement();
			// returns 1 or more submit buttons within the Touchpoints form
			var submitButtons = formElement.querySelectorAll("[type='submit']");
			var that = this;

			var yesNoForm = d.querySelector('.touchpoints-yes-no-buttons');
			if (yesNoForm) { // only for yes/no questions
				Array.prototype.forEach.call(submitButtons, function(submitButton) {
					submitButton.addEventListener('click', that.handleYesNoSubmitClick.bind(that), false);
				})
			} else { // for all other types of forms/questions
				if (submitButtons) {
					Array.prototype.forEach.call(submitButtons, function(submitButton) {
						submitButton.addEventListener('click', that.handleSubmitClick.bind(that), false);
					})
				}
			}
		},
		resetErrors: function()
		{
			var formComponent = this.formComponent();
			var alertElement = formComponent.querySelector(".fba-alert");
			var alertElementBody = formComponent.getElementsByClassName("usa-alert__text")[0];
			var alertErrorElement = formComponent.querySelector(".fba-alert-error");
			var alertErrorElementBody = alertErrorElement.getElementsByClassName("usa-alert__text")[0];
			alertElement.setAttribute("hidden", true);
			alertElementBody.innerHTML = "";
			alertErrorElement.setAttribute("hidden", true);
			alertErrorElementBody.innerHTML = "";
		},
		handleClick: function(e) {
			if (this.dialogOpen && !e.target.closest('#fba-button') && !e.target.closest('.fba-modal-dialog')) {
				this.closeDialog();
			}
		},
		handleButtonClick: function(e) {
			e.preventDefault();
			this.loadDialog();
		},
		handleDialogClose: function(e) {
			e.preventDefault();
			this.closeDialog();
		},
		handleSubmitClick: function(e) {
			e.preventDefault();
			this.resetErrors();
			var formElement = this.formElement();
			var self = this;
			if (self.validateForm(formElement)) {
				var submitButton = formElement.querySelector("[type='submit']");
				submitButton.disabled = true;
				self.sendFeedback();
			}
		},
		handleYesNoSubmitClick: function(e) {
			e.preventDefault();
			
			var input = this.formComponent().querySelector('.fba-touchpoints-page-form');
			input.value = e.target.value;
			this.resetErrors();
			var self = this;
			var formElement = this.formElement();
			if (self.validateForm(formElement)) {
				var submitButtons = formElement.querySelectorAll("[type='submit']");
				Array.prototype.forEach.call(submitButtons, function(submitButton) {
					submitButton.disabled = true;
				})
				self.sendFeedback();
			}
		},
		validateForm: function(form) {
			this.hideValidationError(form);
			var valid = this.checkRequired(form);
			return valid;
		},
		checkRequired: function(form) {
			var requiredItems = form.querySelectorAll('[required]');
			var questions = {};
			// Build a dictionary of questions which require an answer
			Array.prototype.forEach.call(requiredItems, function(item) { questions[item.name] = item });

			Array.prototype.forEach.call(requiredItems, function(item) {
				switch (item.type) {
				case 'radio':
					if (item.checked) delete(questions[item.name]);
					break;
				case 'checkbox':
				  if (item.checked) delete(questions[item.name]);
					break;
				case 'select-one':
					if (item.selectedIndex > 0) delete(questions[item.name]);
					break;
				default:
					if (item.value.length > 0) delete(questions[item.name]);
				}
			});
			for (var key in questions) {
				this.showValidationError(questions[key],'You must respond to question: ');
				return false;
			}
			return true;
		},
		showValidationError: function(question,error) {
			var questionDiv = question.closest(".question");
			var label = questionDiv.querySelector("label");
			var questionNum = label.innerText;
			questionDiv.setAttribute('class', 'usa-form-group usa-form-group--error');
			var span = document.createElement('span');
			span.setAttribute('id', 'input-error-message');
			span.setAttribute('role','alert');
			span.setAttribute('class','usa-error-message');
			span.innerText = error + questionNum;
			label.parentNode.insertBefore(span, label.nextSibling);
			var input = document.createElement('input');
			input.setAttribute('hidden', 'true');
			input.setAttribute('id','input-error');
			input.setAttribute('type','text');
			input.setAttribute('name','input-error');
			input.setAttribute('aria-describedby','input-error-message');
			questionDiv.appendChild(input);
			questionDiv.scrollIntoView();
			questionDiv.focus();
		},
		hideValidationError: function(form) {
			var elem = form.querySelector('.usa-form-group--error');
			if (elem == null) return;
			elem.setAttribute('class','question');
			var elem = form.querySelector('#input-error-message');
			if (elem != null) elem.parentNode.removeChild(elem);
			elem = form.querySelector('#input-error');
			if (elem != null) elem.parentNode.removeChild(elem);
		},
		textCounter: function(field,maxlimit)
			{
			 var countfield = field.parentNode.querySelector(".counter-msg");
			 if ( field.value.length > maxlimit ) {
			  field.value = field.value.substring( 0, maxlimit );
			  countfield.innerText = '0 characters left';
			  return false;
			 } else {
			  countfield.innerText = "" + (maxlimit - field.value.length) + " characters left";
			 }
		},
		loadButton: function()
		{
			// Add the fixed, floating tab button
			this.buttonEl = document.createElement('a');
			this.buttonEl.setAttribute('id', 'fba-button');
			this.buttonEl.setAttribute('class', 'fixed-tab-button usa-button');
			this.buttonEl.setAttribute('href', '#');
			this.buttonEl.setAttribute('aria-haspopup', 'dialog');
			this.buttonEl.addEventListener('click', this.handleButtonClick.bind(this), false);
			this.buttonEl.innerHTML = this.options.modalButtonText;
			d.body.appendChild(this.buttonEl);

			this.loadFeebackSkipLink();
		},
		loadFeebackSkipLink: function() {
			this.skipLink = document.createElement('a');
			this.skipLink.setAttribute('class', 'usa-skipnav touchpoints-skipnav');
			this.skipLink.setAttribute('href', '#fba-button');
			this.skipLink.addEventListener('click', function() {
				document.querySelector("#fba-button").focus();
			});
			this.skipLink.innerHTML = 'Skip to feedback';

			var existingSkipLinks = document.querySelector('.usa-skipnav');
			if(existingSkipLinks) {
				existingSkipLinks.insertAdjacentElement('afterend', this.skipLink);
			} else {
				d.body.prepend(this.skipLink);
			}
		},
		// Used when in a modal
		loadDialog: function()
		{
			d.querySelector('.fba-modal').removeAttribute("hidden");
			this.dialogOpen = true;
		},
		closeDialog: function()
		{
			d.querySelector('.fba-modal').setAttribute("hidden", true);
			this.resetFormDisplay();
			this.dialogOpen = false;
		},
		sendFeedback: function()
		{
			var form = this.formElement();
			this.ajaxPost(form, this.formSuccess);
		},
		showFormSuccess: function(e)
		{
			var formComponent = this.formComponent();
			var formElement = this.formElement();
			var alertElement = formComponent.querySelector(".fba-alert");
			var alertElementBody = formComponent.querySelector(".usa-alert__text");

			// Display success Message
			alertElementBody.innerHTML += "Thank you. Your feedback has been received.";
			alertElement.removeAttribute("hidden");

			// Hide Form Elements
			if (formElement) {
				// And clear the Form's Fields
				formElement.reset();
				if (formElement.querySelector('.touchpoints-form-body')) {
					var formBody = formElement.querySelector('.touchpoints-form-body');
					if(formBody) {
						formBody.setAttribute("hidden", true);
					}
				}
				if (formComponent.querySelector('.touchpoints-form-disclaimer')) {
					var formDisclaimer = formComponent.querySelector('.touchpoints-form-disclaimer');
					if(formDisclaimer) {
						formDisclaimer.setAttribute("hidden", true);
					}
				}

			}
		},
		resetFormDisplay: function()
		{
			if (this.successState === false) {
				return false;
			}

			// Hide and Reset Flash Message
			this.resetErrors();

			// Re-enable Submit Button
			var formElement = this.formElement();
			var submitButton = formElement.querySelector("[type='submit']");
			submitButton.disabled = false;

			// Show Form Elements
			if (formElement) {
				if (formElement.querySelector('.touchpoints-form-body')) {
					var formBody = formElement.querySelector('.touchpoints-form-body')
					if(formBody) {
						formBody.removeAttribute("hidden");
					}
				}
			}
		},
		formSuccess: function(e) {
			// Clear the alert box
			var formComponent = this.formComponent();
			var alertElement = formComponent.querySelector(".fba-alert");
			var alertElementBody = formComponent.getElementsByClassName("usa-alert__text")[0];
			var alertErrorElement = formComponent.querySelector(".fba-alert-error");
			var alertErrorElementBody = alertErrorElement.getElementsByClassName("usa-alert__text")[0];
			alertElementBody.innerHTML = "";
			alertErrorElementBody.innerHTML = "";

			var formElement = this.formElement();
			var submitButton = formElement.querySelector("[type='submit']");

			if (e.target.readyState === 4) {
	      if (e.target.status === 201) { // SUCCESS!
					this.successState = true;
					if(submitButton) {
						submitButton.disabled = true;
					}
					this.showFormSuccess();
	      } else if (e.target.status === 422) { // FORM ERRORS =\
						this.successState = false;
						if(submitButton) {
							submitButton.disabled = false;
						}
					  var jsonResponse = JSON.parse(e.target.response);
					  var errors = jsonResponse.messages;

					  for (var err in errors) {
							if (errors.hasOwnProperty(err)) {
								alertErrorElementBody.innerHTML += err;
								alertErrorElementBody.innerHTML += " ";
								alertErrorElementBody.innerHTML += errors[err];
								alertErrorElementBody.innerHTML += "<br />";
							}
					  }
						alertErrorElement.removeAttribute("hidden");
				} else { // SERVER ERROR
					console.log('failed');
					alertErrorElement.removeAttribute("hidden");
					alertErrorElementBody.innerHTML += "Server error. We're sorry, but this submission was not successful. The Product Team has been notified.";
				}
			}
		},
		ajaxPost: function (form, callback) {
	    var url = form.action;
	    var xhr = new XMLHttpRequest();

			// for each form question
			var params = {
				answer_01:
				form.querySelector("#answer_01") && form.querySelector("#answer_01").value,
			}

			// Combine Referrer and Pathname with Form-specific params
			params["referer"] = d.referrer;
			params["page"] = window.location.pathname;
			params["location_code"] = form.querySelector("#fba_location_code") ? form.querySelector("#fba_location_code").value : null;
			params["language"] = "en";

			// Submit Feedback with a POST
			xhr.open("POST", url);
			xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8;");
	    xhr.onload = callback.bind(this);
	    xhr.send(JSON.stringify({
				"submission": params
			}));
		},
		pagination: function() {
			var previousButtons = document.getElementsByClassName("previous-section");
			var nextButtons = document.getElementsByClassName("next-section");

			var self = this;
			for (var i = 0; i < previousButtons.length; i++) {
				previousButtons[i].addEventListener('click', function(e) {
					e.preventDefault();
					var currentPage = e.target.closest(".section");
					if (!this.validateForm(currentPage)) return false;
					currentPage.classList.remove("visible");
					currentPage.previousElementSibling.classList.add("visible");
					window.scrollTo(0, 0);
				}.bind(self));
			}

			for (var i = 0; i < nextButtons.length; i++) {
				nextButtons[i].addEventListener('click', function(e) {
					e.preventDefault();
					var currentPage = e.target.closest(".section");
					if (!this.validateForm(currentPage)) return false;
					currentPage.classList.remove("visible");
					currentPage.nextElementSibling.classList.add("visible");
					window.scrollTo(0, 0);
				}.bind(self))
			}
		}
	};
};

// Form Settings
var formOptions = {
	'modalButtonText': "Feedback"
};

// Create unique Touchpoints form object
const touchpointForm4f8d19c2 = new FBAform(document, window).init(formOptions);
