<?php
/**
 * LearnDash Course Scheduler Notification Class
 */

if(!class_exists('LD_CS_NOTIFY')) {

	class LD_CS_NOTIFY {

		private $email_settings;

		public function __construct() {
			$this->init();
		}

        public function dd( array $array ) {
            echo '<pre>';
            print_r( $array );
            echo '</pre>';
        }

        public function log( $log ) {
            if ( is_array( $log ) || is_object( $log ) ) {
                error_log( print_r( $log, true ) );
            } else {
                error_log( $log );
            }
        }

		/**
		 * Kick-in the class
		 */
		protected function init() {
			$this->email_settings = get_course_availability_email_settings();

			$course_ids = get_posts([                                     
				'fields' => 'ids',
				'post_type' => learndash_get_post_type_slug('course'),
				'numberposts' => -1,
				'post_status' => 'publish'
			]   );

			$interval = $this->email_settings['interval'];
			$interval_unit = $this->email_settings['interval_unit'];

			$all_courses_schedules = $this->get_course_schedules($course_ids, $interval, $interval_unit);
			foreach ($all_courses_schedules as $course_id => $course_schedules) {

				$course_users_query = learndash_get_users_for_course( $course_id, array(), true );
				if ( $course_users_query instanceof WP_User_Query ) {
					$course_user_ids = $course_users_query->get_results();
				}

				foreach ($course_schedules as $course_schedule) {

                    $course_user_ids = [];
                    if( isset($course_schedule->ld_group) && ! empty($course_schedule->ld_group) && 0 != $course_schedule->ld_group ) {
                        /**
                         * If Scheduled event course is enrolled by the group
                         */
						$course_user_ids = learndash_get_groups_user_ids( $course_schedule->ld_group );
                    }else{
                        /**
                         * If Scheduled event course is not enrolled by the group
                         */
                        $course_users_query = learndash_get_users_for_course( $course_id, array(), true );
                        if ( $course_users_query instanceof WP_User_Query ) {
                            $course_user_ids = $course_users_query->get_results();
                        }
                    }

					if(!empty($course_user_ids)) {
						foreach ($course_user_ids as $course_user_id) {
							$user_has_access = $this->user_has_access($course_user_id, $course_schedule->excluded_role, $course_schedule->excluded_users, $course_schedule->user_filter_type);
							
							if($user_has_access) {
								$this->process_notification($course_user_id, $course_id, $course_schedule);
							}
						}
					}
				}
				
			}
		}

		private function process_notification($user_id, $course_id, $schedule, $type='email') {

			//Skip if content is unavailable
			if( $this->is_content_hidden_for_all($course_id) && !$this->is_content_available($course_id) ) {
				return false;
			}

			return $this->process_email($user_id, $course_id, $schedule);
		}

		private function process_email($user_id, $course_id, $schedule) {

			$email_settings = get_course_availability_email_settings();
			$subject = $email_settings['subject'];
			$message = $email_settings['message'];

			$user = get_userdata($user_id);;
			$course_title = get_the_title($course_id);
			$course_link = sprintf('<a href="%s" target="_blank">%s</a>', get_the_permalink($course_id), $course_title);
			$start_at = date('F jS, Y g:i A',strtotime($schedule->start));
			$end_at = date('F jS, Y g:i A',strtotime($schedule->end));
			$both = $start_at.' '.__('to', 'cs_ld_addon' ).' '.$end_at;
			$is_hide = get_option('course_scheduler_ld_addon_setting', 'hide') == 'hide';

			$will_be = __('unavailable','cs_ld_addon');
			if(!$is_hide) {
				$will_be = __('available','cs_ld_addon');
			}

			$subject = str_replace(array(
				'[user_login]',
				'[course]',
				'[course_with_link]',
				'[schedule_availability]',
				'[schedule_datetime_start_only]',
				'[schedule_datetime_end_only]',
				'[schedule_datetime]'
			), array(
				$user->user_login,
				$course_title,
				$course_link,
				$will_be,
				$start_at,
				$end_at,
				$both
			), $subject);

			$message = str_replace(array(
				'[user_login]',
				'[course]',
				'[course_with_link]',
				'[schedule_availability]',
				'[schedule_datetime_start_only]',
				'[schedule_datetime_end_only]',
				'[schedule_datetime]'
			), array(
				$user->user_login,
				$course_title,
				$course_link,
				$will_be,
				$start_at,
				$end_at,
				$both
			), $message);

			$message = $this->get_full_message($message);

			return $this->send_email($user->user_email, $subject, $message);
		}

		private function send_email($email, $subject, $message) {
			$site_name = get_option('blogname');
			$admin_email = get_option('admin_email');

			$headers = [];
			 $headers[] = "From: {$site_name} <{$admin_email}>";
			$headers[] = "Content-Type: text/html; charset=UTF-8"; 

			return wp_mail($email, $subject, $message, $headers);
		}

		private function get_full_message($message) {
			$message_template_header = apply_filters('ld_cs_email_notify_message_header_template',  dirname(__FILE__) . '/views/notify_message_header.php');
			$message_template_footer = apply_filters('ld_cs_email_notify_message_footer_template',  dirname(__FILE__) . '/views/notify_message_footer.php');

			ob_start();
			include_once $message_template_header;
			echo wpautop($message);
			include_once $message_template_footer;
			$message = ob_get_clean();

			return $message;
		}

		private function get_course_schedules($course_ids, $interval=1, $interval_unit='day') {
            
			$course_schedules = [];

			if( !empty($course_ids) ) {
                
				global $wpdb;

				$date = date('Y-m-d', strtotime(current_time('mysql') . " +{$interval} {$interval_unit}"));

				$format = $this->query_in_placeholders($course_ids, '%d');

				$table_name = "{$wpdb->prefix}csld_events";

				$query = "SELECT * FROM `{$table_name}` E 
                        WHERE E.`object_type`='sfwd-courses' 
                          AND E.`object_id` IN ({$format})";

				$query .= " AND DATE(E.`start`) = DATE(%s)";
				$query .= " AND E.`is_subsdate_as_startdate` != %s";
				$query .= ";";

				$query_data = $course_ids;
				$query_data[] = $date;
				$query_data[] = 'Yes';

				$results = $wpdb->get_results( $wpdb->prepare($query, $query_data) );
				//echo $wpdb->last_query;
            
				if( !empty($results) ) {

					foreach ($results as $result) {
						$course_schedules[$result->object_id][] = $result;
					}
				}
			}

			return $course_schedules;
		}

		private function query_in_placeholders(array $values, $placeholder = '%s') {

			$format = null;

			if( !empty($values) ) {

				if (empty($placeholder)) {
					$placeholder = '%s';
				}

				$count = count($values);
				$placeholders = array_fill(0, $count, $placeholder);
				$format = implode(', ', $placeholders);
			}

			return $format;
		}

		private function is_content_hidden_for_all($content_id) {
			$content_hidden_for_all = get_post_meta($content_id, '_csld_hide_all_users', true);

			return ($content_hidden_for_all == 'yes');
		}

		private function is_content_available($content_id) {
			$availability_status = get_option( 'course_scheduler_ld_addon_setting', 'hide' ) == 'show';

			$content_availability_status = get_post_meta($content_id,'_show_hide_action',true);

			if( !empty($content_availability_status) ) {
				$availability_status = $content_availability_status;
			}

			return ($availability_status == 'show');
		}

		private function user_has_access($user_id, $user_roles, $user_ids, $access_type = 'include') {

			$access_type = strtolower(sanitize_text_field($access_type));

			if( empty($access_type) ) {
				$access_type = 'include';
			}

			//Set default values according to access type
			if( $access_type == 'include' ) {
				$schedule_user_role_exists = true;
				$schedule_user_id_exists = true;
			} else {
				$schedule_user_role_exists = false;
				$schedule_user_id_exists = false;
			}

			if( !empty($user_roles) ) {
				$schedule_user_role_exists = $this->is_user_role_exists($user_id, $user_roles);
			}

			if( !empty($user_ids) ) {
				$schedule_user_id_exists = $this->is_user_id_exists($user_id, $user_ids);
			}

			if($access_type == 'include' && $schedule_user_role_exists && $schedule_user_id_exists) {
				return true;
			}

			if($access_type == 'exclude' && !$schedule_user_role_exists && !$schedule_user_id_exists) {
				return true;
			}

			return false;
		}

		private function is_user_role_exists($user_id, $user_roles) {

			$schedule_user_role_exists = true;

			if( !empty($user_roles) ) {

				$user_roles = array_map( function($role) {
					if( !empty(trim($role)) ) {
						return $role;
					}
				}, explode(',',$user_roles) );

				$current_user_roles = $this->get_current_user_roles($user_id);

				$schedule_user_role_exists = !empty(array_intersect($current_user_roles, $user_roles));

			}

			return $schedule_user_role_exists;
		}

		private function get_current_user_roles($user_id) {
			$user = get_userdata($user_id);
			if ( !is_wp_error($user) ) {
				$roles = ( array )$user->roles;
				return $roles;
			} else {
				return array();
			}
		}

		private function is_user_id_exists($user_id, $user_ids) {

			$schedule_user_id_exists = true;

			if( !empty($user_ids) ) {

				$user_ids = array_map( function($user_id) {
					if( !empty(trim($user_id)) ) {
						return $user_id;
					}
				}, explode(',', $user_ids) );

				$schedule_user_id_exists = in_array($user_id, $user_ids);
			}

			return $schedule_user_id_exists;
		}

	} //Class End
}

