<?php

namespace AcademyProWishlistMember;

class Hooks {
	private $settings = array();
	public static function init() {
		$self = new self();
		$data           = wishlistmember_instance()->get_option( 'academylms_settings' );
		$self->settings = is_array( $data ) ? $data : array();

		// filter hook for inject our plugin to other integrations
		add_filter( 'wishlistmember_integration_providers_list', array( $self, 'add_academy_lms_to_wishlist_integration_provider' ), 10, 2 );
		add_filter( 'wishlistmember_integration_providers_config_path', array( $self, 'add_addon_path_to_wishlist_integration' ), 10, 3 );

		// action hooks for working process of wishlist member
		add_action( 'wishlistmember_user_registered', array( $self, 'new_user_tags_hook' ), 99, 2 );
		add_action( 'wishlistmember_add_user_levels_shutdown', array( $self, 'add_user_tags_hook' ), 10, 3 );

		add_action( 'wishlistmember_confirm_user_levels', array( $self, 'confirm_approval_levels_tags_hook' ), 99, 2 );
		add_action( 'wishlistmember_approve_user_levels', array( $self, 'confirm_approval_levels_tags_hook' ), 99, 2 );

		add_action( 'wishlistmember_pre_remove_user_levels', array( $self, 'remove_users_tags_hook' ), 99, 2 );
		add_action( 'wishlistmember_cancel_user_levels', array( $self, 'cancel_user_tags_hook' ), 99, 2 );

		add_action( 'wishlistmember_save_other_provider', array( $self, 'enroll_existing_members' ) );

		// handler for our plugin
		add_action( 'academy/course/after_enroll', array( $self, 'course_enroll_hook' ), 99, 3 );
		add_action( 'academy/admin/course_complete_after', array( $self, 'course_complete_hook' ), 99, 2 );
	}

	public function add_academy_lms_to_wishlist_integration_provider( $providers, $slug ) {
		if ( 'other_provider' === $slug ) {
			$providers[] = ACADEMY_PRO_ADDON_WISHLIST_MEMBER_PATH;
		}
		return $providers;
	}

	public function course_complete_hook( $course_id, $user_id ) {
		$action = 'complete';
		$user_id = get_current_user_id();
		if ( $user_id ) {
			$settings = isset( $this->settings['course'][ $course_id ][ $action ] ) ? $this->settings['course'][ $course_id ][ $action ] : array();
			$this->do_course_hook( $user_id, $course_id, $action, $settings );
		}
	}

	public function course_enroll_hook( $course_id, $post_id, $user_id ) {
		$action = 'add';
		$post = get_post( $post_id );
		if ( $post ) {
			$settings = isset( $this->settings['course'][ $course_id ][ $action ] ) ? $this->settings['course'][ $course_id ][ $action ] : array();
			$this->do_course_hook( $post->post_author, $course_id, $action, $settings );
		}
	}

	public function add_addon_path_to_wishlist_integration( $path, $provider, $slug ) : string {
		if ( 'academylms' === $provider ) {
			return ACADEMY_PRO_ADDON_WISHLIST_MEMBER_PATH;
		}

		return $path;
	}

	public function new_user_tags_hook( $uid = null, $udata = null ) {
		$user = get_userdata( $uid );
		if ( ! $user ) {
			return;
		}
		if ( false !== strpos( $user->user_email, 'temp_' ) && 37 === strlen( $user->user_email ) && false === strpos( $user->user_email, '@' ) ) {
			return;
		}

		$level_unconfirmed  = wishlistmember_instance()->level_unconfirmed( $udata['wpm_id'], $uid );
		$level_for_approval = wishlistmember_instance()->level_for_approval( $udata['wpm_id'], $uid );

		$settings      = isset( $this->settings['level'][ $udata['wpm_id'] ]['add'] ) ? $this->settings['level'][ $udata['wpm_id'] ]['add'] : array();
		$apply_course  = isset( $settings['apply_course'] ) ? $settings['apply_course'] : array();
		$remove_course = isset( $settings['remove_course'] ) ? $settings['remove_course'] : array();

		if ( ! $level_unconfirmed && ! $level_for_approval ) {
			foreach ( $apply_course as $course_id ) {
				$order_id = "WLM-{$udata['wpm_id']}-{$uid}-{$course_id}";
				\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
			}
			foreach ( $remove_course as $course_id ) {
				\Academy\Helper::cancel_course_enroll( $course_id, $uid );
			}
		}
	}

