<?php
/**
 * FacebookProcessLogin class.
 *
 * @since 2.7.0
 */
namespace Masteriyo\Addons\SocialLogin;

defined( 'ABSPATH' ) || exit;


use Exception;
use League\OAuth2\Client\Provider\Facebook;
use Masteriyo\Addons\SocialLogin\Setting;

class FacebookProcessLogin {

	/**
	 * Initialization.
	 *
	 * @since 2.7.0
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'init', array( __CLASS__, 'process' ) );
	}

	/**
	 *  Processes the Facebook login flow and handles user authentication.
	 *
	 * @since 2.7.0
	 *
	 *@return void
	 */
	public static function process() {

		if ( ! static::is_facebook_login_path() ) {
			return;
		}

		$provider = self::get_facebook_provider();

		if ( isset( $_GET['code'] ) ) {//phpcs:ignore WordPress.Security.NonceVerification.Recommended

			$token = self::get_access_token( $provider );

			if ( ! isset( $token ) ) {
				self::redirect_to_home_page();
				return;
			}

			self::handle_user_login( $provider, $token );

			if ( $token->hasExpired() ) {
				self::refresh_token( $provider, $token );
			}

			$page = masteriyo_get_setting( 'general.pages.account_page_id' );
			if ( $page ) {
				wp_redirect(//phpcs:ignore
					get_permalink( $page )
				);
				exit;
			} else {
				wp_redirect(//phpcs:ignore
					home_url( '/' )
				);
				exit;
			}
		}
	}

	/**
	 * sees if user is login using facebook
	 *
	 * @since 2.17.0
	 */
	private static function is_facebook_login_path() {
		$request_path = trim( parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/' );
		if ( strpos( $request_path, 'masteriyo-facebook-login' ) !== false ) {
			return true;
		}

		return false;
	}

	/**
	 * Retrieves a Facebook OAuth2 provider for social login.
	 *
	 * @since 2.7.0
	 *
	 * @return object|string An instance of the Facebook OAuth2 provider if successful,
	 *                      or an error message string if an exception is caught.
	 */
	private static function get_facebook_provider() {
		$setting = new Setting();
		$setting->init();
		$facebook_database_info = $setting->get( 'facebook' );
		$client_secret          = sanitize_text_field( $facebook_database_info['secret_key'] );
		$redirect_uri           = masteriyo_get_social_login_redirect_url( 'masteriyo-facebook-login' );
		$client_id              = sanitize_text_field( $facebook_database_info['client_id'] );

		try {
			return new Facebook(
				array(
					'clientId'        => $client_id,
					'clientSecret'    => $client_secret,
					'redirectUri'     => $redirect_uri,
					'graphApiVersion' => 'v2.10',
				)
			);
		} catch ( Exception $e ) {
			return 'Sorry, something went wrong. Please try again later.';
		}
	}

	/**
	 * Retrieves an access token from a provider using the authorization code.
	 *
	 * @since 2.7.0
	 *
	 * @param object $provider The provider object used to obtain the access token.
	 *
	 * @return string|object The access token if successful, or an error message string
	 *                      if an exception is caught.
	 */
	private static function get_access_token( $provider ) {
		try {
			return $provider->getAccessToken(
				'authorization_code',
				array(
					'code' => sanitize_text_field( $_GET['code'] ), //phpcs:ignore WordPress.Security.NonceVerification.Recommended
				)
			);
		} catch ( Exception $e ) {
			return __( 'Sorry, something went wrong. Please try again later.', 'learning-management-system' );
		}
	}


	/**
	 * sets the user login details in browser if user exist or create user in database
	 *
	 * @since 2.7.0
	 * @param $provider provides the information and methods to get resources based on valid token
	 * @param token used to access the login user data
	 *
	 * @return data to database or logs user in
	 */
	private static function handle_user_login( $provider, $token ) {
		try {

			$user = $provider->getResourceOwner( $token );
			$role = 'masteriyo_student';

			$user_id    = $user->getId();
			$user_email = $user->getEmail();
			$name       = strstr( $user_email, '@', true );
			$first_name = $user->getFirstName();
			$last_name  = $user->getLastName();

			$user = get_user_by( 'email', $user_email );
			$page = masteriyo_get_setting( 'general.pages.account_page_id' );

			if ( $user ) {
				wp_set_auth_cookie( $user->ID, true );

				if ( $page ) {
					wp_redirect( get_permalink( $page ) );
					exit;
				} else {
					wp_redirect( home_url( '/' ) );
					exit;
				}
			}

			/** @var Masteriyo\Database\Model $user */
			$user = masteriyo( 'user' );
			$user->set_username( $name );
			$user->set_password( '' );
			$user->set_email( $user_email );
			$user->set_first_name( $first_name );
			$user->set_last_name( $last_name );
			$user->set_roles( $role );
			$user_id = $user->save();

			if ( is_wp_error( $user_id ) ) {
				wp_die( esc_html( $user_id->get_error_message() ) );
			}
			wp_set_auth_cookie( $user_id, true );
			$page = masteriyo_get_setting( 'general.pages.account_page_id' );
			if ( $page ) {
				wp_redirect( get_permalink( $page ) );
				exit;
			} else {
				wp_redirect( home_url( '/' ) );
				exit;
			}
		} catch ( Exception $e ) {
			return __( 'Sorry, something went wrong. Please try again later.', 'learning-management-system' );
		}
	}

	/**
	 *  Handles user login and registration using a provider and access token.
	 *
	 * @since 2.7.0
	 * @param object $provider The provider object used for user authentication.
	 * @param object $token  The access token obtained for the authenticated user.
	 * @return void|string If successful, logs in the user. If an exception is caught, returns an error message string.
	*/
	private static function refresh_token( $provider, $token ) {
		try {
			$long_lived_token = $provider->getLongLivedAccessToken( $token->getToken() );
			if ( $long_lived_token ) {
				$token = $long_lived_token;
			}
		} catch ( Exception $e ) {
			return __( 'Sorry, something went wrong. Please try again later.', 'learning-management-system' );
		}
	}

	/**
	 * Redirect to the home page.
	 *
	 * @since 2.7.0
	 */
	private static function redirect_to_home_page() {
		wp_safe_redirect( home_url( '/' ) );
		exit;
	}
}
