window.hbfwc = window.hbfwc || {};

function parse_str(str, array) {
	var strArr = String( str ).replace( /^&/, '' ).replace( /&$/, '' ).split( '&' );
	var sal    = strArr.length;
	var i;
	var j;
	var ct;
	var p;
	var lastObj;
	var obj;
	var chr;
	var tmp;
	var key;
	var value;
	var postLeftBracketPos;
	var keys;
	var keysLen;

	var _fixStr = function _fixStr(str) {
		return decodeURIComponent( str.replace( /\+/g, '%20' ) );
	};

	var $global      = typeof window !== 'undefined' ? window : global;
	$global.$locutus = $global.$locutus || {};
	var $locutus     = $global.$locutus;
	$locutus.php     = $locutus.php || {};

	if ( ! array) {
		array = $global;
	}

	for (i = 0; i < sal; i++) {
		tmp   = strArr[i].split( '=' );
		key   = _fixStr( tmp[0] );
		value = tmp.length < 2 ? '' : _fixStr( tmp[1] );

		while (key.charAt( 0 ) === ' ') {
			key = key.slice( 1 );
		}

		if (key.indexOf( '\x00' ) > -1) {
			key = key.slice( 0, key.indexOf( '\x00' ) );
		}

		if (key && key.charAt( 0 ) !== '[') {
			keys               = [];
			postLeftBracketPos = 0;

			for (j = 0; j < key.length; j++) {
				if (key.charAt( j ) === '[' && ! postLeftBracketPos) {
					postLeftBracketPos = j + 1;
				} else if (key.charAt( j ) === ']') {
					if (postLeftBracketPos) {
						if ( ! keys.length) {
							keys.push( key.slice( 0, postLeftBracketPos - 1 ) );
						}

						keys.push( key.substr( postLeftBracketPos, j - postLeftBracketPos ) );
						postLeftBracketPos = 0;

						if (key.charAt( j + 1 ) !== '[') {
							break;
						}
					}
				}
			}

			if ( ! keys.length) {
				keys = [key];
			}

			for (j = 0; j < keys[0].length; j++) {
				chr = keys[0].charAt( j );

				if (chr === ' ' || chr === '.' || chr === '[') {
					keys[0] = keys[0].substr( 0, j ) + '_' + keys[0].substr( j + 1 );
				}

				if (chr === '[') {
					break;
				}
			}

			obj = array;

			for (j = 0, keysLen = keys.length; j < keysLen; j++) {
				key     = keys[j].replace( /^['"]/, '' ).replace( /['"]$/, '' );
				lastObj = obj;

				if ((key === '' || key === ' ') && j !== 0) {
					// Insert new dimension
					ct = -1;

					for (p in obj) {
						if (obj.hasOwnProperty( p )) {
							if (+p > ct && p.match( /^\d+$/g )) {
								ct = +p;
							}
						}
					}

					key = ct + 1;
				}

				// if primitive value, replace with object
				if (Object( obj[key] ) !== obj[key]) {
					obj[key] = {};
				}

				obj = obj[key];
			}

			lastObj[key] = value;
		}
	}
};

hbfwc.avail = function ($) {
	const run = {
		init: function () {
			this.calendar_init();
			this.skip_dot();
			this.singular_rate();
			this.room_quantity();
			this.room_status();
			this.bulkForm_run();
		},
		skip_dot: function () {
			const invalidChars = [ hbfwc_admin_availability.thousand_sep ];
			$( document.body ).on(
				'keydown',
				'.hbfwc-rate-price__field, .bulk__price',
				function (e) {
					if (invalidChars.includes( e.key )) {
						e.preventDefault();
					}
				}
			);
		},
		bulkForm_run: function () {
			const d = this;

			d.appendNewAction();
			$( '.hbfwc-bulk__form-dates' ).each(
				function () {
					d.calbulk_init( this );
				}
			);

			$( '#hbfwc-bulk-add-date' ).on(
				'click',
				function (e) {
					e.preventDefault();
					const dvp = $( '#hbfwc-bulk__form-dates-wrapper' );
					let ndv   = dvp.find( '.hbfwc-bulk__form-dates:last-child' ).clone();

					$( ndv ).appendTo( dvp );
					$( ndv ).find( '.daterangepicker' ).remove();
					$( '.hbfwc-bulk__form-dates' ).each(
						function () {
							d.calbulk_init( this );
						}
					);
				}
			);

			$( document.body ).on(
				'click',
				'.hbfwc-rmv-bulk-date',
				function (e) {
					e.preventDefault();
					$( this ).closest( '.hbfwc-bulk__form-dates' ).remove();
				}
			).on(
				'click',
				'#hbfwc-bulk-add-action',
				function (e) {
					e.preventDefault();
					d.appendNewAction();
				}
			).on(
				'click',
				'.hbfwc-rmv-bulk-action',
				function (e) {
					e.preventDefault();
					$( this ).closest( '.hbfwc-bulk__form-action' ).remove();
				}
			).on(
				'click',
				'#call-bulk-form',
				function (e) {
					e.preventDefault();
					$( '#hbfwc-bulk__form' ).addClass( 'is_called' );
				}
			).on(
				'click',
				'.hbfwc-button-cancel-bulk-update, #hbfwc-bulk__form-backdrop',
				function (e) {
					e.preventDefault();
					$( '#hbfwc-bulk__form' ).removeClass( 'is_called' );
				}
			).on(
				'click',
				'#sync-calendar-btn',
				function (e) {
					e.preventDefault();
					$( '#hbfwc-sync__form' ).addClass( 'is_called' );
				}
			).on(
				'click',
				'.hbfwc-button-cancel-sync-cal, #hbfwc-sync__form-backdrop',
				function (e) {
					e.preventDefault();
					$( '#hbfwc-sync__form' ).removeClass( 'is_called' );
				}
			).on(
				'change',
				'.action-set_select',
				function () {
					const [parent, grandparent, vl] = [$( this ).closest( '.hbfwc-bulk__form-action' ), $( '#hbfwc-bulk__form-actions-wrapper' ), $( this ).val()];
					const nspan                     = $( parent ).find( '>span' );
					if ( grandparent.find( '.action-set__next_' + vl ).not( ':hidden' ).length > 0 ) {
						alert( 'Cannot create duplicate action. Please select another action.' );
						$( this ).val( '' ).trigger( 'change' );
						return false;
					}

					nspan.css( {display:'none'} );
					nspan.find( 'input, select' ).prop( 'required', false );
					if ( '' !== vl ) {
						const nspanvl = $( parent ).find( '.action-set__next_' + vl );
						nspanvl.css( {display: 'inline-block'} );
						nspanvl.find( 'input, select' ).prop( 'required', true );
					}
				}
			);

			$( '#hbfwc-bulk__form-the-form' ).on(
				'submit',
				function (e) {
					e.preventDefault();
					const f = this;

					$( f ).find( '.notice' ).remove();
					$( f ).addClass( 'hbfwc_on_admin_ajax' );
					const dt = $.param( $( f ).serializeArray() );
					let arr  = {};
					parse_str( dt, arr );
					const sendData = arr;

					const data = {
						data: sendData,
						action: 'hbfwc_bulk_update',
						security: hbfwc_admin_availability.bulk_update,
					};

					$.post(
						hbfwc_admin_availability.ajax_url,
						data,
						function (response) {
							if ( response.success === false ) {
								const err = $( '<div class="notice notice-error is-dismissible"><p>' + response.data.error + '</p></div>' );
								$( err ).insertAfter( $( '.hbfwc-bulk__form-wrap>h3' ) );
							} else {
								const smsg = $( '<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p></div>' );
								$( smsg ).insertAfter( $( '.hbfwc-bulk__form-wrap>h3' ) );
							}
							$( f ).removeClass( 'hbfwc_on_admin_ajax' );
							window.setTimeout(
								function () {
									$( f ).find( '.notice' ).slideUp( 300 );
								},
								1500
							);
							$( '#avail_dates__output' ).trigger( 'apply.daterangepicker', $( '#avail_dates__output' ).data( 'daterangepicker' ) );
						}
					)
				}
			);
		},
		appendNewAction: function () {
			if ( $( '#hbfwc-jstm__action-selection-html' ).length < 1 ) return;

			const [d,w,u] = [this,$( '#hbfwc-bulk__form-actions-wrapper' ),this.uniqId()];
			let na        = $( '#hbfwc-jstm__action-selection-html' ).html();
			na            = na.replaceAll( '{{%loop%}}', u );

			$( na ).appendTo( w );
		},
		calendar_init: function () {
			const d    = this;
			const comp = $( '#avail_dates__output' );
			const df   = comp.data( 'output-format' );

			moment.suppressDeprecationWarnings = true;
			comp.daterangepicker(
				{
					opens: 'right',
					showDropdowns: false,
					autoUpdateInput: false,
					startDate: $( '#avail_dates' ).find( 'input[name="from"]' ).val(),
					endDate: $( '#avail_dates' ).find( 'input[name="end"]' ).val(),
					minDate: comp.data( 'mindate' ),
					locale: {
						format: 'MM/DD/YYYY',
					},
					autoApply: true,
					showCancel: false,
				}
			);

			comp.on(
				'apply.daterangepicker',
				function (ev, picker) {
					const unixCi = moment( picker.startDate.format( 'MM/DD/YYYY' ) ).unix();
					const unixCo = moment( picker.endDate.format( 'MM/DD/YYYY' ) ).unix();

					let noOfNights = moment( picker.endDate.format( 'MM/DD/YYYY' ) ).diff( moment( picker.startDate.format( 'MM/DD/YYYY' ) ), "days" );

					if ( noOfNights < 1 ) {
						comp.data( 'daterangepicker' ).setStartDate( $( '#avail_dates' ).find( 'input[name="from"]' ).val() );
						comp.data( 'daterangepicker' ).setEndDate( $( '#avail_dates' ).find( 'input[name="end"]' ).val() );
						comp.trigger( 'click' );
						return false;
					}

					$( '#avail_dates' ).find( 'input[name="from"]' ).val( picker.startDate.format( 'MM/DD/YYYY' ) );
					$( this ).find( 'input[name="check-out"]' ).val( picker.endDate.format( 'MM/DD/YYYY' ) );
					$( this ).text( d.dateFormat( df,picker.startDate.format( 'MM/DD/YYYY' ) ) + ' - ' + d.dateFormat( df,picker.endDate.format( 'MM/DD/YYYY' ) ) );

					const prm       = { 'from': unixCi, 'end': unixCo};
					const urlParams = window.location.href + ( window.location.href.indexOf( '?' ) >= 0 ? '&' : '?' ) + $.param( prm );

					$( '#avail_form__calendar_wrap' ).addClass( 'hbfwc_on_admin_ajax' );

					$( '#avail_form__calendar_wrap' ).load(
						urlParams + " #avail_form__calendar_wrap>*",
						function () {
							$( '#avail_form__calendar_wrap' ).removeClass( 'hbfwc_on_admin_ajax' );
						}
					);
				}
			);
		},
		singular_rate: function () {
			$( document.body ).on(
				'change',
				'.hbfwc-rate-price__field',
				function () {
					const [d, price, date, rate] = [this, $( this ).val(), $( this ).data( 'date' ), $( this ).data( 'rate' )];

					let attrs = [
					{
						'name': 'price',
						'value': price
					},
					{
						'name': 'date',
						'value': date
					},
					{
						'name': 'rate_id',
						'value': rate
					}
					];
					let arr   = {};
					parse_str( $.param( attrs ), arr );
					const sendData = arr;

					const data = {
						post_id: hbfwc_admin_availability.post_id,
						data: sendData,
						action: 'hbfwc_update_room_price',
						security: hbfwc_admin_availability.modify_price,
					};
					$( d ).closest( 'li' ).addClass( 'hbfwc_on_admin_ajax' );
					$.post(
						hbfwc_admin_availability.ajax_url,
						data,
						function (response) {
							if ( response.success === false ) {
								// Error.
								window.alert( response.data.error );
							}
							$( d ).closest( 'li' ).removeClass( 'hbfwc_on_admin_ajax' );
						}
					)
				}
			).on(
				'change',
				'.hbfwc-rate-status__field',
				function () {
					const [d, date, rate] = [this, $( this ).data( 'date' ), $( this ).data( 'rate' )];
					const sts             = $( d ).is( ':checked' ) ? 1 : 0;
					const stsClass        = sts === 1 ? 'unit_is_active' : 'unit_not_active';

					let attrs = [
					{
						'name': 'status',
						'value': sts
					},
					{
						'name': 'date',
						'value': date
					},
					{
						'name': 'rate_id',
						'value': rate
					}
					];
					let arr   = {};
					parse_str( $.param( attrs ), arr );
					const sendData = arr;

					const data = {
						post_id: hbfwc_admin_availability.post_id,
						data: sendData,
						action: 'hbfwc_update_rate_status',
						security: hbfwc_admin_availability.modify_rate_status,
					};
					$( d ).closest( 'li' ).addClass( 'hbfwc_on_admin_ajax' );
					$.post(
						hbfwc_admin_availability.ajax_url,
						data,
						function (response) {
							if ( response.error ) {
								// Error.
								window.alert( response.error );
							} else {
								$( d ).closest( 'li' ).removeClass( 'unit_is_active' ).removeClass( 'unit_not_active' ).addClass( stsClass );
							}
							$( d ).closest( 'li' ).removeClass( 'hbfwc_on_admin_ajax' );
						}
					)
				}
			);
		},
		room_quantity: function () {
			$( document.body ).on(
				'change',
				'.hbfwc-room-quantity__field',
				function () {
					const [d, qty, max, date] = [this, $( this ).val(), $( this ).data( 'max' ), $( this ).data( 'date' )];

					if ( qty > max ) {
						$( this ).val( max );
						$( this ).trigger( 'change' );
						return false;
					}

					let attrs = [
					{
						'name': 'qty',
						'value': qty
					},
					{
						'name': 'max',
						'value': max
					},
					{
						'name': 'date',
						'value': date
					}
					];
					let arr   = {};
					parse_str( $.param( attrs ), arr );
					const sendData = arr;

					const data = {
						post_id: hbfwc_admin_availability.post_id,
						data: sendData,
						action: 'hbfwc_update_room_data',
						security: hbfwc_admin_availability.modify_qty,
					};
					$( d ).closest( 'li' ).addClass( 'hbfwc_on_admin_ajax' );
					$.post(
						hbfwc_admin_availability.ajax_url,
						data,
						function (response) {
							if ( response.success === false ) {
								// Error.
								window.alert( response.data.error );
							}
							$( d ).closest( 'li' ).removeClass( 'hbfwc_on_admin_ajax' );
						}
					)
				}
			);
		},
		room_status: function () {
			$( document.body ).on(
				'change',
				'.hbfwc-room-status__field',
				function () {
					const [d, max, date, qty] = [this, $( this ).data( 'max' ), $( this ).data( 'date' ), $( this ).closest( 'ul' ).find( '.hbfwc-room-quantity__field' ).val()];
					const sts                 = $( d ).is( ':checked' ) ? 1 : 0;
					const stsClass            = sts === 1 ? 'unit_is_active' : 'unit_not_active';

					let attrs = [
					{
						'name': 'status',
						'value': sts
					},
					{
						'name': 'qty',
						'value': qty
					},
					{
						'name': 'max',
						'value': max
					},
					{
						'name': 'date',
						'value': date
					}
					];
					let arr   = {};
					parse_str( $.param( attrs ), arr );
					const sendData = arr;

					const data = {
						post_id: hbfwc_admin_availability.post_id,
						data: sendData,
						action: 'hbfwc_update_room_status',
						security: hbfwc_admin_availability.modify_status,
					};
					$( d ).closest( 'li' ).addClass( 'hbfwc_on_admin_ajax' );
					$.post(
						hbfwc_admin_availability.ajax_url,
						data,
						function (response) {
							if ( response.success === false ) {
								// Error.
								window.alert( response.data.error );
								sts === 1 ? $( d ).prop('checked', false) : $( d ).prop('checked', true);
							} else {
								$( d ).closest( 'li' ).removeClass( 'unit_is_active' ).removeClass( 'unit_not_active' ).addClass( stsClass );
							}
							$( d ).closest( 'li' ).removeClass( 'hbfwc_on_admin_ajax' );
						}
					);
				}
			)
		},
		dateFormat: function (format,date) {
			if ( ! date || date === "") {
				date = new Date();
			} else if (typeof('date') !== 'object') {
				date = new Date( date.replace( /-/g,"/" ) ); // attempt to convert string to date object
			}

			var string = '',
				mo     = date.getMonth(),   // month (0-11)
				m1     = mo + 1,			    // month (1-12)
				dow    = date.getDay(),    // day of week (0-6)
				d      = date.getDate(),     // day of the month (1-31)
				y      = date.getFullYear(), // 1999 or 2003
				h      = date.getHours(),    // hour (0-23)
				mi     = date.getMinutes(), // minute (0-59)
				s      = date.getSeconds();  // seconds (0-59)

			for (var i = 0, len = format.length; i < len; i++) {
				switch (format[i]) {
					case 'j': // Day of the month without leading zeros  (1 to 31)
						string += d;
						break;

					case 'd': // Day of the month, 2 digits with leading zeros (01 to 31)
						string += (d < 10) ? "0" + d : d;
						break;

					case 'l': // (lowercase 'L') A full textual representation of the day of the week
						var days = Array( "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" );
						string  += days[dow];
						break;

					case 'w': // Numeric representation of the day of the week (0=Sunday,1=Monday,...6=Saturday)
						string += dow;
						break;

					case 'D': // A textual representation of a day, three letters
						days    = Array( "Sun","Mon","Tue","Wed","Thr","Fri","Sat" );
						string += days[dow];
						break;

					case 'm': // Numeric representation of a month, with leading zeros (01 to 12)
						string += (m1 < 10) ? "0" + m1 : m1;
						break;

					case 'n': // Numeric representation of a month, without leading zeros (1 to 12)
						string += m1;
						break;

					case 'F': // A full textual representation of a month, such as January or March
						var months = Array( "January","February","March","April","May","June","July","August","September","October","November","December" );
						string    += months[mo];
						break;

					case 'M': // A short textual representation of a month, three letters (Jan - Dec)
						months  = Array( "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" );
						string += months[mo];
						break;

					case 'Y': // A full numeric representation of a year, 4 digits (1999 OR 2003)
						string += y;
						break;

					case 'y': // A two digit representation of a year (99 OR 03)
						string += y.toString().slice( -2 );
						break;

					case 'H': // 24-hour format of an hour with leading zeros (00 to 23)
						string += (h < 10) ? "0" + h : h;
						break;

					case 'g': // 12-hour format of an hour without leading zeros (1 to 12)
						var hour = (h === 0) ? 12 : h;
						string  += (hour > 12) ? hour - 12 : hour;
						break;

					case 'h': // 12-hour format of an hour with leading zeros (01 to 12)
						hour    = (h === 0) ? 12 : h;
						hour    = ( hour > 12) ? hour - 12 : hour;
						string += (hour < 10) ? "0" + hour : hour;
						break;

					case 'a': // Lowercase Ante meridiem and Post meridiem (am or pm)
						string += (h < 12) ? "am" : "pm";
						break;

					case 'i': // Minutes with leading zeros (00 to 59)
						string += (mi < 10) ? "0" + mi : mi;
						break;

					case 's': // Seconds, with leading zeros (00 to 59)
						string += (s < 10) ? "0" + s : s;
						break;

					case 'c': // ISO 8601 date (eg: 2012-11-20T18:05:54.944Z)
						string += date.toISOString();
						break;

					default:
						string += format[i];
				}
			}

			return string;
		},
		calbulk_init: function (e) {
			const [d,disp,df,md,ip] = [this,$( e ).find( '.hbfwc-bulk__form-date-output' ),$( e ).data( 'output-format' ),$( e ).data( 'mindate' ),$( e ).find( 'input' )];
			const idt               = ip.val().split( '-' );

			moment.suppressDeprecationWarnings = true;
			disp.daterangepicker(
				{
					opens: 'right',
					showDropdowns: false,
					autoUpdateInput: false,
					startDate: idt[0],
					endDate: idt[1],
					minDate: md,
					locale: {
						format: 'MM/DD/YYYY',
					},
					autoApply: true,
					showCancel: false,
					parentEl: e
				}
			);

			disp.on(
				'apply.daterangepicker',
				function (ev, picker) {
					let noOfNights = moment( picker.endDate.format( 'MM/DD/YYYY' ) ).diff( moment( picker.startDate.format( 'MM/DD/YYYY' ) ), "days" );

					if ( noOfNights < 1 ) {
						$( this ).data( 'daterangepicker' ).setStartDate( idt[0] );
						$( this ).data( 'daterangepicker' ).setEndDate( idt[1] );
						$( this ).trigger( 'click' );
						return false;
					}

					ip.val( picker.startDate.format( 'MM/DD/YYYY' ) + '-' + picker.endDate.format( 'MM/DD/YYYY' ) ).trigger( 'change' );
					$( this ).text( d.dateFormat( df,picker.startDate.format( 'MM/DD/YYYY' ) ) + ' ⇢ ' + d.dateFormat( df,picker.endDate.format( 'MM/DD/YYYY' ) ) );
				}
			)
		},
		uniqId: function () {
			let n    = new Date().getTime();
			let base = Math.floor( n / 1000 );
			if (window.performance) {
				const s = performance.timing.navigationStart;
				n       = performance.now();
				base    = Math.floor( (s + Math.floor( n )) / 1000 );
			}

			const ext = Math.floor( n % 1000 * 1000 );
			let now   = ("00000000" + base.toString( 16 )).slice( -8 ) + ("000000" + ext.toString( 16 )).slice( -5 );
			if (now <= window.my_last_uid) {
				now = (parseInt( window.my_last_uid ? window.my_last_uid : now, 16 ) + 1).toString( 16 );
			}
			window.my_last_uid = now;
			return 'hbfwc' + now;
		}
	};
	run.init();
	return run;
}(window.jQuery);