	public function add_user_tags_hook( $uid, $addlevels = '' ) {
		$user = get_userdata( $uid );
		if ( ! $user ) {
			return;
		}
		if ( false !== strpos( $user->user_email, 'temp_' ) && 37 === strlen( $user->user_email ) && false === strpos( $user->user_email, '@' ) ) {
			return;
		}

		$level_added = reset( $addlevels );

		if ( isset( wlm_post_data()['action'] ) && 'wpm_register' === wlm_post_data()['action'] ) {
			if ( wlm_post_data()['wpm_id'] === $level_added ) {
				return;
			}
		}

		foreach ( $addlevels as $key => $lvl ) {
			$level_unconfirmed  = wishlistmember_instance()->level_unconfirmed( $lvl, $uid );
			$level_for_approval = wishlistmember_instance()->level_for_approval( $lvl, $uid );

			$settings      = isset( $this->settings['level'][ $lvl ]['add'] ) ? $this->settings['level'][ $lvl ]['add'] : array();
			$apply_course  = isset( $settings['apply_course'] ) ? $settings['apply_course'] : array();
			$remove_course = isset( $settings['remove_course'] ) ? $settings['remove_course'] : array();

			if ( ! $level_unconfirmed && ! $level_for_approval ) {
				foreach ( $apply_course as $course_id ) {
					$order_id = "WLM-{$lvl}-{$uid}-{$course_id}";
					\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
				}
				foreach ( $remove_course as $course_id ) {
					\Academy\Helper::cancel_course_enroll( $course_id, $uid );
				}
			} elseif ( isset( wlm_post_data()['SendMail'] ) ) {
				foreach ( $apply_course as $course_id ) {
					$order_id = "WLM-{$lvl}-{$uid}-{$course_id}";
					\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
				}
				foreach ( $remove_course as $course_id ) {
					\Academy\Helper::cancel_course_enroll( $course_id, $uid );
				}
			}
		}//end foreach
	}

	public function confirm_approval_levels_tags_hook( $uid = null, $levels = null ) {
		$user = get_userdata( $uid );
		if ( ! $user ) {
			return;
		}
		if ( false !== strpos( $user->user_email, 'temp_' ) && 37 === strlen( $user->user_email ) && false === strpos( $user->user_email, '@' ) ) {
			return;
		}

		$levels             = is_array( $levels ) ? $levels : (array) $levels;
		$level_unconfirmed  = wishlistmember_instance()->level_unconfirmed( $levels[0], $uid );
		$level_for_approval = wishlistmember_instance()->level_for_approval( $levels[0], $uid );

		$settings      = isset( $this->settings['level'][ $levels[0] ]['add'] ) ? $this->settings['level'][ $levels[0] ]['add'] : array();
		$apply_course  = isset( $settings['apply_course'] ) ? $settings['apply_course'] : array();
		$remove_course = isset( $settings['remove_course'] ) ? $settings['remove_course'] : array();

		if ( ! $level_unconfirmed && ! $level_for_approval ) {
			foreach ( $apply_course as $course_id ) {
				$order_id = "WLM-{$level[0]}-{$uid}-{$course_id}";
				\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
			}
			foreach ( $remove_course as $course_id ) {
				\Academy\Helper::cancel_course_enroll( $course_id, $uid );
			}
		}
	}

