<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}
/**
 * Ajax routine to Store Device id token generated from Google's FireBase
 * based on user subscription from browser to allow push notifications.
 *
 * @param string   $_POST['device_id'] Device id sent from firebase ajax routine
 * @param string   $_POST['subscriptionoptions'] Push notification subscription code using Firebase as push notification provider
 * @param string   $_POST['onesignal_subscriptionoptions'] Push notification subscription code using Onesignal as push notification provider
 * @param string   $_POST['pushtype'] Push notification call types using Firebase/Onesignal push notification
 * @param string   $_POST['onesignal_externalid'] Onesignal push notification external id
 * @param string   $_POST['pnfpb_endpoint'] Push notification Subscription endpoint
 * @param string   $_POST['pnfpb_options'] Push notification subscription vapid key
 *
 *
 * @since 1.0.0
 */

// Check the nonce first
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['nonce'])), 'pnfpbpushnonce' ) ) {
	echo wp_json_encode(array('subscriptionstatus' => 'error', 'message' => 'Security validation failed'));
} else {
	require __DIR__ . '/../../vendor/autoload.php';


	/** Get instance of class to subscribe Firebase topics based on  subscription options **/
	$PNFPB_ajax_subscription_update_obj = new PNFPB_httpv1_subscription_option_update();

	// phpcs:ignoreFile WordPress.DB.DirectDatabaseQuery

	$bpdeviceid = '';
	if (isset($_POST['device_id'])) {
		/** Sanitize the device id generated by Google's Firebase for the user who subscribed push notification  **/
		$bpdeviceid = sanitize_text_field(wp_unslash($_POST['device_id']));
	}
	$bpsubscribeoptions = '10000000000';
	if (isset($_POST['subscriptionoptions']) && is_numeric(sanitize_text_field(wp_unslash($_POST['subscriptionoptions'])))) {
		$bpsubscribeoptions = sanitize_text_field(wp_unslash($_POST['subscriptionoptions']));
		$bpsubscribeoptions = esc_html($bpsubscribeoptions);
	}
	if (isset($_POST['onesignal_subscriptionoptions']) && is_numeric(sanitize_text_field(wp_unslash($_POST['onesignal_subscriptionoptions'])))) {
		$bpsubscribeoptions = sanitize_text_field(wp_unslash($_POST['onesignal_subscriptionoptions']));
		$bpsubscribeoptions = esc_html($bpsubscribeoptions);
	}
	if ($bpsubscribeoptions === '' || $bpsubscribeoptions === '10000') {
		$bpsubscribeoptions = '10000000000';
	}
	$bponesignalid = 0;
	if (isset($_POST['onesignal_get_subscriptionoptions_id'])) {
		$bponesignalid = sanitize_text_field(wp_unslash($_POST['onesignal_get_subscriptionoptions_id']));
		$bponesignalid = esc_html($bponesignalid);
		if ($bponesignalid === '1pnfpbadm') {
			$bponesignalid = 1;
		}
		if ($bponesignalid === null || ($bponesignalid !== null && !is_numeric($bponesignalid)) || $bponesignalid === '') {
			$bponesignalid = 0;
		}
	}
	if (isset($_POST['progressier_subscriptionoptions']) && sanitize_text_field(wp_unslash($_POST['progressier_subscriptionoptions']))) {
		$bpsubscribeoptions = sanitize_text_field(wp_unslash($_POST['progressier_subscriptionoptions']));
		$bpsubscribeoptions = esc_html($bpsubscribeoptions);
		if ($bpsubscribeoptions === '' || $bpsubscribeoptions === '10000') {
			$bpsubscribeoptions = '10000000000';
		}
	}
	$bpprogressierid = 0;
	if (isset($_POST['progressier_get_subscriptionoptions_id']) && is_numeric(sanitize_text_field(wp_unslash($_POST['progressier_get_subscriptionoptions_id'])))) {
		$bpprogressierid = sanitize_text_field(wp_unslash($_POST['progressier_get_subscriptionoptions_id']));
		$bpprogressierid = esc_html($bpprogressierid);
		if ($bpprogressierid === null || ($bpprogressierid !== null && !is_numeric($bpprogressierid)) || $bpprogressierid === '') {
			$bpprogressierid = 0;
		}
	}

	$bpwebtoappid = 0;
	if (isset($_POST['webtoapp_userid']) && is_numeric(sanitize_text_field(wp_unslash($_POST['webtoapp_userid'])))) {
		$bpwebtoappid = sanitize_text_field(wp_unslash($_POST['webtoapp_userid']));
		$bpwebtoappid = esc_html($bpwebtoappid);
		if ($bpwebtoappid === null || ($bpwebtoappid !== null && !is_numeric($bpwebtoappid)) || $bpwebtoappid === '') {
			$bpwebtoappid = 0;
		}
	}

	$bpwebtoapp_deviceid = '';
	if (isset($_POST['webtoapp_deviceid'])) {
		$bpwebtoapp_deviceid = sanitize_text_field(wp_unslash($_POST['webtoapp_deviceid']));
		$bpwebtoapp_deviceid = esc_html($bpwebtoapp_deviceid);
	}
	
	$bpnotification_id = 0;
	if (isset($_POST['notification_id']) && is_numeric(sanitize_text_field(wp_unslash($_POST['notification_id'])))) {
		/** Sanitize the device id generated by Google's Firebase for the user who subscribed push notification  **/
		$bpnotification_id = sanitize_text_field(wp_unslash($_POST['notification_id']));
		$bpnotification_id = intval(esc_html($bpnotification_id));
	}	

	/** securing data from Firebase who subscribed push notification  **/
	$bpdeviceid = esc_html($bpdeviceid);
	$pushtype = 'normal';
	global $wpdb;
	$table = $wpdb->prefix . 'pnfpb_ic_subscribed_deviceids_web';
	$dbname = $wpdb->dbname;
	if (isset($_POST['pushtype'])) {
		$pushtype = sanitize_text_field(wp_unslash($_POST['pushtype']));
		$pushtype = esc_html($pushtype);
	}
	
	$delivered_notification_title = '';
	$delivered_notification_content = '';
	$delivered_notification_browser = '';
	$delivered_notification_token = '';
	$delivered_notification_id = 0;
	$delivered_notification_userid = 0;
	$delivered_notification_confirmation = 0;
	$delivered_notification_opened_confirmation = 0;	
	
	$pnfpb_endpoint = null;
	$pnfpb_options = null;
	$pnfpb_ipaddress = null;
	$pnfpb_subscription_auth_token = null;
	
	if (isset($_POST['pnfpb_endpoint'])) {
		$pnfpb_endpoint = sanitize_text_field($_POST['pnfpb_endpoint']);
	}
	if (isset($_POST['pnfpb_options'])) {
		$pnfpb_options = sanitize_text_field($_POST['pnfpb_options']);
	}
	if (isset($_POST['pnfpb_subscription_token'])) {
		$pnfpb_subscription_auth_token = sanitize_text_field($_POST['pnfpb_subscription_token']);
	}	
	if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
		$pnfpb_ipaddress = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']);
	}
	//whether ip is from the proxy
	elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		$pnfpb_ipaddress = sanitize_text_field($_SERVER['HTTP_X_FORWARDED_FOR']);
	}
	//whether ip is from the remote address
	else {
		$pnfpb_ipaddress = sanitize_text_field($_SERVER['REMOTE_ADDR']);
	}
	$bpuserid = 0;
	if ( is_user_logged_in() ) {
		$bpuserid = get_current_user_id();
	}

	/*********************************************************************************************
	 * Dispatcher: echo JSON response, then run Firebase topic subscription asynchronously.
	 *
	 * Priority order:
	 *   1. fastcgi_finish_request() / litespeed_finish_request() — closes HTTP connection
	 *      immediately so the user gets their response while Firebase calls run in the background.
	 *   2. WP-Cron fallback — stores tasks in a transient and schedules a background event
	 *      for shared-hosting environments where fcgi functions are unavailable.
	 *
	 * @param string $json_response  Already-encoded JSON string to send to the client.
	 * @param array  $sync_tasks     One or more task arrays, each containing:
	 *                                 'type'             => 'multiple' | 'default'
	 *                                 'subscribeoptions' => string  (required for 'multiple')
	 *                                 'deviceid'         => string
	 *                                 'pushtype'         => string  (optional, for 'multiple')
	 *                                 'old_option'       => string  (optional, for 'multiple')
	 *                                 'version'          => string  (optional, for 'multiple')
	 *********************************************************************************************/
	$pnfpb_dispatch_topic_sync = function ( $json_response, array $sync_tasks ) use ( $PNFPB_ajax_subscription_update_obj ) {
		echo $json_response;

		$has_fcgi = function_exists( 'fastcgi_finish_request' ) || function_exists( 'litespeed_finish_request' );

		if ( $has_fcgi ) {
			// Flush output buffer and close the HTTP connection so the client gets its response immediately.
			if ( ob_get_level() > 0 ) {
				@ob_end_flush(); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
			}
			flush();
			if ( function_exists( 'fastcgi_finish_request' ) ) {
				fastcgi_finish_request();
			} else {
				litespeed_finish_request();
			}
			// Client has its response — run Firebase topic calls without blocking the user.
			foreach ( $sync_tasks as $task ) {
				if ( $task['type'] === 'multiple' ) {
					$PNFPB_ajax_subscription_update_obj->PNFPB_httpv1_multiple_subscription_option_update(
						$task['subscribeoptions'],
						$task['deviceid'],
						isset( $task['pushtype'] ) ? $task['pushtype'] : '',
						isset( $task['old_option'] ) ? $task['old_option'] : '',
						isset( $task['version'] ) ? $task['version'] : 'v5'
					);
				} elseif ( $task['type'] === 'default' ) {
					$PNFPB_ajax_subscription_update_obj->PNFPB_httpv1_default_subscription_option_update( $task['deviceid'] );
				}
			}
		} else {
			// Shared-hosting fallback: append tasks to a named cumulative queue.
			// The queue is flushed synchronously at the start of every notification dispatch,
			// eliminating the race window between a subscription change and an FCM send.
			$pnfpb_pending = get_transient( 'pnfpb_pending_topic_sync' );
			if ( ! is_array( $pnfpb_pending ) ) {
				$pnfpb_pending = array();
			}
			foreach ( $sync_tasks as $task ) {
				$pnfpb_pending[] = $task;
			}
			set_transient( 'pnfpb_pending_topic_sync', $pnfpb_pending, DAY_IN_SECONDS );
			// Safety drain: WP-Cron event to process any tasks not yet flushed by a notification.
			if ( ! wp_next_scheduled( 'pnfpb_async_topic_subscription', array( 'pnfpb_pending_topic_sync' ) ) ) {
				wp_schedule_single_event( time() + 300, 'pnfpb_async_topic_subscription', array( 'pnfpb_pending_topic_sync' ) );
				spawn_cron();
			}
		}
	};

	/*********************************************************************************************
	 * Main AJAX dispatcher — routes each pushtype to its handler via switch/case.
	 *********************************************************************************************/
	switch ( $pushtype ) {

		/*----------------------------------------------------------------------------------
		 * Send Firebase credentials to JavaScript
		 *----------------------------------------------------------------------------------*/
		case 'icfirebasecred':
			echo wp_json_encode( array(
				'apiKey'             => get_option( 'pnfpb_ic_fcm_api' ),
				'authDomain'         => get_option( 'pnfpb_ic_fcm_authdomain' ),
				'databaseURL'        => get_option( 'pnfpb_ic_fcm_databaseurl' ),
				'projectId'          => get_option( 'pnfpb_ic_fcm_projectid' ),
				'storageBucket'      => get_option( 'pnfpb_ic_fcm_storagebucket' ),
				'messagingSenderId'  => get_option( 'pnfpb_ic_fcm_messagingsenderid' ),
				'appId'              => get_option( 'pnfpb_ic_fcm_appid' ),
				'publicKey'          => get_option( 'pnfpb_ic_fcm_publickey' ),
				'pnfpb_authsw_token' => '0',
			) );
			break;

		/*----------------------------------------------------------------------------------
		 * Send Web Push credentials to JavaScript
		 *----------------------------------------------------------------------------------*/
		case 'icwebpushcred':
			echo wp_json_encode( array( 'vapidKey' => get_option( 'pnfpb_web_push_vapid_public_key' ) ) );
			break;

		/*----------------------------------------------------------------------------------
		 * Return notification read-receipt token for webview
		 *----------------------------------------------------------------------------------*/
		case 'pnfpb_read_receipt_webview':
			if ( $bpnotification_id > 0 ) {
				$data                    = array( 'notification_status' => 'failed', 'notification_token' => '' );
				$read_receipt_table_name = $wpdb->prefix . 'pnfpb_ic_total_statistics_notifications';
				$results                 = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE notificationid = %d', array( $read_receipt_table_name, $bpnotification_id ) ) );
				foreach ( $results as $result ) {
					$data = array( 'notification_status' => 'success', 'notification_token' => $result->notification_auth_token );
				}
				echo wp_json_encode( $data );
			} else {
				echo wp_json_encode( array( 'notification_status' => 'failed', 'notification_token' => '' ) );
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Register a WebToApp subscribed user
		 *----------------------------------------------------------------------------------*/
		case 'webtoapp_subscribed_users':
			$results = $wpdb->get_results( $wpdb->prepare(
				'SELECT * FROM %i WHERE userid = %d AND device_id LIKE %s',
				array( $table, $bpwebtoappid, '%' . $wpdb->esc_like( $bpwebtoapp_deviceid ) . '%' )
			) );
			if ( count( $results ) <= 0 ) {
				$data         = array( 'userid' => $bpwebtoappid, 'device_id' => $bpwebtoapp_deviceid, 'subscription_option' => '100000000000', 'ip_address' => $pnfpb_ipaddress );
				$insertstatus = $wpdb->insert( $table, $data );
				if ( ! $insertstatus ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'error', 'message' => $insertstatus ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'message' => $bpwebtoapp_deviceid ) );
				}
			} else {
				foreach ( $results as $result ) {
					if ( $result->subscription_option === null || $result->subscription_option === '' ) {
						$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', array( $table, $bpsubscribeoptions, $bpwebtoappid ) ) );
					}
				}
				echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'message' => $result->device_id ) );
			}
			break;
		/*----------------------------------------------------------------------------------
		 * Register a Progressier subscribed user
		 *----------------------------------------------------------------------------------*/
		case 'progressier_subscribed_users':
			if ( isset( $_POST['progressier_external_id'] ) ) {
				$progressier_externalid = sanitize_text_field( wp_unslash($_POST['progressier_external_id'] ));
				$progressier_externalid = esc_html( $progressier_externalid );
				if ( $progressier_externalid === null || ( $progressier_externalid !== null && ! is_numeric( $progressier_externalid ) ) || $progressier_externalid === '' ) {
					$progressier_externalid = 0;
				}
				$results = $wpdb->get_results( $wpdb->prepare(
					'SELECT * FROM %i WHERE userid = %d AND device_id LIKE %s',
					array( $table, $progressier_externalid, '%' . $wpdb->esc_like( 'progressier' ) . '%' )
				) );
				if ( count( $results ) <= 0 ) {
					$length               = 10;
					$progressier_deviceid = substr( str_shuffle( '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' ), 1, $length ) . 'progressier@N';
					$data                 = array( 'userid' => $progressier_externalid, 'device_id' => $progressier_deviceid, 'subscription_option' => '100000000000', 'ip_address' => $pnfpb_ipaddress );
					$insertstatus         = $wpdb->insert( $table, $data );
					if ( ! $insertstatus ) {
						echo wp_json_encode( array( 'subscriptionstatus' => 'error', 'message' => $insertstatus ) );
					} else {
						echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'message' => $progressier_deviceid ) );
					}
				} else {
					foreach ( $results as $result ) {
						if ( $result->subscription_option === null || $result->subscription_option === '' ) {
							$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', array( $table, $bpsubscribeoptions, $progressier_externalid ) ) );
						}
					}
					echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'message' => $result->device_id ) );
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Register a OneSignal subscribed user
		 *----------------------------------------------------------------------------------*/
		case 'onesignal_subscribed_users':
			if ( isset( $_POST['onesignal_externalid'] ) ) {
				$onesignal_externalid = sanitize_text_field(wp_unslash( $_POST['onesignal_externalid'] ));
				$onesignal_externalid = esc_html( $onesignal_externalid );
				if ( $onesignal_externalid === '1pnfpbadm' ) {
					$onesignal_externalid = 1;
				}
				if ( $onesignal_externalid === null || ( $onesignal_externalid !== null && ! is_numeric( $onesignal_externalid ) ) || $onesignal_externalid === '' ) {
					$onesignal_externalid = 0;
				}
				$results = $wpdb->get_results( $wpdb->prepare(
					'SELECT * FROM %i WHERE userid = %d AND device_id LIKE %s',
					array( $table, $onesignal_externalid, '%' . $wpdb->esc_like( 'onesignal' ) . '%' )
				) );
				if ( count( $results ) <= 0 ) {
					$data         = array( 'userid' => $onesignal_externalid, 'device_id' => 'onesignal@N', 'subscription_option' => '100000000000', 'ip_address' => $pnfpb_ipaddress );
					$insertstatus = $wpdb->insert( $table, $data );
					if ( ! $insertstatus ) {
						echo 'error in inserting onesignal subscription details in PNFPB for id: ' . esc_html( $onesignal_externalid );
					} else {
						echo '';
					}
				} else {
					foreach ( $results as $result ) {
						if ( $result->subscription_option === null || $result->subscription_option === '' ) {
							$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', array( $table, $bpsubscribeoptions, $onesignal_externalid ) ) );
						}
					}
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Get OneSignal frontend subscription options
		 *----------------------------------------------------------------------------------*/
		case 'onesignal_get_frontend_subscriptions':
			$data = '';
			if ( $bponesignalid !== 0 ) {
				$results = $wpdb->get_results( $wpdb->prepare(
					'SELECT * FROM %i WHERE userid = %d AND device_id LIKE %s',
					array( $table, $bponesignalid, '%' . $wpdb->esc_like( 'onesignal' ) . '%' )
				) );
				foreach ( $results as $result ) {
					$data = array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $result->subscription_option );
				}
				echo wp_json_encode( $data );
			} else {
				echo wp_json_encode( array( 'subscriptionstatus' => 'notsubscribed', 'subscriptionoptions' => '' ) );
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Update OneSignal frontend subscription options
		 *----------------------------------------------------------------------------------*/
		case 'onesignal_frontend_subscriptions':
			if ( $bpuserid !== 0 ) {
				$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', array( $table, $bpsubscribeoptions, $bpuserid ) ) );
			}
			echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $bpsubscribeoptions ) );
			break;

		/*----------------------------------------------------------------------------------
		 * Get Progressier frontend subscription options
		 *----------------------------------------------------------------------------------*/
		case 'progressier_get_frontend_subscriptions':
			$data = '';
			if ( $bpprogressierid !== 0 ) {
				$results = $wpdb->get_results( $wpdb->prepare(
					'SELECT * FROM %i WHERE userid = %d AND device_id LIKE %s',
					array( $table, $bpprogressierid, '%' . $wpdb->esc_like( 'progressier' ) . '%' )
				) );
				foreach ( $results as $result ) {
					$data = array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $result->subscription_option );
				}
				echo wp_json_encode( $data );
			} else {
				echo wp_json_encode( array( 'subscriptionstatus' => 'notsubscribed', 'subscriptionoptions' => '' ) );
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Update Progressier frontend subscription options
		 *----------------------------------------------------------------------------------*/
		case 'progressier_frontend_subscriptions':
			if ( $bpuserid !== 0 ) {
				$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', array( $table, $bpsubscribeoptions, $bpuserid ) ) );
			}
			echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $bpsubscribeoptions ) );
			break;

		/*----------------------------------------------------------------------------------
		 * Add a new Firebase-subscribed device (first-time subscription)
		 *----------------------------------------------------------------------------------*/
		case 'normal':
			$deviceid_exists = array();
			if ( $bpdeviceid !== '' ) {
				$deviceid_exists = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE device_id = %s', $table, $bpdeviceid ) );
			}
			if ( $pnfpb_subscription_auth_token !== '' ) {
				$deviceid_exists = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE subscription_auth_token = %s', $table, $pnfpb_subscription_auth_token ) );
			}
			foreach ( $deviceid_exists as $result ) {
				if ( ( $result->userid == 0 || ( $result->userid != $bpuserid && $bpuserid !== 0 ) ) && $bpdeviceid !== '' ) {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET userid = %d WHERE device_id = %s', $table, $bpuserid, $bpdeviceid ) );
				}
				if ( ( $result->userid == 0 || ( $result->userid != $bpuserid && $bpuserid !== 0 ) ) && $pnfpb_subscription_auth_token !== '' ) {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET userid = %d WHERE device_id = %s OR subscription_auth_token = %s', $table, $bpuserid, $pnfpb_subscription_auth_token ) );
				}
				if ( is_null( $result->web_auth )
					|| is_null( $result->web_256 )
					|| is_null( $result->subscription_auth_token )
					|| ( $result->web_auth === '' )
					|| ( $result->web_256 === '' )
					|| ( $result->subscription_auth_token === '' )
				) {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET web_auth = %s, web_256 = %s, subscription_auth_token = %s, ip_address = %s WHERE device_id = %s', $table, $pnfpb_endpoint, $pnfpb_options, $pnfpb_subscription_auth_token, $pnfpb_ipaddress, $bpdeviceid ) );
				}
			}
			if ( count( $deviceid_exists ) > 0 ) {
				echo 'duplicate';
			} else {
				// First-time registration: insert record then dispatch Firebase topic sync.
				$data         = array( 'userid' => $bpuserid, 'device_id' => $bpdeviceid, 'subscription_option' => $bpsubscribeoptions, 'web_auth' => $pnfpb_endpoint, 'web_256' => $pnfpb_options, 'subscription_auth_token' => $pnfpb_subscription_auth_token, 'ip_address' => $pnfpb_ipaddress, 'firebase_version' => 'v5' );
				$insertstatus = $wpdb->insert( $table, $data );

				$json_response             = ( $insertstatus > 0 )
					? wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $bpsubscribeoptions ) )
					: wp_json_encode( array( 'subscriptionstatus' => 'fail', 'subscriptionoptions' => $bpsubscribeoptions ) );
				$subscription_option_array = $bpsubscribeoptions !== '' ? str_split( $bpsubscribeoptions ) : array();
				$sync_tasks                = array();

				if ( get_option( 'pnfpb_httpv1_push' ) === '1' && $bpsubscribeoptions !== ''
					&& ( count( $subscription_option_array ) > 0 && $subscription_option_array[0] !== '1' )
				) {
					$sync_tasks[] = array( 'type' => 'multiple', 'subscribeoptions' => $bpsubscribeoptions, 'deviceid' => $bpdeviceid, 'pushtype' => '', 'old_option' => '', 'version' => 'v5' );
				}
				if ( get_option( 'pnfpb_httpv1_push' ) === '1'
					&& ( count( $subscription_option_array ) <= 0
						|| ( count( $subscription_option_array ) > 0 && $subscription_option_array[0] === '1' ) )
				) {
					$sync_tasks[] = array( 'type' => 'default', 'deviceid' => $bpdeviceid );
				}

				if ( ! empty( $sync_tasks ) ) {
					$pnfpb_dispatch_topic_sync( $json_response, $sync_tasks );
				} else {
					echo $json_response;
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Update subscription options from the frontend settings / custom prompt
		 *----------------------------------------------------------------------------------*/
		case 'subscribe-button':
			$old_subscription_option        = '';
			$old_subscription_option_values = $wpdb->get_col( $wpdb->prepare( 'SELECT subscription_option FROM %i WHERE device_id = %s', $table, $bpdeviceid ) );
			foreach ( $old_subscription_option_values as $old_subscription_option_value ) {
				$old_subscription_option = $old_subscription_option_value;
			}

			$subscription_option_array     = array();
			$old_subscription_option_array = array();

			if ( $bpsubscribeoptions !== '' ) {
				$subscription_option_array = str_split( $bpsubscribeoptions );
				if ( get_option( 'pnfpb_ic_fcm_buddypress_comments_radio_enable' ) === '2'
					&& count( $subscription_option_array ) > 3
					&& $subscription_option_array[2] === '1'
				) {
					$subscription_option_array[2] = '0';
					$subscription_option_array[3] = '1';
					$bpsubscribeoptions           = implode( '', $subscription_option_array );
				}
			}

			if ( $old_subscription_option !== '' ) {
				$old_subscription_option_array = str_split( $old_subscription_option );
				if ( get_option( 'pnfpb_ic_fcm_buddypress_comments_radio_enable' ) === '2'
					&& count( $old_subscription_option_array ) > 3
					&& $old_subscription_option_array[2] === '1'
				) {
					$old_subscription_option_array[2] = '0';
					$old_subscription_option_array[3] = '1';
					$old_subscription_option          = implode( '', $old_subscription_option_array );
				}
			}

			// Pre-build Firebase sync tasks before any output.
			$sync_tasks = array();
			if ( get_option( 'pnfpb_httpv1_push' ) === '1' && $bpsubscribeoptions !== '' ) {
				$sync_tasks[] = array( 'type' => 'multiple', 'subscribeoptions' => $bpsubscribeoptions, 'deviceid' => $bpdeviceid, 'pushtype' => '', 'old_option' => $old_subscription_option, 'version' => 'v5' );
			}
			if ( get_option( 'pnfpb_httpv1_push' ) === '1'
				&& ( count( $subscription_option_array ) <= 0
					|| ( count( $subscription_option_array ) > 0 && $subscription_option_array[0] === '1' ) )
			) {
				$sync_tasks[] = array( 'type' => 'default', 'deviceid' => $bpdeviceid );
			}

			if ( $bpdeviceid !== '' ) {
				if ( $bpuserid !== 0 ) {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', $table, $bpsubscribeoptions, $bpuserid ) );
				} else {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE device_id = %s', $table, $bpsubscribeoptions, $bpdeviceid ) );
				}
				$deviceid_select_status = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE device_id = %s', $table, $bpdeviceid ) );
				$json_response          = wp_json_encode( array( 'subscriptionstatus' => 'subscribed updated', 'subscriptionoptions' => $bpsubscribeoptions ) );
				if ( ! empty( $sync_tasks ) ) {
					$pnfpb_dispatch_topic_sync( $json_response, $sync_tasks );
				} else {
					echo $json_response;
				}
			} else {
				if ( $bpuserid !== 0 ) {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE userid = %d', $table, $bpsubscribeoptions, $bpuserid ) );
				} else {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE device_id = %s', $table, $bpsubscribeoptions, $bpdeviceid ) );
				}
				$json_response = wp_json_encode( array( 'subscriptionstatus' => 'subscribed webview', 'subscriptionoptions' => $bpsubscribeoptions ) );
				if ( ! empty( $sync_tasks ) ) {
					$pnfpb_dispatch_topic_sync( $json_response, $sync_tasks );
				} else {
					echo $json_response;
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Check whether a device is already subscribed (called on page load)
		 *----------------------------------------------------------------------------------*/
		case 'checkdeviceid':
			$deviceid_select_status = array();
			if ( $bpdeviceid !== '' && $bpuserid > 0 ) {
				/* Check if user id is present; if user just logged in, link userid to their token. */
				$deviceid_select_status = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE userid = %d AND device_id = %s', $table, $bpuserid, $bpdeviceid ) );
				if ( $deviceid_select_status != null && $deviceid_select_status->subscription_option ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $deviceid_select_status->subscription_option ) );
				} else {
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET userid = %d, subscription_auth_token = %s WHERE device_id = %s', $table, $bpuserid, $pnfpb_subscription_auth_token, $bpdeviceid ) );
					if ( $deviceid_update_status <= 0 ) {
						$data         = array( 'userid' => $bpuserid, 'device_id' => $bpdeviceid, 'subscription_option' => '100000000000', 'web_auth' => $pnfpb_endpoint, 'web_256' => $pnfpb_options, 'subscription_auth_token' => $pnfpb_subscription_auth_token, 'ip_address' => $pnfpb_ipaddress, 'firebase_version' => 'v5' );
						$insertstatus = $wpdb->insert( $table, $data );
						if ( $insertstatus > 0 ) {
							echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => '100000000000' ) );
						} else {
							echo wp_json_encode( array( 'subscriptionstatus' => 'not-subscribed', 'subscriptionoptions' => '100000000000' ) );
						}
					} else {
						if ( $deviceid_select_status != null && $deviceid_select_status->subscription_option ) {
							echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $deviceid_select_status->subscription_option ) );
						} else {
							echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => '100000000000000000000' ) );
						}
					}
				}
			} else {
				echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => '100000000000000000000' ) );
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Check subscription status for a specific BuddyPress group
		 *----------------------------------------------------------------------------------*/
		case 'checkdeviceidforgroup':
			if ( $bpdeviceid !== '' || $pnfpb_endpoint !== '' ) {
				$bpgroupid              = sanitize_text_field( wp_unslash( $_POST['bpgroup_id'] ) );
				$bpgroupdeviceid        = $bpdeviceid . '!!' . $bpgroupid . '!!';
				$deviceid_select_status = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE web_auth = %s OR device_id = %s AND userid = %d', $table, $pnfb_endpoint, $bpgroupdeviceid, $bpuserid ) );
				$subscriptionoptions    = '000000000000';
				if ( count( $deviceid_select_status ) > 0 ) {
					$version_value = 'L';
					foreach ( $deviceid_select_status as $result ) {
						$version_value       = $result->firebase_version;
						$subscriptionoptions = $result->subscription_option;
						if ( $subscriptionoptions === '10000' || $subscriptionoptions === '' || is_null( $subscriptionoptions ) ) {
							$subscriptionoptions    = '100000000000';
							$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'UPDATE %i SET subscription_option = %s WHERE web_auth = %s OR device_id = %s AND userid = %d', $table, $subscriptionoptions, $pnfb_endpoint, $bpgroupdeviceid, $bpuserid ) );
						}
						$webpush_option   = get_option( 'pnfpb_webpush_push' );
						$webpush_firebase = get_option( 'pnfpb_webpush_push_firebase' );
						if ( $bpdeviceid !== $result->device_id && $webpush_option !== '1' && $webpush_option !== '2' && $webpush_firebase !== '1' && get_option( 'pnfpb_httpv1_push' ) === '1' ) {
							$group_name  = groups_get_slug( $bpgroupid );
							$client      = new Google_Client();
							$client->useApplicationDefaultCredentials();
							$configArray = json_decode( get_option( 'pnfpb_sa_json_data' ), true );
							$client->setAuthConfig( $configArray );
							$client->addScope( 'https://www.googleapis.com/auth/firebase.messaging' );
							$client->refreshTokenWithAssertion();
							$pnfpb_fbauth_token_array = $client->getAccessToken();
							$pnfpb_fbauth_token       = $pnfpb_fbauth_token_array['access_token'];
							update_option( 'pnfpb_firebase_oauth_token', $pnfpb_fbauth_token );
							$url        = 'https://iid.googleapis.com/iid/v1:batchAdd';
							$headers    = array( 'Authorization' => 'Bearer ' . $pnfpb_fbauth_token, 'Content-Type' => 'application/json', 'access_token_auth' => 'true' );
							$grouptopic = '/topics/' . $group_name;
							$fields     = array( 'to' => $grouptopic, 'registration_tokens' => array( $bpdeviceid ) );
							$body       = wp_json_encode( $fields );
							$args       = array( 'httpversion' => '1.0', 'blocking' => false, 'body' => $body, 'headers' => $headers );
							$apiresults = wp_remote_post( $url, $args );
							$deviceid_version_update_status = $wpdb->query( $wpdb->prepare( "UPDATE %i SET firebase_version = %s, WHERE device_id = %s AND userid = %d", $table, 'v5', $bpdeviceid . '!!' . $bpgroupid . '!!' . $group_device_identifier_array[1], $bpuserid ) );
						}
					}
					echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $subscriptionoptions ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'not-subscribed', 'subscriptionoptions' => $subscriptionoptions ) );
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Subscribe to BuddyPress group push notifications
		 *----------------------------------------------------------------------------------*/
		case 'subscribe-group-button':
			if ( $bpdeviceid !== '' || $pnfpb_endpoint !== '' ) {
				$bpgroupid   = sanitize_text_field( wp_unslash( $_POST['bpgroup_id'] ) );
				$cookievalue = '';
				if ( isset( $_COOKIE[ 'pnfpb_group_push_notification_' . $bpgroupid ] ) ) {
					$cookievalue = $_COOKIE[ 'pnfpb_group_push_notification_' . $bpgroupid ];
				}
				$bpnewdeviceid          = $bpdeviceid . '!!' . $bpgroupid . '!!' . $cookievalue;
				$deviceid_select_status = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE device_id = %s OR web_auth = %s', $table, $bpdeviceid, $pnfpb_endpoint ) );
				$subscriptionoptions    = '000000000000';
				foreach ( $deviceid_select_status as $result ) {
					$subscriptionoptions = $result->subscription_option;
				}
				$uniqueid      = uniqid();
				setcookie( 'pnfpb_group_push_notification_' . $bpgroupid, $uniqueid, time() + ( 86400 * 30 ), '/' );
				$bpnewdeviceid = $bpdeviceid . '!!' . $bpgroupid . '!!' . $uniqueid;
				$data          = array( 'userid' => $bpuserid, 'device_id' => $bpnewdeviceid, 'subscription_option' => $subscriptionoptions, 'web_auth' => $pnfpb_endpoint, 'web_256' => $pnfpb_options, 'subscription_auth_token' => $pnfpb_subscription_auth_token, 'ip_address' => $pnfpb_ipaddress, 'firebase_version' => 'v5' );
				$insertstatus  = $wpdb->insert( $table, $data );
				if ( $insertstatus > 0 ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'subscribed', 'subscriptionoptions' => $subscriptionoptions ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'deleted' ) );
				}
				if ( get_option( 'pnfpb_httpv1_push' ) === '1' ) {
					$group_name             = 'pnfpbgroupid' . $bpgroupid;
					$pnfpb_oauth_timestamp  = get_option( 'pnfpb_firebase_oauth_timestamp' );
					$pnfpb_fbauth_token     = get_option( 'pnfpb_firebase_oauth_token' );
					$one_hour_ago_timestamp = strtotime( '-1 hour' );
					if ( $pnfpb_fbauth_token === false || $pnfpb_fbauth_token === ''
						|| $pnfpb_oauth_timestamp === false || $pnfpb_oauth_timestamp === ''
						|| ! is_numeric( $pnfpb_oauth_timestamp )
						|| ( is_numeric( $pnfpb_oauth_timestamp ) && $pnfpb_oauth_timestamp < $one_hour_ago_timestamp )
					) {
						$client = new Google_Client();
						$client->useApplicationDefaultCredentials();
						$configArray = json_decode( get_option( 'pnfpb_sa_json_data' ), true );
						$client->setAuthConfig( $configArray );
						$client->addScope( 'https://www.googleapis.com/auth/firebase.messaging' );
						$client->refreshTokenWithAssertion();
						$pnfpb_fbauth_token_array = $client->getAccessToken();
						$pnfpb_fbauth_token       = $pnfpb_fbauth_token_array['access_token'];
						update_option( 'pnfpb_firebase_oauth_token', $pnfpb_fbauth_token );
						update_option( 'pnfpb_firebase_oauth_timestamp', strtotime( 'now' ) );
					}
					$url        = 'https://iid.googleapis.com/iid/v1:batchAdd';
					$headers    = array( 'Authorization' => 'Bearer ' . $pnfpb_fbauth_token, 'Content-Type' => 'application/json', 'access_token_auth' => 'true' );
					$grouptopic = '/topics/' . $group_name;
					$fields     = array( 'to' => $grouptopic, 'registration_tokens' => array( $bpdeviceid ) );
					$body       = wp_json_encode( $fields );
					$args       = array( 'httpversion' => '1.0', 'blocking' => false, 'body' => $body, 'headers' => $headers );
					$apiresults = wp_remote_post( $url, $args );
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Unsubscribe from BuddyPress group push notifications
		 *----------------------------------------------------------------------------------*/
		case 'unsubscribe-group-button':
			if ( $bpdeviceid !== '' || $pnfpb_endpoint !== '' ) {
				$bpgroupid   = sanitize_text_field( wp_unslash( $_POST['bpgroup_id'] ) );
				$cookievalue = '';
				if ( isset( $_COOKIE[ 'pnfpb_group_push_notification_' . $bpgroupid ] ) ) {
					$cookievalue = $_COOKIE[ 'pnfpb_group_push_notification_' . $bpgroupid ];
				}
				$deviceid_update_status = 0;
				if ( isset( $bpdeviceid ) && $bpdeviceid !== '' ) {
					$bpolddeviceid          = $bpdeviceid . '!!' . $bpgroupid . '!!' . $cookievalue;
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'DELETE from %i WHERE userid = %d AND device_id = %s', $table, $bpuserid, $bpolddeviceid ) );
				} elseif ( isset( $pnfpb_endpoint ) && $pnfpb_endpoint !== '' ) {
					$bpolddeviceid          = '!!' . $bpgroupid . '!!' . $cookievalue;
					$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'DELETE from %i WHERE userid = %d AND web_auth = %s AND device_id = %s', $table, $bpuserid, $pnfpb_endpoint, $bpolddeviceid ) );
				}
				if ( get_option( 'pnfpb_httpv1_push' ) === '1' ) {
					$group_name             = 'pnfpbgroupid' . $bpgroupid;
					$pnfpb_oauth_timestamp  = get_option( 'pnfpb_firebase_oauth_timestamp' );
					$pnfpb_fbauth_token     = get_option( 'pnfpb_firebase_oauth_token' );
					$one_hour_ago_timestamp = strtotime( '-1 hour' );
					if ( $pnfpb_fbauth_token === false || $pnfpb_fbauth_token === ''
						|| $pnfpb_oauth_timestamp === false || $pnfpb_oauth_timestamp === ''
						|| ! is_numeric( $pnfpb_oauth_timestamp )
						|| ( is_numeric( $pnfpb_oauth_timestamp ) && $pnfpb_oauth_timestamp < $one_hour_ago_timestamp )
					) {
						$client = new Google_Client();
						$client->useApplicationDefaultCredentials();
						$configArray = json_decode( get_option( 'pnfpb_sa_json_data' ), true );
						$client->setAuthConfig( $configArray );
						$client->addScope( 'https://www.googleapis.com/auth/firebase.messaging' );
						$client->refreshTokenWithAssertion();
						$pnfpb_fbauth_token_array = $client->getAccessToken();
						$pnfpb_fbauth_token       = $pnfpb_fbauth_token_array['access_token'];
						update_option( 'pnfpb_firebase_oauth_token', $pnfpb_fbauth_token );
						update_option( 'pnfpb_firebase_oauth_timestamp', strtotime( 'now' ) );
					}
					$url        = 'https://iid.googleapis.com/iid/v1:batchRemove';
					$headers    = array( 'Authorization' => 'Bearer ' . $pnfpb_fbauth_token, 'Content-Type' => 'application/json', 'access_token_auth' => 'true' );
					$grouptopic = '/topics/' . $group_name;
					$fields     = array( 'to' => $grouptopic, 'registration_tokens' => array( $bpdeviceid ) );
					$body       = wp_json_encode( $fields );
					$args       = array( 'httpversion' => '1.0', 'blocking' => false, 'body' => $body, 'headers' => $headers );
					$apiresults = wp_remote_post( $url, $args );
				}
				if ( $deviceid_update_status > 0 ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'deleted' ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'failed in unsubscribe button' ) );
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Delete a push notification token (user unsubscribed entirely)
		 *----------------------------------------------------------------------------------*/
		case 'deletepushtoken':
			$deviceid_update_status = 0;
			if ( isset( $bpdeviceid ) && $bpdeviceid !== '' ) {
				$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'DELETE from %i WHERE device_id = %s', $table, $bpdeviceid ) );
				if ( $deviceid_update_status > 0 ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'deleted', 'deviceidupdatestauts' => $deviceid_update_status, 'deviceid' => $bpdeviceid ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'failed in deleting push token', 'deviceidupdatestauts' => $deviceid_update_status, 'deviceid' => $bpdeviceid ) );
				}
			} elseif ( isset( $pnfpb_endpoint ) && $pnfpb_endpoint !== '' ) {
				$deviceid_update_status = $wpdb->query( $wpdb->prepare( 'DELETE from %i WHERE web_auth = %s', $table, $pnfpb_endpoint ) );
				if ( $deviceid_update_status > 0 ) {
					echo wp_json_encode( array( 'subscriptionstatus' => 'deleted', 'deviceidupdatestauts' => $deviceid_update_status, 'deviceid' => $bpdeviceid ) );
				} else {
					echo wp_json_encode( array( 'subscriptionstatus' => 'failed in deleting push token', 'deviceidupdatestauts' => $deviceid_update_status, 'deviceid' => $bpdeviceid ) );
				}
			}
			break;

		/*----------------------------------------------------------------------------------
		 * Unknown or unhandled pushtype
		 *----------------------------------------------------------------------------------*/
		default:
			echo wp_json_encode( array( 'subscriptionstatus' => 'failed' ) );
			break;
	}
}
wp_die();
?>