<?php

/**
 * Main class for Login Redirects
 *
 * @package LoginPress Pro
 * @since 3.0.0
 */

if ( ! class_exists( 'LoginPress_Set_Login_Redirect' ) ) :

	/**
	 * Set's LoginPress Login Redirects.
	 */
	class LoginPress_Set_Login_Redirect {

		/** * * * * * * * *
		 * Class constructor
		 * * * * * * * * * */
		public function __construct() {

			add_filter( 'login_redirect', array( $this, 'loginpress_redirects_after_login' ), 10, 3 );
			add_action( 'clear_auth_cookie', array( $this, 'loginpress_redirects_after_logout' ), 10 );
			add_action( 'loginpress_redirect_autologin', array( $this, 'loginpress_autologin_redirects' ), 10, 1 );
			// User switching hooks - redirect after user switching compatibility
			add_action( 'switch_to_user', array( $this, 'loginpress_redirect_after_user_switch' ), 10, 4 );
		}

		/**
		 * Check if inner link provided.
		 *
		 * @param string $url URL of the site.
		 * @since 3.0.0
		 * @return bool
		 */
		public function is_inner_link( $url ) {

			$current_site = wp_parse_url( get_site_url() );
			$current_site = $current_site['host'];

			if ( false !== strpos( $url, $current_site ) ) {
				return true;
			}

			return false;
		}

		/**
		 * This function wraps around the main redirect function to determine whether or not to bypass the WordPress local URL limitation.
		 *
		 * @param string $redirect_to where to redirect.
		 * @param string $requested_redirect_to requested redirect.
		 * @param object $user user object.
		 * @return string
		 * @since  3.0.0
		 */
		public function loginpress_redirects_after_login( $redirect_to, $requested_redirect_to, $user ) {

			if ( apply_filters( 'prevent_loginpress_login_redirect', false ) ) {
				return $redirect_to;
			}

			if ( isset( $user->ID ) ) {
				$user_redirects_url = $this->loginpress_redirect_url( $user->ID, 'loginpress_login_redirects_url' );
				$role_redirects_url = get_option( 'loginpress_redirects_role' );

				if ( isset( $user->roles ) && is_array( $user->roles ) ) {

					if ( ! empty( $user_redirects_url ) ) { // check for specific user.

						if ( $this->is_inner_link( $user_redirects_url ) ) {
							return $user_redirects_url;
						}

						$this->loginpress_safe_redirects( $user->ID, $user->name, $user, $user_redirects_url );

					} elseif ( ! empty( $role_redirects_url ) ) { // check for specific role.

						foreach ( $role_redirects_url as $key => $value ) {
							$login_url = isset( $value['login'] ) && ! empty( $value['login'] ) ? $value['login'] : $redirect_to;
							if ( in_array( $key, $user->roles, true ) ) {

								$this->loginpress_safe_redirects( $user->ID, $user->name, $user, $login_url );

							}
						}
					}
				} else {
					return $redirect_to;
				}
			}
			return $redirect_to;
		}

		/**
		 * Callback for clear_auth_cookie.
		 * Fire after user is logged out.
		 *
		 * @return null
		 * @since 3.0.0
		 * @version 6.0.0
		 */
		public function loginpress_redirects_after_logout() {

			// Prevent method from executing.
			if ( apply_filters( 'prevent_loginpress_logout_redirect', false ) ) {
				return;
			}

			// Prevent LoginPress logout redirects during User Switching operations
			if ( $this->loginpress_is_user_switching() ) {
				return;
			}

			$user_id = get_current_user_id();

			// Only execute for registered user.
			if ( 0 !== $user_id ) {
				$user_info = get_userdata( $user_id );
				$user_role = $user_info->roles;

				$role_redirects_url = get_option( 'loginpress_redirects_role' );
				$user_redirects_url = $this->loginpress_redirect_url( $user_id, 'loginpress_logout_redirects_url' );

				if ( isset( $user_redirects_url ) && ! empty( $user_redirects_url ) ) {
					wp_safe_redirect( $user_redirects_url );
					exit;
				} elseif ( ! empty( $role_redirects_url ) ) {
					foreach ( $role_redirects_url as $key => $value ) {
						$logout_url = isset( $value['logout'] ) && ! empty( $value['logout'] ) ? $value['logout'] : wp_login_url();

						if ( in_array( $key, $user_role, true ) ) {
							wp_safe_redirect( $logout_url );
							exit;
						}
					}
				}
			}
		}

		/**
		 * Set auth cookies for user and redirect on login.
		 *
		 * @param int    $user_id user ID.
		 * @param string $username username.
		 * @param obj    $user user object.
		 * @param string $redirect redirect string.
		 *
		 * @since 6.0.0
		 */
		public function loginpress_safe_redirects( $user_id, $username, $user, $redirect ) {

			wp_set_auth_cookie( $user_id, false );
			do_action( 'wp_login', $username, $user );
			wp_safe_redirect( $redirect );
			exit;
		}

		/**
		 * Compatible Login Redirects with Auto Login Add-On.
		 * Redirect a user to a custom URL for specific auto login link.
		 *
		 * @param object $user user object.
		 * @since 3.0.0
		 */
		public function loginpress_autologin_redirects( $user ) {

			$user_redirects_url = $this->loginpress_redirect_url( $user->ID, 'loginpress_login_redirects_url' );
			$role_redirects_url = get_option( 'loginpress_redirects_role' );

			if ( isset( $user->roles ) && is_array( $user->roles ) ) {

				if ( ! empty( $user_redirects_url ) ) { // check for specific user.
					$this->loginpress_safe_redirects( $user->ID, $user->name, $user, $user_redirects_url );
				} elseif ( ! empty( $role_redirects_url ) ) { // check for specific role.

					foreach ( $role_redirects_url as $key => $value ) {

						if ( in_array( $key, $user->roles, true ) ) {
							$this->loginpress_safe_redirects( $user->ID, $user->name, $user, $value['login'] );
						}
					}
				}
			}
		}

		/**
		 * Get user meta.
		 *
		 * @param int    $user_id ID of the user.
		 * @param string $option user meta key.
		 * @return string $redirect_url
		 * @since 3.0.0
		 */
		public function loginpress_redirect_url( $user_id, $option ) {

			if ( ! is_multisite() ) {
				$redirect_url = get_user_meta( $user_id, $option, true );
			} else {
				$redirect_url = get_user_option( $option, $user_id );
			}

			return $redirect_url;
		}

		/**
		 * Check if current user has role redirect.
		 *
		 * @param object $user Current user object.
		 *
		 * @return bool True if user has role redirect, false otherwise.
		 *
		 * @since 6.0.0
		 */
		public static function loginpress_role_redirect( $user ) {

			$role_redirects_url = get_option( 'loginpress_redirects_role' );
			if ( empty( $role_redirects_url ) ) {
				return false;
			}

			foreach ( $role_redirects_url as $key ) {

				if ( in_array( $key, $user->roles, true ) ) {
					return true;
				}
			}
			return false;
		}

		/**
		 * Check if current user has role redirect from user groups.
		 *
		 * @param object $user Current user object.
		 *
		 * @return bool True if user has role redirect, false otherwise.
		 *
		 * @since 6.0.0
		 */
		public static function loginpress_group_redirect( $user ) {

			$group_redirect_url = get_option( 'loginpress_redirects_group' );
			if ( empty( $role_redirects_url ) || ! function_exists( 'learndash_is_user_in_group' ) ) {
				return false;
			}

			$groups = get_posts(
				array(
					'post_type'   => 'groups',
					'post_status' => 'publish',
					'numberposts' => -1,
					'fields'      => 'ids,post_name',
				)
			);

			foreach ( $groups as $group ) {
				$group_name = $group->post_name;
				$group_id   = $group->ID;
				// check if user is part of a group.
				$user_in_groups = learndash_is_user_in_group( $user->ID, $group_id );
				if ( isset( $group_redirect_url[ $group_name ] ) && $user_in_groups ) {
					return true;
				}
			}
			return false;
		}
		/**
		 * Check if user switching is in progress
		 *
		 * @return bool True if user switching is in progress
		 * @since 6.0.0
		 */
		private function loginpress_is_user_switching() {
			// Check if we're in a user switching action
			if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'switch_to_user', 'switch_to_olduser', 'switch_off' ) ) ) {
				return true;
			}

			// Check if current user was switched in
			if ( function_exists( 'current_user_switched' ) && current_user_switched() ) {
				return true;
			}

			return false;
		}

		/**
		 * Redirect after user switching, For user switching plugin compatibility
		 *
		 * @param int    $user_id     The ID of the user being switched to.
		 * @param int    $old_user_id The ID of the user being switched from.
		 * @param string $new_token   The token of the session of the user being switched to.
		 * @param string $old_token   The token of the session of the user being switched from.
		 * @since 6.0.0
		 */
		public function loginpress_redirect_after_user_switch( $user_id, $old_user_id, $new_token, $old_token ) {
			// Get the user object for the user being switched to.
			$user = get_userdata( $user_id );
			if ( ! $user ) {
				return;
			}

			// Apply redirect logic for the switched user.
			$user_redirects_url = $this->loginpress_redirect_url( $user->ID, 'loginpress_login_redirects_url' );
			$role_redirects_url = get_option( 'loginpress_redirects_role' );

			if ( isset( $user->roles ) && is_array( $user->roles ) ) {
				if ( ! empty( $user_redirects_url ) ) {
					wp_safe_redirect( $user_redirects_url );
					exit;
				} elseif ( ! empty( $role_redirects_url ) ) {
					foreach ( $role_redirects_url as $key => $value ) {
						$login_url = isset( $value['login'] ) && ! empty( $value['login'] ) ? $value['login'] : '';
						if ( in_array( $key, $user->roles, true ) && ! empty( $login_url ) ) {
							wp_safe_redirect( $login_url );
							exit;
						}
					}
				}
			}
		}
	}

endif;
new LoginPress_Set_Login_Redirect();