	public function remove_users_tags_hook( $uid, $removedlevels = '' ) {
		$user = get_userdata( $uid );
		if ( ! $user ) {
			return;
		}
		if ( false !== strpos( $user->user_email, 'temp_' ) && 37 === (int) strlen( $user->user_email ) && false === strpos( $user->user_email, '@' ) ) {
			return;
		}

		$levels = (array) $removedlevels;
		foreach ( $levels as $key => $level ) {
			if ( false !== strrpos( $level, 'U-' ) ) {
				unset( $levels[ $key ] );
			}
		}
		if ( count( $levels ) <= 0 ) {
			return;
		}

		foreach ( $levels as $level ) {
			$settings      = isset( $this->settings['level'][ $level ]['remove'] ) ? $this->settings['level'][ $level ]['remove'] : array();
			$apply_course  = isset( $settings['apply_course'] ) ? $settings['apply_course'] : array();
			$remove_course = isset( $settings['remove_course'] ) ? $settings['remove_course'] : array();

			foreach ( $apply_course as $course_id ) {
				$order_id = "WLM-{$level}-{$uid}-{$course_id}";
				\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
			}
			foreach ( $remove_course as $course_id ) {
				\Academy\Helper::cancel_course_enroll( $course_id, $uid );
			}
		}
	}

	public function cancel_user_tags_hook( $uid, $cancellevels = '' ) {
		$user = get_userdata( $uid );
		if ( ! $user ) {
			return;
		}
		if ( false !== strpos( $user->user_email, 'temp_' ) && 37 === (int) strlen( $user->user_email ) && false === strpos( $user->user_email, '@' ) ) {
			return;
		}

		// lets check for PPPosts
		$levels = (array) $cancellevels;
		foreach ( $levels as $key => $level ) {
			if ( false !== strrpos( $level, 'U-' ) ) {
				unset( $levels[ $key ] );
			}
		}
		if ( count( $levels ) <= 0 ) {
			return;
		}

		foreach ( $levels as $level ) {
			$settings      = isset( $this->settings['level'][ $level ]['cancel'] ) ? $this->settings['level'][ $level ]['cancel'] : array();
			$apply_course  = isset( $settings['apply_course'] ) ? $settings['apply_course'] : array();
			$remove_course = isset( $settings['remove_course'] ) ? $settings['remove_course'] : array();

			foreach ( $apply_course as $course_id ) {
				$order_id = "WLM-{$level}-{$uid}-{$course_id}";
				\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
			}

			foreach ( $remove_course as $course_id ) {
				\Academy\Helper::cancel_course_enroll( $course_id, $uid );
			}
		}
	}

	public function enroll_existing_members( $data ) {
		$enroll = wlm_arrval( $data, 'enroll-existing-members' );
		$level = key( wlm_arrval( $data, 'tutorlms_settings', 'level' ) );
		if ( ! is_array( $enroll ) || ! $enroll || ! $level ) {
			return;
		}

		$member_ids = wishlistmember_instance()->member_ids_by_status( 'active', $level );
		foreach ( $member_ids as $uid ) {
			foreach ( $enroll as $course_id ) {
				$order_id = "WLM-{$level}-{$uid}-{$course_id}";
				\Academy\Helper::do_enroll( $course_id, $uid, $order_id );
			}
		}
	}

