/* global BP_Nouveau, CommunityAllyLoader */
/* @since 3.0.0 */
/* @version 8.0.0 */
window.bp = window.bp || {};

( function( bp, $ ) {

	// Bail if not set.
	if ( typeof BP_Nouveau === 'undefined' ) {
		return;
	}

	bp.Nouveau = bp.Nouveau || {};

	/**
	 * [Activity description]
	 * @type {Object}
	 */
	bp.Nouveau.Notifications = {

		/**
		 * [start description]
		 * @return {[type]} [description]
		 */
		start: function() {
			this.setupGlobals();

			// Listen to events ("Add hooks!").
			this.addListeners();
		},

		/**
		 * [setupGlobals description]
		 * @return {[type]} [description]
		 */
		setupGlobals: function() {
			// Always reset sort to Newest notifications
			bp.Nouveau.setStorage( 'bp-notifications', 'extras', 'DESC' );
		},

		/**
		 * [addListeners description]
		 */
		addListeners: function() {
			// Trigger Notifications order request.
			$(document).on('click touchend', '[data-bp-notifications-order]', this.sortNotifications);

			// Enable the Apply Button once the bulk action is selected.
			$(document).on('change', '#notification-select', this.enableBulkSubmit);

			// Select all displayed notifications.
			$(document).on('click touchend', '.select-all-notifications', this.selectAll);

			// Process bulk update operation
			$(document).on('click touchend', '#notification-bulk-manage', this.bulkUpdate);

			// If user click on unread notification, mark as read and reload notifications
			$(document).on('click touchend', '[communityally-notification-id]', this, this.reloadNotifications);

			$(document).on('click touchend', '[communityally-notification-mark-read]', this, this.markReadNotifications);
			$(document).on('click touchend', '[communityally-notification-mark-unread]', this, this.markUnreadNotifications);
			$(document).on('click touchend', '[communityally-notification-delete]', this, this.deleteNotifications);

			// Pagination
			$(document).on('click touchend', '[communityally-members-notification-read-page-update] a', this, this.readNotificationPaginateAction);
			$(document).on('click touchend', '[communityally-members-notification-unread-page-update] a', this, this.unreadNotificationPaginateAction);
		},

		/**
		 * [sortNotifications description]
		 * @param  {[type]} event [description]
		 * @return {[type]}       [description]
		 */
		sortNotifications: function( event ) {
			event.preventDefault();

			let $target = $(event.currentTarget),
				sort = $target.data('bp-notifications-order'),
				$parent = $target.parents('.communityally-notification-element'),
				$entries = $parent.find('[communityally-sortable-entry]');

			$parent.find('[data-bp-notifications-order]').show();
			$parent.find('[data-bp-notifications-order="' + sort + '"]').hide();
			
			if ($entries.length <= 0) {
				return;
			}
			// the exsiting list is already in monotonic order
			let reference_value, $reference_entry;
			$entries.each(function(index, elem) {
				let $elem = $(elem),
					value = $elem.attr('communityally-sortable-entry');
				if (0 < index) {
					if (value > reference_value) {
						if ('ASC' === sort) {
							$reference_entry.after($elem);
						} else {
							$reference_entry.before($elem);
						}
					} else {
						if ('ASC' === sort) {
							$reference_entry.before($elem);
						} else {
							$reference_entry.after($elem);
						}
					}
				}
				$reference_entry = $elem;
				reference_value = value;
			});
		},

		/**
		 * [enableBulkSubmit description]
		 * @param  {[type]} event [description]
		 * @return {[type]}       [description]
		 */
		enableBulkSubmit: function( event ) {
			$( '#notification-bulk-manage' ).prop( 'disabled', $( event.currentTarget ).val().length <= 0 );
		},

		/**
		 * [selectAll description]
		 * @param  {[type]} event [description]
		 * @return {[type]}       [description]
		 */
		selectAll: function( event ) {
			let $check_all = $(event.currentTarget),
				is_checked = $check_all.prop('checked');
			$check_all.parents('table.notifications').find('.notification-check').prop('checked', is_checked);
		},

		/**
		 * Reload notifications, only runs when reading an unread notification
		 */
		reloadNotifications: function(event) {
			let self = event.data,
				notification_id = $(this).attr('communityally-notification-id'),
				data = {
					action: 'communityally_notifications_bulk_action',
					notification_bulk_action: 'read',
					ids: notification_id,
					silent: 'yes',
					nonce: CommunityAllyLoader.nonce
				};
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data
			});

			self.hideNotificationRow(notification_id);
		},

		/**
		 * Mark a notification as unread when clicking on the individual button
		 */
		markUnreadNotifications: function(event) {
			let self = event.data,
				notification_id = $(this).attr('communityally-notification-mark-unread'),
				data = {
					action: 'communityally_notifications_bulk_action',
					notification_bulk_action: 'unread',
					ids: notification_id,
					silent: 'yes',
					nonce: CommunityAllyLoader.nonce
				};
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data
			});

			self.hideNotificationRow(notification_id);
			return false;
		},

		/**
		 * Mark a notification as read when clicking on the individual button
		 */
		markReadNotifications: function(event) {
			let self = event.data,
				notification_id = $(this).attr('communityally-notification-mark-read'),
				data = {
					action: 'communityally_notifications_bulk_action',
					notification_bulk_action: 'read',
					ids: notification_id,
					silent: 'yes',
					nonce: CommunityAllyLoader.nonce
				};
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data
			});

			self.hideNotificationRow(notification_id);
			return false;
		},

		/**
		 * Delete notification when clicking on the individual delete button
		 */
		deleteNotifications: function(event) {
			let self = event.data,
				notification_id = $(this).attr('communityally-notification-delete'),
				data = {
					action: 'communityally_notifications_bulk_action',
					notification_bulk_action: 'delete',
					ids: notification_id,
					silent: 'yes',
					nonce: CommunityAllyLoader.nonce
				};
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data
			});

			self.hideNotificationRow(notification_id);
			return false;
		},

		hideNotificationRow: function(notification_id) {
			let $row = $('.communityally-notification-row-' + notification_id),
				$count_elem = $('.communityally-notification-count'),
				count = 0;
			if ($row.length <= 0) {
				return;
			}
			if ($count_elem.length > 0) {
				count = parseInt($count_elem[0].textContent);
			}
			if (isNaN(count)) {
				count = 0;
			}
			// uncheck any child checkboxes so they won't be included with bulk operations
			$row.find('input[type="checkbox"]').prop('checked', false).change();
			$row.fadeOut();

			--count;
			$count_elem.text(count);
		},

		/**
		 * Bulk update notifications
		 */
		bulkUpdate: function(event) {
			let $select_elem = $('#notification-select'),
				current_notification_type = $select_elem.attr('communityally-notification-type'),
				bulk_action = $select_elem.val(),
				$selected_notifications = $('input.notification-check:checked'),
				notification_ids = [];
			$selected_notifications.each(function(index, elem) {
				notification_ids.push($(elem).val());
			});
			if (notification_ids.length <= 0) {
				return false;
			}
			let data = {
					action: 'communityally_notifications_bulk_action',
					notification_bulk_action: bulk_action,
					notification_type: current_notification_type,
					ids: notification_ids.join('|'),
					nonce: CommunityAllyLoader.nonce
				};

			$('#communityally-wait-overlay').show();
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data,
				success: function(response) {
					try {
						var result = JSON.parse(response);
						if ('status' in result) {
							if ('success' === result['status']) {
								$('#communityally-members-notification-container').after(result['code']).remove();
							} else {
								throw result['message'];
							}
						}
					} catch (e) {
						let $error_elem = $('#communityally-members-notification-error-message');
						$error_elem.find('p').text(e);
						$error_elem.show();
					}
					$('#communityally-wait-overlay').hide();
				}
			});
			return false;
		},

		readNotificationPaginateAction: function(event) {
			let $this = $(this),
				$parent = $this.parents('[communityally-members-notification-read-page-update]'),
				data = {
					status: 'read',
					page: $this.attr('href')
				};
			if ($parent.length < 1) {
				return;
			}
			let user_id = $parent.attr('communityally-members-notification-read-page-update');
			event.data.notificationUpdateList(user_id, data);
			return false;
		},

		unreadNotificationPaginateAction: function(event) {
			let $this = $(this),
				$parent = $this.parents('[communityally-members-notification-unread-page-update]'),
				data = {
					status: 'unread',
					page: $this.attr('href')
				};
			if ($parent.length < 1) {
				return;
			}
			let user_id = $parent.attr('communityally-members-notification-unread-page-update');
			event.data.notificationUpdateList(user_id, data);
			return false;
		},

		notificationUpdateList: function(user_id, data) {
			data['action'] = 'communityally_members_get_notification_list';
			data['nonce'] = CommunityAllyLoader.nonce;
			data['user_id'] = user_id;

			$('#communityally-wait-overlay').show();
			$.ajax({
				type: 'POST',
				url: CommunityAllyLoader.ajax_url,
				data: data,
				success: function(response) {
					try {
						var result = JSON.parse(response);
						if ('status' in result) {
							if ('success' === result['status']) {
								$('#communityally-members-notification-container').after(result['code']).remove();
							} else {
								throw result['message'];
							}
						}
					} catch (e) {
						let $error_elem = $('#communityally-members-notification-error-message');
						$error_elem.find('p').text(e);
						$error_elem.show();
					}
					$('#communityally-wait-overlay').hide();
				}
			});
			return false;
		},
	};

	// Launch BP Nouveau Notifications.
	bp.Nouveau.Notifications.start();

} )( window.bp, jQuery );