/**
 * Global helper method to retrieve email settings
 */
function get_course_availability_email_settings() {

	$default_subject = __('Course [course] Reminder', 'cs_ld_addon');
	$default_message = __('<p>Dear [user_login],</p><p>Your course <strong>[course_with_link]</strong> will be [schedule_availability] on <strong>[schedule_datetime]</strong></p><p>Thank You</p>', 'cs_ld_addon');
	$db_form_fields  = get_option('ld_cms_availability_email_settings', array());

	$db_form_fields = wp_parse_args($db_form_fields, array('subject' => $default_subject, 'message' => $default_message, 'interval' => 1, 'interval_unit' => 'day'));

	return $db_form_fields;
}

//If send email option is enabled


add_action('init', 'call_mail_smtp');
function call_mail_smtp() {
	if(get_option( 'ld_cms_send_course_availability_email', 'no') == 'yes') {
		add_action( 'ld_cms_notify_cron_hook', 'ld_cms_notify' );
		
		//Schedule cron everyday midnight
		if ( ! wp_next_scheduled( 'ld_cms_notify_cron_hook' ) ) {
			wp_schedule_event( strtotime('tomorrow'), 'daily', 'ld_cms_notify_cron_hook' );
		}
	} else {
		$timestamp = wp_next_scheduled( 'ld_cms_notify_cron_hook' );
		wp_unschedule_event( $timestamp, 'ld_cms_notify_cron_hook' );
	}
}

function ld_cms_notify() {
	new LD_CS_NOTIFY();
}