	private function do_course_hook( $wpuser, $hook_id, $action, $settings ) {
		$added_levels     = isset( $settings['add_level'] ) ? $settings['add_level'] : array();
		$cancelled_levels = isset( $settings['cancel_level'] ) ? $settings['cancel_level'] : array();
		$removed_levels   = isset( $settings['remove_level'] ) ? $settings['remove_level'] : array();

		$current_user_mlevels = wishlistmember_instance()->get_membership_levels( $wpuser );
		$wpm_levels           = wishlistmember_instance()->get_option( 'wpm_levels' );

		$action = strtoupper( substr( $action, 0, 1 ) );
		$txnid  = "Tutor-{$action}{$hook_id}-";

		if ( count( $added_levels ) > 0 ) {
			$user_mlevels  = $current_user_mlevels;
			$add_level_arr = $added_levels;
			foreach ( $add_level_arr as $id => $add_level ) {
				if ( ! isset( $wpm_levels[ $add_level ] ) ) {
					continue;
				}
				if ( ! in_array( $add_level, $user_mlevels, true ) ) {
					$user_mlevels[] = $add_level;
					$new_levels[]   = $add_level;
					wishlistmember_instance()->set_membership_levels( $wpuser, $user_mlevels );
					wishlistmember_instance()->set_membership_level_txn_id( $wpuser, $add_level, "{$txnid}" . time() );// update txnid
				} else {
					$cancelled      = wishlistmember_instance()->level_cancelled( $add_level, $wpuser );
					$resetcancelled = true;
					if ( isset( $wpm_levels[ $add_level ]['uncancelonregistration'] ) ) {
						$resetcancelled = 1 === (int) $wpm_levels[ $add_level ]['uncancelonregistration'];
					}
					if ( $cancelled && $resetcancelled ) {
						$ret = wishlistmember_instance()->level_cancelled( $add_level, $wpuser, false );
						wishlistmember_instance()->set_membership_level_txn_id( $wpuser, $add_level, "{$txnid}" . time() );// update txnid
					}

					$expired      = wishlistmember_instance()->level_expired( $add_level, $wpuser );
					$resetexpired = 1 === (int) $wpm_levels[ $add_level ]['registrationdatereset'];
					if ( $expired && $resetexpired ) {
						wishlistmember_instance()->user_level_timestamp( $wpuser, $add_level, time() );
						wishlistmember_instance()->set_membership_level_txn_id( $wpuser, $add_level, "{$txnid}" . time() );// update txnid
					} else {
						// if levels has expiration and allow reregistration for active members
						$levelexpires     = isset( $wpm_levels[ $add_level ]['expire'] ) ? (int) $wpm_levels[ $add_level ]['expire'] : false;
						$levelexpires_cal = isset( $wpm_levels[ $add_level ]['calendar'] ) ? $wpm_levels[ $add_level ]['calendar'] : false;
						$resetactive      = 1 === (int) $wpm_levels[ $add_level ]['registrationdateresetactive'];
						if ( $levelexpires && $resetactive ) {
							// get the registration date before it gets updated because we will use it later
							$levelexpire_regdate = wishlistmember_instance()->Get_UserLevelMeta( $wpuser, $add_level, 'registration_date' );

							$levelexpires_cal = in_array( $levelexpires_cal, array(
								'Days',
								'Weeks',
								'Months',
								'Years'
							), true ) ? $levelexpires_cal : false;
							if ( $levelexpires_cal && $levelexpire_regdate ) {
								list( $xdate, $xfraction ) = explode( '#', $levelexpire_regdate );
								list( $xyear, $xmonth, $xday, $xhour, $xminute, $xsecond ) = preg_split( '/[- :]/', $xdate );
								if ( 'Days' === $levelexpires_cal ) {
									$xday = $levelexpires + $xday;
								}
								if ( 'Weeks' === $levelexpires_cal ) {
									$xday = ( $levelexpires * 7 ) + $xday;
								}
								if ( 'Months' === $levelexpires_cal ) {
									$xmonth = $levelexpires + $xmonth;
								}
								if ( 'Years' === $levelexpires_cal ) {
									$xyear = $levelexpires + $xyear;
								}
								wishlistmember_instance()->user_level_timestamp( $wpuser, $add_level, mktime( $xhour, $xminute, $xsecond, $xmonth, $xday, $xyear ) );
								wishlistmember_instance()->set_membership_level_txn_id( $wpuser, $add_level, "{$txnid}" . time() );// update txnid
							}
						}//end if
					}//end if
				}//end if
			}//end foreach
			$current_user_mlevels = wishlistmember_instance()->get_membership_levels( $wpuser );
		}//end if
		if ( count( $cancelled_levels ) > 0 ) {
			$user_mlevels = $current_user_mlevels;
			foreach ( $cancelled_levels as $id => $cancel_level ) {
				if ( ! isset( $wpm_levels[ $cancel_level ] ) ) {
					continue;
				}
				if ( in_array( $cancel_level, $user_mlevels, true ) ) {
					$ret = wishlistmember_instance()->level_cancelled( $cancel_level, $wpuser, true );
				}
			}
		}
		if ( count( $removed_levels ) > 0 ) {
			$user_mlevels = $current_user_mlevels;
			foreach ( $removed_levels as $id => $remove_level ) {
				$arr_index = array_search( $remove_level, $user_mlevels, true );
				if ( false !== $arr_index ) {
					unset( $user_mlevels[ $arr_index ] );
				}
			}
			wishlistmember_instance()->set_membership_levels( $wpuser, $user_mlevels );
			wishlistmember_instance()->schedule_sync_membership( true );
		}
	}

}
