<?php
namespace AcademyProNotifications\Classes;

use AcademyPro\Minishlink\WebPush\Subscription;
use AcademyPro\Minishlink\WebPush\VAPID;
use AcademyPro\Minishlink\WebPush\WebPush;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class PushNotifications {
	public $vapidkey = array();
	protected $settings_names;
	public static function init() {
		$self = new self();
		$self->generate_vapid_keys();
		$self->set_settings_name();
		add_action( 'wp_enqueue_scripts', array( $self, 'load_scripts' ) );
		add_action( 'admin_enqueue_scripts', array( $self, 'load_scripts' ) );
		// ajax
		add_action( 'wp_ajax_academy_pro_notification/save_notifications_data', array( $self, 'save_subscription_data' ) );
	}

	public function load_scripts() {
		if ( ! is_user_logged_in() ) {
			return;
		}
		wp_enqueue_script( 'academy-pro-notification-subscriber', ACADEMY_PRO_NOTIFICATIONS_ASSETS . '/notifications.js', array( 'jquery' ), ACADEMY_PRO_VERSION, true );
		wp_enqueue_script( 'academy-pro-service-subscriber', ACADEMY_PRO_NOTIFICATIONS_ASSETS . '/serviceworker.js', array(), ACADEMY_PRO_VERSION, true );

		wp_localize_script( 'academy-pro-notification-subscriber', 'academy_pro_notifications',
			array(
				'swurl'         => ACADEMY_PRO_NOTIFICATIONS_ASSETS . '/serviceworker.js',
				'ajaxurl'       => admin_url( 'admin-ajax.php' ),
				'action'        => 'academy_pro_notification/save_notifications_data',
				'security'      => wp_create_nonce( 'academy_nonce' ),
				'publickey'     => $this->vapidkey['publicKey'] ?? '',
				'privateKey'    => $this->vapidkey['privateKey'] ?? '',
			)
		);
	}

	public function generate_vapid_keys() {
		if ( ! get_option( 'ACADEMY_NOTIFICATION_VAPID_KEYS' ) ) {
			try {
				$this->vapidkey = VAPID::createVapidKeys();
			} catch ( \Exception $e ) {
				return null;
			}
			update_option( 'ACADEMY_NOTIFICATION_VAPID_KEYS', $this->vapidkey );
		} else {
			$this->vapidkey = get_option( 'ACADEMY_NOTIFICATION_VAPID_KEYS' );
		}
	}

	public function save_subscription_data() {
		check_ajax_referer( 'academy_nonce', 'security' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$endpoint = sanitize_text_field( $_POST['endpoint'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$expiration_time = sanitize_text_field( $_POST['expirationTime'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$p256dh = sanitize_text_field( $_POST['p256dh'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$auth = sanitize_text_field( $_POST['auth'] );

		$meta_value = array(
			'endpoint' => $endpoint,
			'expirationTime' => $expiration_time,
			'p256dh' => $p256dh,
			'auth' => $auth,
		);
		$user_id = get_current_user_id();
		$meta_key = 'academy_notifications_subscription';

		$is_alredy = get_user_meta( $user_id, $meta_key );

		if ( $is_alredy ) {
			if ( update_user_meta( $user_id, $meta_key, $meta_value ) ) {
				wp_send_json_success();
			}
		} else {
			if ( add_user_meta( $user_id, $meta_key, $meta_value ) ) {
				wp_send_json_success();
			}
		}
	}

	public function is_subscriber( $user_id ) : bool {
		$meta = get_user_meta( $user_id, 'academy_notifications_subscription' );

		if ( ! $meta ) {
			return false;
		}

		return true;
	}

	public function send_notification_to_users( $title, $body, $url, $user_ids = array() ) : bool {

		$user_ids = is_array( $user_ids ) ? $user_ids : array( $user_ids );
		$user_ids = array_unique( $user_ids );

		$vapid = get_option( 'ACADEMY_NOTIFICATION_VAPID_KEYS' );

		if ( ! $vapid ) {
			return false;
		}

		$auth = [
			'VAPID' => [
				'subject' => 'mailto:' . home_url(),
				'publicKey' => $vapid['publicKey'],
				'privateKey' => $vapid['privateKey'],
			],
		];

		try {
			$webpush = new WebPush( $auth );
		} catch ( \Exception $e ) {
			return false;
		}

		$message = wp_json_encode( array(
			'title' => $title,
			'body'  => $body,
			'url'   => $url,
			'badge' => get_site_icon_url( 96 ),
			'icon'  => get_site_icon_url( 256 ),
			'dir'   => is_rtl() ? 'rtl' : 'ltr',
			'timestamp' => time() * 1000,
		) );

		foreach ( $user_ids as $user_id ) {
			$user_meta = get_user_meta( $user_id, 'academy_notifications_subscription' );
			if ( $user_meta ) {
				$user_meta = current( maybe_unserialize( $user_meta ) );

				$subscription = Subscription::create(
					array(
						'endpoint' => $user_meta['endpoint'],
						'keys'     => array(
							'p256dh' => $user_meta['p256dh'],
							'auth'   => $user_meta['auth'],
						),
					)
				);

				$webpush->queueNotification( $subscription, $message );
			}
		}

		foreach ( $webpush->flush() as $report ) {
			return $report->isSuccess();
		}

		return false;
	}

	private function set_settings_name() {
		$this->settings_names = array(
			'instructor_registration' => 'is_enabled_new_instructor_registration_push',
			'instructor_approval'     => 'is_enabled_new_instructor_approve_push',
			'instructor_remove'       => 'is_enabled_new_instructor_remove_push',
			'course_enrollment'       => 'is_enabled_new_course_enrollment_push',
			'cancel_enrollment'       => 'is_enabled_cancel_enrollment_push',
			'announcement_publish'    => 'is_enabled_announcement_publish_push',
			'student_registration'    => 'is_enabled_new_student_registration_push',
			'course_publish'          => 'is_enabled_new_course_publish_push',
			'course_complete'         => 'is_enabled_course_complete_push',
			'course_review'           => 'is_enabled_course_review_push',
			'quiz_evaluate'           => 'is_enabled_quiz_evaluate_push',
			'quiz_submit'             => 'is_enabled_quiz_submit_push',
			'assignment_evaluate'     => 'is_enabled_assignment_evaluate_push',
			'assignment_submit'       => 'is_enabled_assignment_submit_push',
			'withdraw_request_approved' => 'is_enabled_withdraw_request_approved_push',
			'withdraw_request_rejected' => 'is_enabled_withdraw_request_rejected_push',
			'question_answer_submit'  => 'is_enabled_question_answer_submit_push',
			'question_answer_reply'   => 'is_enabled_question_answer_reply_push',
		);
	}

	public function is_enable_setting( $setting_name ) : bool {
		$this->set_settings_name();
		return \AcademyProNotifications\Helper::get_setting( $this->settings_names[ $setting_name ] );
	}
}
