<?php

// Exit if accessed directly
if( !defined('ABSPATH') ) exit;

class ESLP_FacebookAuthCallback {

	private static $eslp_easy_social_login_extra = null;

	/**
	 * Constructor for initializing the class and loading required files.
	 * 
	 * This constructor includes the necessary file and creates an instance
	 * of the ESLP_Easy_Social_Login_Extra class to handle additional functionality.
	 */
	public function __construct() {	
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/eslp-easy-social-login-extra.php';
		self::$eslp_easy_social_login_extra = new ESLP_Easy_Social_Login_Extra();
	}

	/**
	 * Handles the Facebook OAuth callback.
	 * 
	 * This function is triggered when the user is redirected back from Facebook's OAuth 
	 * service after the user has authenticated. It processes the 'code' and 'state' 
	 * parameters from the URL, validates the nonce, exchanges the code for an access 
	 * token, and retrieves the user details. The user is then either registered or logged in.
	 *
	 * @return void
	 */
	public function handle_facebook_oauth_callback() {        
		// Check if the 'code' and 'state' are present in the URL
		if (isset($_GET['code']) && isset($_GET['state'])) {
			$transient_key = sanitize_text_field(wp_unslash($_GET['state']));

			// Retrieve the state from the transient
			$state_encoded = get_transient($transient_key);
			if (false !== $state_encoded) {
				// Remove the transient immediately
				delete_transient($transient_key);

				// Decode the state
				$state_data = json_decode($state_encoded, true);

				// Validate the nonce
				if (!is_array($state_data) || !isset($state_data['nonce']) || !wp_verify_nonce($state_data['nonce'], 'eslp_facebook_login')) {
					echo esc_html( self::$eslp_easy_social_login_extra->eslp_esc_message(
						__( 'Security check failed. Invalid nonce.', 'easy-social-login' ),
						'die'
						)
					);
				}

				// Exchange the authorization code for an access token
				$app_id = get_option('eslp_facebook_app_id');
				$app_secret = get_option('eslp_facebook_app_secret');
				$callback_url = get_option('eslp_facebook_oauth_redirect_uri');
				$auth_code = sanitize_text_field(wp_unslash($_GET['code']));

				$token_url = add_query_arg(array(
					'client_id'     => $app_id,
					'redirect_uri'  => sanitize_url($callback_url),
					'client_secret' => $app_secret,
					'code'          => $auth_code,
				), 'https://graph.facebook.com/v22.0/oauth/access_token');

				$response = wp_remote_get($token_url);

				if (is_wp_error($response)) {
					echo esc_html( self::$eslp_easy_social_login_extra->eslp_esc_message(
						__( 'Failed to retrieve access token from Facebook.', 'easy-social-login' ),
						'die'
						)
					);
				}

				$token_data = json_decode(wp_remote_retrieve_body($response), true);
				if (!isset($token_data['access_token'])) {
					echo esc_html( self::$eslp_easy_social_login_extra->eslp_esc_message(
						__( 'Invalid access token received from Facebook.', 'easy-social-login' ),
						'die'
						)
					);
				}

				// Use the access token to get user data
				$access_token = sanitize_text_field($token_data['access_token']);
				$user_url = add_query_arg(array(
					'fields'       => 'id,first_name,last_name,name,email',
					'access_token' => $access_token,
				), 'https://graph.facebook.com/me');

				$user_response = wp_remote_get($user_url);
				if (is_wp_error($user_response)) {
					echo esc_html( self::$eslp_easy_social_login_extra->eslp_esc_message(
						__( 'Failed to retrieve user data from Facebook.', 'easy-social-login' ),
						'die'
						)
					);
				}

				$user_data = json_decode(wp_remote_retrieve_body($user_response), true);
				if (isset($user_data['id'])) {
					// Register or log the user
					self::facebook_register_or_login_user($user_data, $state_data['redirect_url']);
				} else {
					echo esc_html( self::$eslp_easy_social_login_extra->eslp_esc_message(
						__( 'Failed to retrieve user data from Facebook.', 'easy-social-login' ),
						'die'
						)
					);
				}
			} else {
				//wp_safe_redirect( sanitize_url( home_url() ) );
				//exit;
			}
		} else {
			//wp_safe_redirect( sanitize_url( home_url() ) );
			//exit;
		}
		// WIP
		?>
		<script language="javascript">
			window.close();
		</script>
		<?php
		// WIP
	}


	/**
	 * Registers or logs in a user based on their Facebook account.
	 * 
	 * @param array  $facebook_user The Facebook user data, including email, name, first_name, last_name, and id.
	 * @param string $redirect_url The URL to redirect to after the user is logged in or registered.
	 * 
	 * @return void
	 */
	private function facebook_register_or_login_user( $facebook_user, $redirect_url ) {
		$email = $facebook_user['email'];
		$name = $facebook_user['name'];
		$first_name = $facebook_user['first_name'];
		$last_name = $facebook_user['last_name'];
		$facebook_id = $facebook_user['id'];

		// Variable to hold the user ID (new or existing)
		$user_id = null;

		if ( email_exists( $email ) ) {
			// User exists, get their ID
			$user = get_user_by( 'email', $email );
			$user_id = $user->ID;
		} else {
			// Register a new user
			$user_id = wp_create_user( $email, wp_generate_password(), $email );
			$role = get_option( 'eslp_social_login_user_role', 'subscriber' );

			if ( !is_wp_error( $user_id ) ) {
				wp_update_user([
					'ID' => $user_id,
					'display_name' => $name,
					'nickname' => $name,
					'first_name' => $first_name,
					'last_name' => $last_name,
					'role' => $role,
				]);

				// Add the Facebook ID as user meta for future reference
				update_user_meta( $user_id, 'eslp_facebook_id', $facebook_id );

				// Notify admin if enabled
				if ( 'not-exists' !== get_option( 'eslp_easy_social_login_notify_admin', 'not-exists' ) ) {
					if ( get_option( 'eslp_easy_social_login_notify_admin' ) == true ) {
						wp_new_user_notification( $user_id, null, 'admin' );
					}
				}
			} else {
				// Handle user creation error
				echo esc_html( $eslp_easy_social_login_extra->eslp_esc_message(
					__( 'Error when creating user: ', 'easy-social-login' ) . esc_html( $user_id->get_error_message() ),
					'die'
					)
				);
				//return;
			}
		}

		// Log the user in and redirect
		if ( $user_id ) {
			add_filter('allowed_redirect_hosts', function ( $hosts ) use ( $redirect_url ) {
				$parsed_url = wp_parse_url( $redirect_url );
				if ( isset( $parsed_url['host'] ) ) {
					$hosts[] = $parsed_url['host'];
				}
				return $hosts;
			});			
			wp_set_auth_cookie( $user_id, true );			
			wp_safe_redirect( sanitize_url( $redirect_url ) );
			exit;
		}
	}

}
$facebook_auth_callback = new ESLP_FacebookAuthCallback();
$facebook_auth_callback->handle_facebook_oauth_callback();