/*
 * Licensed Materials - Property of IBM
 *
 * IBM Cognos Products: SHARE
 *
 * (C) Copyright IBM Corp. 2016, 2017
 *
 * US Government Users Restricted Rights - Use, duplication or disclosure
 * restricted by GSA ADP Schedule Contract with IBM Corp.
 */
define([
	'bi/schedule/views/CadencePickerView',
	'bi/schedule/app/appControler',
	'jquery',
	'bi/sharecommon/utils/translator',
	'bi/content_apps/utils/GlassContextHelper',
	'q',
	'moment-timezone',
	'bi/sharecommon/utils/simpledoT',
	'text!bi/schedule/templates/DateTimeRangeCadencePicker.html',
	'underscore',
	'bi/commons/ui/widgets/DatePicker',
	'bi/commons/ui/widgets/TimePicker',
	'bi/commons/ui/properties/CheckBox',
	'bi/commons/utils/DateTimeUtils'
], function(View, controler, $, t, GlassContextHelper, Q, moment, dot, template, _, DatePicker, TimePicker, CheckBox, DateTimeUtils) {
	'use strict';

	var DateTimeRange = View.extend({
		/**
		 * @constructor
		 */
		init: function(options) {
			DateTimeRange.inherited('init', this, arguments);
			_.extend(this, options);
			this.descriptor = this.objectInformation.descriptor;
			this.isEditMode = typeof(this.descriptor) !== "undefined";
			this.noEndDateCheckbox = null;
			this.uniqueId = _.uniqueId();
			this.timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
			this.locale = this._determineDateLocale();
			this.logger = this.glassContext.getCoreSvc && this.glassContext.getCoreSvc('.Logger'); //backwards compatible
		},

		_determineDateLocale: function() {
			var prodLocale = GlassContextHelper.getUserPreference(this.glassContext, 'productLocale');
			var contentLocale = GlassContextHelper.getUserPreference(this.glassContext, 'contentLocale');

			if (prodLocale === contentLocale.substring(0, 2)) {
				return contentLocale;
			} else {
				return prodLocale;
			}
		},

		_renderDateStartEndPeriod: function(translatedStrings) {
			var todayAtMidnight = moment.tz(this.timezone).startOf('day');
			var sdate = this.isEditMode ? moment.utc(this.descriptor.scheduleInfo.startDate).toDate() : todayAtMidnight.toDate();
			this.startDate = new DatePicker({
				$el: this.$el.find(".schedule_period_start"),
				ariaLabelText: translatedStrings.schedule_datepicker_start,
				timezone: this.timezone,
				locale: this.locale,
				logger: this.logger,
				attributes: {
					inputFieldDate: sdate
				}
			});
			return this.startDate.render().then(function() {
				var edate = new Date(sdate);
				edate.setMonth(edate.getMonth() + 3);
				if (this.isEditMode) {
					if (this.descriptor.scheduleInfo.endType === "onDate") {
						edate = moment.utc(this.descriptor.scheduleInfo.endDate).toDate();
					}
				}
				this.endDate = new DatePicker({
					$el: this.$el.find(".schedule_period_end"),
					ariaLabelText: translatedStrings.schedule_datepicker_end,
					timezone: this.timezone,
					locale: this.locale,
					logger: this.logger,
					attributes: {
						defaultDate: '+3m',
						inputFieldDate: edate
					}
				});
				return this.endDate.render();
			}.bind(this));
		},

		_renderNoEndDateCheckBox: function() {
			var checked = false;

			if (this.isEditMode && this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.endType && this.descriptor.scheduleInfo.endType != 'onDate') {
				this.$el.find(".schedule_date_section_end").hide();
				checked = true;
			}

			this.noEndDateCheckbox = new CheckBox({
				'id': 'schedule_noEndDate_checkbox_' + this.uniqueId,
				'el': this.$el.find('.no_endDate_checkbox'),
				'name': 'schedule_DateTimeRange_noEndDate',
				'label': t.translate('schedule_date_noEndDate'),
				'ariaLabel': t.translate('schedule_date_noEndDate'),
				'checked': checked,
				'controlOnLeft': true,
				'onChange': this._hideShowEndDate.bind(this)
			});

			this.noEndDateCheckbox.doRender();
		},

		/**
		 * Render the new schedule view date time range picker section
		 *
		 */
		render: function() {
			var deferred = Q.defer();
			var htmlGenerator = dot.simpleTemplate(template);

			var attributes = {
				schedule_datepicker_label: t.translate("schedule_datepicker_label"),
				schedule_datepicker_start: t.translate("period_start_label"),
				schedule_datepicker_end: t.translate("period_end_label"),
				schedule_timepicker_label: t.translate("schedule_timepicker_label"),
				schedule_timepicker_start: t.translate("period_start_time_label"),
				schedule_timepicker_end: t.translate("period_end_time_label"),
				uniqueid: this.uniqueId
			};

			this.$el.append(htmlGenerator(attributes));

			this._renderDateStartEndPeriod(attributes).then(function() {
				this._renderDateTimeRangeTimePickers();
				this._renderNoEndDateCheckBox();

				deferred.resolve(this);
			}.bind(this));
			return deferred.promise;
		},

		/**
		 * All views should overwrite this function. It takes a partially
		 * populated json schedule descriptor and adds to it based on the
		 * properties of this view.
		 *
		 * @param desc the partial JSON schedule descriptor
		 * @returns the descriptor passed in, with added attributes.
		 */
		toDescriptor: function(desc) {
			// Moved from ScheduleView, startDate/endDate is set here, not passed in.
			// startDate is midnight on the start date in their timezone.
			var startDate = this.startDate.getDateAsISOString();
			// Assemble datetime for startDate and endDate based on the selections from the widgets
			var asStartDate = moment(startDate).toDate();
			// Get the right format for desc
			var asStartTime = this.rangeStartTime.getDateTimeUTC(asStartDate);

			var endType = this.noEndDateCheckbox.isChecked() ? "indefinite" : "onDate";

			var asEndTime = "";
			if (endType === "onDate") {
				var endDate = this.endDate.getDateAsISOString();
				var asEndDate = moment(endDate).toDate();
				asEndTime = this.rangeEndTime.getDateTimeUTC(asEndDate);
			}

			// Push into the desc
			desc.startDate = asStartTime;
			desc.endDate = asEndTime;
			desc.endType = endType;

			return desc;
		},

		validate: function(msgs) {
			var parameters = {};
			var noEndDateChecked = this.noEndDateCheckbox.isChecked();
			// Date
			var $startDateDiv = this.$el.find(".schedule_period_start");
			var $endDateDiv = this.$el.find(".schedule_period_end");
			$startDateDiv.removeAttr('aria-invalid aria-describedby');
			$endDateDiv.removeAttr('aria-invalid aria-describedby');
			// Time
			var $iStartTime = this.$el.find(".schedule_time_start");
			var $iEndTime = this.$el.find(".schedule_time_end");
			$iStartTime.removeAttr('aria-invalid aria-describedby');
			$iEndTime.removeAttr('aria-invalid aria-describedby');

			if (!this.startDate.isValidDate()) {
				parameters.param1 = t.translate("schedule_period");
				parameters.param2 = t.translate("schedule_datepicker_label");
				parameters.param3 = t.translate("period_start_label");
				msgs.push(t.translate("schedule_invalid_date", parameters));
				$startDateDiv.attr({
					'aria-invalid': 'true',
					'aria-describedby': msgs[0]
				});
			} else if (!noEndDateChecked && !this.endDate.isValidDate()) {
				parameters.param1 = t.translate("schedule_period");
				parameters.param2 = t.translate("schedule_datepicker_label");
				parameters.param3 = t.translate("period_end_label");
				msgs.push(t.translate("schedule_invalid_date", parameters));
				$endDateDiv.attr({
					'aria-invalid': 'true',
					'aria-describedby': msgs[0]
				});
			} else if (!this.rangeStartTime.isValidTime()) {
				parameters.param1 = t.translate("schedule_period");
				parameters.param2 = t.translate("period_start_label");
				msgs.push(t.translate("schedule_invalid_time", parameters));
				$iStartTime.attr({
					'aria-invalid': 'true',
					'aria-describedby': msgs[0]
				});
			} else if (!noEndDateChecked && !this.rangeEndTime.isValidTime()) {
				parameters.param1 = t.translate("schedule_period");
				parameters.param2 = t.translate("period_end_label");
				msgs.push(t.translate("schedule_invalid_time", parameters));
				$iEndTime.attr({
					'aria-invalid': 'true',
					'aria-describedby': msgs[0]
				});
			} else if (this.startDate.isValidDate() && this.endDate.isValidDate()) {
				// Check start date is less than end date
				// No end date not checked
				if (!noEndDateChecked) {
					var startingDate = this.startDate.getDateObj();
					var endingDate = this.endDate.getDateObj();
					if (startingDate > endingDate) {
						parameters.param1 = t.translate("schedule_period");
						parameters.param2 = t.translate("schedule_datepicker_label");
						msgs.push(t.translate("schedule_invalid_date_range", parameters));
						$endDateDiv.attr({
							'aria-invalid': 'true',
							'aria-describedby': msgs[0]
						});
					}
				}
			}

			return msgs;
		},

		_renderDateTimeRangeTimePickers: function() {
			this.rangeStartTime = new TimePicker({
				$el: this.$el.find(".schedule_time_start"),
				timezone: this.timezone,
				ariaLabel: t.translate("period_start_time_label"),
				attributes: {
					showMeridian: !DateTimeUtils.is24HrFormat(this.locale)
				}
			});

			this.rangeStartTime.render();

			this.rangeEndTime = new TimePicker({
				$el: this.$el.find(".schedule_time_end"),
				timezone: this.timezone,
				ariaLabel: t.translate("period_end_time_label"),
				attributes: {
					showMeridian: !DateTimeUtils.is24HrFormat(this.locale)
				}
			});

			this.rangeEndTime.render();

			if (this.isEditMode) {
				if (this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.startDate) {
					this.rangeStartTime.setDateTimeUTC(this.descriptor.scheduleInfo.startDate);
				}
				if (this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.endDate) {
					this.rangeEndTime.setDateTimeUTC(this.descriptor.scheduleInfo.endDate);
				}
			}
		},

		_hideShowEndDate: function(name, value) {
			if (value) {
				this.$el.find(".schedule_date_section_end").hide();
			} else {
				this.$el.find(".schedule_date_section_end").show();
			}
		}
	});

	return DateTimeRange;

});