/**
 * This is the object that stores all calendar data when editing a calendar
 *
 * Its structure is by year, month, day basis. Eg: wpsbc_calendar_data[2018][1][21]
 *
 */
var wpsbc_calendar_data = {};

jQuery(function ($) {

	/**
	 * Retrieves an array with the query arguments found in a given string
	 *
	 */
	function get_query_args(string) {

		var query_arr = string.replace('?', '').split('&');
		var query_params = [];

		for (var q = 0, q_query_arr = query_arr.length; q < q_query_arr; q++) {

			var q_arr = query_arr[q].split('=');
			query_params[q_arr[0]] = q_arr[1];

		}

		return query_params;

	}

	/**
	 * Resizes the calendar to always have square dates
	 *
	 */
	function resize_calendar($calendars_wrapper) {

		var td_width = $calendars_wrapper.find('td').first().width();

		$calendars_wrapper.find('td .wpsbc-date-inner, td .wpsbc-week-number').css('height', td_width + 'px');
		$calendars_wrapper.find('td .wpsbc-date-inner, td .wpsbc-week-number').css('line-height', td_width + 'px');

		$calendars_wrapper.css('visibility', 'visible');

	}


	/**
	 * Refreshed the output of the calendar with the given data
	 *
	 */
	function refresh_calendar($calendar_container, current_year, current_month) {

		var $calendar_container = $calendar_container;
		var $calendar_editor = $('#wpsbc-calendar-editor');

		if ($calendar_container.hasClass('wpsbc-is-loading'))
			return false;

		/**
		 * Prepare the calendar data
		 *
		 */
		var data = $calendar_container.data();

		data['action'] = 'wpsbc_refresh_calendar_editor';
		data['current_year'] = current_year;
		data['current_month'] = current_month;
		data['calendar_data'] = JSON.stringify(wpsbc_calendar_data);
		
		if(typeof wpsbc_bulk_edit_availability_start_date !== 'undefined'){
			wpsbc_bulk_editor_default_date = new Date();
			wpsbc_bulk_editor_default_date.setMonth(current_month - 1);
			wpsbc_bulk_editor_default_date.setYear(current_year);
			wpsbc_bulk_edit_availability_start_date.datepicker('option', 'defaultDate', wpsbc_bulk_editor_default_date)
		}

		/**
		 * Add loading animation
		 *
		 */
		$calendar_container.find('.wpsbc-calendar').append('<div class="wpsbc-overlay"><div class="wpsbc-overlay-spinner"><div class="wpsbc-overlay-bounce1"></div><div class="wpsbc-overlay-bounce2"></div><div class="wpsbc-overlay-bounce3"></div></div></div>');
		$calendar_container.addClass('wpsbc-is-loading');
		$calendar_container.find('select').attr('disabled', true);

		$('#wpsbc-calendar-editor').append('<div class="wpsbc-overlay"><div class="wpsbc-overlay-spinner"><div class="wpsbc-overlay-bounce1"></div><div class="wpsbc-overlay-bounce2"></div><div class="wpsbc-overlay-bounce3"></div></div></div>');

		/**
		 * Make the request
		 *
		 */
		$.post(ajaxurl, data, function (response) {

			response = JSON.parse(response);

			$calendar_container.replaceWith(response.calendar);
			$calendar_editor.replaceWith(response.calendar_editor);

			resize_calendar($('.wpsbc-container[data-id="' + data['id'] + '"]'));
			refresh_calendar_dates();

		});

	}


	/**
	 * Updates the calendar legend items icons of each date from the 
	 * data found in wpsbc_calendar_data for the legend items
	 *
	 */
	function refresh_calendar_dates() {

		var $calendar_container = $('.wpsbc-container');

		var year = $calendar_container.data('current_year');
		var month = $calendar_container.data('current_month');

		if (typeof wpsbc_calendar_data[year] == 'undefined')
			return false;

		if (typeof wpsbc_calendar_data[year][month] == 'undefined')
			return false;

		for (day in wpsbc_calendar_data[year][month]) {

			if (typeof wpsbc_calendar_data[year][month][day] == 'undefined')
				continue;

			if (typeof wpsbc_calendar_data[year][month][day]['legend_item_id'] == 'undefined')
				continue;

			var $legend_item_selector = $('.wpsbc-calendar-date-legend-item select[data-year="' + year + '"][data-month="' + month + '"][data-day="' + day + '"]');

			$calendar_container.find('[data-year="' + year + '"][data-month="' + month + '"][data-day="' + day + '"] .wpsbc-legend-item-icon')
				.attr('class', 'wpsbc-legend-item-icon wpsbc-legend-item-icon-' + $legend_item_selector.val())
				.attr('data-type', $legend_item_selector.find('option:selected').data('type'));

		}

	}


	/**
	 * Callback function that is triggered on changes made to input, textarea, select, etc.
	 * fields from the calendar editor
	 *
	 */
	function calendar_editor_field_change($input) {

		/**
		 * Exit if the input does not have the needed data values
		 *
		 */
		if (typeof $input.data('year') == 'undefined')
			return false;

		if (typeof $input.data('month') == 'undefined')
			return false;

		if (typeof $input.data('day') == 'undefined')
			return false;

		if (typeof $input.data('name') == 'undefined')
			return false;

		/**
		 * Sanitize the data values and set them as variables
		 *
		 */
		var year = parseInt($input.data('year'));
		var month = parseInt($input.data('month'));
		var day = parseInt($input.data('day'));
		var name = $input.data('name');

		// Update data
		update_calendar_data(year, month, day, name, $input.val());

	}


	/**
	 * Updates the calendar data object with new data from the provided field
	 *
	 */
	function update_calendar_data(year, month, day, field_name, field_value) {

		if (typeof field_name == 'undefined')
			return false;

		if (typeof field_value == 'undefined')
			return false;

		/**
		 * Create the object for each date layer if needed
		 *
		 */
		if (typeof wpsbc_calendar_data[year] == 'undefined')
			wpsbc_calendar_data[year] = {};

		if (typeof wpsbc_calendar_data[year][month] == 'undefined')
			wpsbc_calendar_data[year][month] = {};

		if (typeof wpsbc_calendar_data[year][month][day] == 'undefined')
			wpsbc_calendar_data[year][month][day] = {};

		/**
		 * Set the value for the current date
		 *
		 */
		wpsbc_calendar_data[year][month][day][field_name] = field_value;

	}


	/**
	 * Resize the calendars on page load
	 *
	 */
	$('.wpsbc-container').each(function () {
		resize_calendar($(this));
	});

	/**
	 * Resize the calendars on page resize
	 *
	 */
	$(window).on('resize', function () {
		$('.wpsbc-container').each(function () {
			resize_calendar($(this));
		});
	});


	/**
	 * Handles the navigation of the Previous button
	 *
	 */
	$(document).on('click', '.wpsbc-container .wpsbc-prev', function (e) {

		e.preventDefault();

		// Set container
		var $container = $(this).closest('.wpsbc-container');

		// Set the current year and month that are displayed in the calendar
		var current_month = $container.data('current_month');
		var current_year = $container.data('current_year');

		// Calculate the 
		var navigate_count = 1;

		// Take into account jump months option
		if (typeof $container.data('jump_months') != 'undefined' && $container.data('jump_months') == '1')
			navigate_count = parseInt($container.data('months_to_show'));

		for (var i = 1; i <= navigate_count; i++) {

			current_month -= 1;

			if (current_month < 1) {
				current_month = 12;
				current_year -= 1;
			}

		}

		refresh_calendar($container, current_year, current_month);

	});

	/**
	 * Handles the navigation of the Next button
	 *
	 */
	$(document).on('click', '.wpsbc-container .wpsbc-next', function (e) {

		e.preventDefault();

		// Set container
		var $container = $(this).closest('.wpsbc-container');

		// Set the current year and month that are displayed in the calendar
		var current_month = $container.data('current_month');
		var current_year = $container.data('current_year');

		// Calculate the 
		var navigate_count = 1;

		// Take into account jump months option
		if (typeof $container.data('jump_months') != 'undefined' && $container.data('jump_months') == '1')
			navigate_count = parseInt($container.data('months_to_show'));

		for (var i = 1; i <= navigate_count; i++) {

			current_month += 1;

			if (current_month > 12) {
				current_month = 1;
				current_year += 1;
			}

		}

		refresh_calendar($container, current_year, current_month);

	});

	/**
	 * Handles the navigation of the Month Selector
	 *
	 */
	$(document).on('change', '.wpsbc-container .wpsbc-select-container select', function () {

		// Set container
		var $container = $(this).closest('.wpsbc-container');

		var date = new Date($(this).val() * 1000);

		var year = date.getFullYear();
		var month = date.getMonth() + 1;

		refresh_calendar($container, year, month);

	});


	/**
	 * Updates the calendar wpsbc_calendar_data object when doing changes in the
	 * calendar editor
	 *
	 */
	$(document).on('change', '#wpsbc-calendar-editor select', function () {

		calendar_editor_field_change($(this));

	});

	$(document).on('keyup change blur', '#wpsbc-calendar-editor input, #wpsbc-calendar-editor textarea', function () {

		calendar_editor_field_change($(this));

	});


	/**
	 * Handle legend item select change in edit caledndar screen
	 *
	 */
	$(document).on('change', '.wpsbc-calendar-date-legend-item select', function () {

		$(this).siblings('div').find('.wpsbc-legend-item-icon')
			.attr('class', 'wpsbc-legend-item-icon wpsbc-legend-item-icon-' + $(this).val())
			.attr('data-type', $(this).find('option:selected').data('type'));

		$(this).closest('.wpsbc-calendar-date-legend-item')
			.attr('class', 'wpsbc-calendar-date-legend-item wpsbc-calendar-date-legend-item-' + $(this).val());

		refresh_calendar_dates();

	});

	/**
	 * Handles the saving of the calendar by making an AJAX call to the server
	 * with the wpsbc_calendar_data.
	 *
	 * Upon success refreshes the page and adds a success message
	 *
	 */
	$(document).on('click', '.wpsbc-save-calendar', function (e) {

		e.preventDefault();

		var form_data = $(this).closest('form').serialize();

		var data = {
			action: 'wpsbc_save_calendar_data',
			form_data: form_data,
			calendar_data: JSON.stringify(wpsbc_calendar_data),
			current_year: $('.wpsbc-container').data('current_year'),
			current_month: $('.wpsbc-container').data('current_month'),
			wpsbc_token: $("#wpsbc_token").val()
		}

		// Disable all buttons and show loading spinner
		$('.wpsbc-wrap-edit-calendar input, .wpsbc-wrap-edit-calendar select, .wpsbc-wrap-edit-calendar textarea').attr('disabled', true);
		$(this).siblings('.wpsbc-save-calendar-spinner').css('visibility', 'visible');

		$.post(ajaxurl, data, function (response) {

			if (typeof response != 'undefined')
				window.location.replace(response);

		});

	});


	/**
	 * Initialize datepickers for Bulk Availability and CSV Export
	 *
	 */

    wpsbc_datepicker_week_start = (wpsbc_plugin_settings.backend_start_day) ? wpsbc_plugin_settings.backend_start_day : 1;

    // Bulk Edit Availability
    var wpsbc_bulk_edit_availability_start_date = $('#wpsbc-bulk-edit-availability-start-date').datepicker({
		dateFormat: 'yy-mm-dd',
		changeMonth: true,
		changeYear: true,
		showOtherMonths: true,
		selectOtherMonths: true,
		firstDay: wpsbc_datepicker_week_start,
		beforeShow: function () {
			$('#ui-datepicker-div').addClass('wpsbc-datepicker');
		},
		onClose: function () {
			$('#ui-datepicker-div').hide().removeClass('wpsbc-datepicker');
			wpsbc_bulk_edit_availability_end_date.focus();
		}	
    }).on('change', function(){
        wpsbc_bulk_edit_availability_end_date.datepicker( "option", "minDate", wpsbc_datepicker_get_date( this ) );
    }),
    
    wpsbc_bulk_edit_availability_end_date = $('#wpsbc-bulk-edit-availability-end-date').datepicker({
		dateFormat: 'yy-mm-dd',
		changeMonth: true,
		changeYear: true,
		showOtherMonths: true,
		selectOtherMonths: true,
		firstDay: wpsbc_datepicker_week_start,
		beforeShow: function () {
			$('#ui-datepicker-div').addClass('wpsbc-datepicker');
		},
		onClose: function () {
			$('#ui-datepicker-div').hide().removeClass('wpsbc-datepicker');
		}        
    })
    
    // CSV Export
    var wpsbc_export_csv_start_date = $('#wpsbc-export-csv-start-date').datepicker({
		dateFormat: 'yy-mm-dd',
		changeMonth: true,
		changeYear: true,
		showOtherMonths: true,
		selectOtherMonths: true,
		firstDay: wpsbc_datepicker_week_start,
		beforeShow: function () {
			$('#ui-datepicker-div').addClass('wpsbc-datepicker');
		},
		onClose: function () {
			$('#ui-datepicker-div').hide().removeClass('wpsbc-datepicker');
			wpsbc_export_csv_end_date.focus();
		}
	}).on('change', function(){
        wpsbc_export_csv_end_date.datepicker( "option", "minDate", wpsbc_datepicker_get_date( this ) );
    }),
    wpsbc_export_csv_end_date = $('#wpsbc-export-csv-end-date').datepicker({
		dateFormat: 'yy-mm-dd',
		changeMonth: true,
		changeYear: true,
		showOtherMonths: true,
		selectOtherMonths: true,
		firstDay: wpsbc_datepicker_week_start,
		beforeShow: function () {
			$('#ui-datepicker-div').addClass('wpsbc-datepicker');
		},
		onClose: function () {
			$('#ui-datepicker-div').hide().removeClass('wpsbc-datepicker');
		}
	})


	/**
	 * Handle bulk edit availability
	 *
	 */
	var wpsbc_calendar_data_cache = '';

	$(document).on('click', '#wpsbc-bulk-edit-availability', function (e) {

		e.preventDefault();

		var start_date = new Date($('#wpsbc-bulk-edit-availability-start-date').val());
		var end_date = new Date($('#wpsbc-bulk-edit-availability-end-date').val());
		var legend_item_id = $('#wpsbc-bulk-edit-availability-legend-item').val();
		var description = $('#wpsbc-bulk-edit-availability-description').val();
		var tooltip = $('#wpsbc-bulk-edit-availability-tooltip').val();

		var week_days = [];
		$.each($('.wpsbc-bulk-edit-availability-week-day:checked'), function () {
			week_days.push(parseInt($(this).val()));
		});

		if (isNaN(start_date.getTime()) || isNaN(end_date.getTime()) || legend_item_id == '')
			return false;

		var start_year = start_date.getUTCFullYear();
		var start_month = start_date.getUTCMonth() + 1;
		var start_day = start_date.getUTCDate();

		var end_year = end_date.getUTCFullYear();
		var end_month = end_date.getUTCMonth() + 1;
		var end_day = end_date.getUTCDate();

		// Cache the calendar data before manipulating it
		wpsbc_calendar_data_cache = JSON.stringify(wpsbc_calendar_data);

		for (var year = start_year; year <= end_year; year++) {

			for (var month = (year == start_year ? start_month : 1); month <= (year == end_year ? end_month : 12); month++) {

				// Get the last day of the month
				var last_month_day = new Date(year, month, 0);

				for (var day = (year == start_year && month == start_month ? start_day : 1); day <= (year == end_year && month == end_month ? end_day : last_month_day.getDate()); day++) {

					var day_of_the_week = new Date(year, month - 1, day).getDay();

					if (week_days.length > 0 && $.inArray(day_of_the_week, week_days) === -1) {
						continue;
					}

					// Update the calendar data
					update_calendar_data(year, month, day, 'legend_item_id', legend_item_id);
					update_calendar_data(year, month, day, 'description', description);
					update_calendar_data(year, month, day, 'tooltip', tooltip);

				}

			}

		}

		// Refresh the calendar to add the data
		refresh_calendar($('.wpsbc-container'), $('.wpsbc-container').data('current_year'), $('.wpsbc-container').data('current_month'));

		// Make the Undo button available
		$('#wpsbc-bulk-edit-availability-undo').removeClass('wpsbc-inactive');

	});

	/**
     * Datepicker helper function
     * 
     */
    function wpsbc_datepicker_get_date( element ) {
        var date;
        try {
            date = $.datepicker.parseDate( 'yy-mm-dd', element.value );
        } catch( error ) {
            date = null;
        }
        return date;
    }

	/**
	 * Undo the latest bulk availability changes
	 *
	 */
	$(document).on('click', '#wpsbc-bulk-edit-availability-undo', function (e) {

		e.preventDefault();

		$(this).blur();

		if ($(this).hasClass('wpsbc-inactive'))
			return false;

		if (!confirm("Are you sure you want to undo the last bulk action?"))
			return false;

		// Set the calendar data to the cached one
		wpsbc_calendar_data = JSON.parse(wpsbc_calendar_data_cache);

		// Refresh the calendar to add the data
		refresh_calendar($('.wpsbc-container'), $('.wpsbc-container').data('current_year'), $('.wpsbc-container').data('current_month'));

		// Make the Undo button unavailable
		$('#wpsbc-bulk-edit-availability-undo').addClass('wpsbc-inactive');

	});

});