<?php

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

class ESLP_Google_Module {

	private static $eslp_easy_social_login_extra = null;

	/**
	 * Constructor for the class.
	 * 
	 * Initializes necessary components for the plugin, including loading required files, 
	 * registering settings, and hooking into WordPress actions and filters.
	 */
	public function __construct() {
		
		// Include the additional functionality for easy social login
		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();
		
		// Ensure that class methods are called correctly
		add_action( 'admin_init', [ $this, 'eslp_register_google_settings' ] );
		
		// Initialize the Social Media Icon hooks
		self::eslp_init_hook();

		// Add query variables for Google OAuth handling
		add_filter( 'query_vars', array( $this, 'eslp_google_add_query_vars' ) );
		
		// Handle the Google OAuth request
		add_action( 'template_redirect', array( $this, 'eslp_google_handle_oauth_request' ) );
		
		// Enqueue scripts for the module
		add_action( 'login_enqueue_scripts', [ $this, 'eslp_module_enqueue_scripts' ] );
		// Enqueue scripts during WooCommerce checkout if the user is not logged in
		if ( !is_user_logged_in() ) {
			add_action( 'woocommerce_checkout_init', [ $this, 'eslp_module_enqueue_scripts' ] );
		}

	}

	/**
	 * Returns the slug for the Google module.
	 * 
	 * @return string The slug for the module.
	 */
	public function eslp_module_get_slug() {
		return 'google';
	}

	/**
	 * Returns the name for the Google module.
	 * 
	 * @return string The name of the module.
	 */
	public function eslp_module_get_name() {
		return 'Google';
	}

	/**
	 * Enqueues the necessary CSS and JS files for the Google module.
	 * 
	 * Loads the required styles and scripts, and localizes the script with relevant 
	 * data for Google OAuth functionality.
	 */
	public function eslp_module_enqueue_scripts(){
		// Enqueue CSS and JS files if necessary
		wp_enqueue_style( 'eslp-google-css', esc_url( plugins_url( 'google.css', __FILE__ ) ), false, ESLP_VERSION );
		wp_enqueue_script( 'eslp-google-js', esc_url( plugins_url( 'google-min.js', __FILE__ ) ), array( 'jquery' ), ESLP_VERSION, true );

		// Localize the Google JS script with relevant data
		wp_localize_script('eslp-google-js', 'eslpGoogleData', [
			'client_id'    => get_option('eslp_google_client_id'),
			'exchange_url' => get_option('eslp_google_redirect_uri'),
			'redirect_url' => self::eslp_module_url_to_go()
		]);
	}

	/**
	 * Registers the Google settings in the WordPress admin.
	 * 
	 * Registers settings for Google OAuth, adds default options if not already set, 
	 * and sets up the admin settings section and fields for configuration.
	 */
	public function eslp_register_google_settings() {
		register_setting( 'eslp_google_settings', 'eslp_google_enabled', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => 'no',
		) );
		
		register_setting( 'eslp_google_settings', 'eslp_google_client_id', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => null,
		) );

		register_setting( 'eslp_google_settings', 'eslp_google_client_secret', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => null,
		) );

		register_setting( 'eslp_google_settings', 'eslp_google_redirect_uri', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_url',
			'default'           => home_url( '?eslp_google_oauth_callback=1' ),
		) );

		// Add default options if they do not exist
		if ( 'not-exists' === get_option( 'eslp_google_enabled', 'not-exists' ) ) {
			add_option( 'eslp_google_enabled', 'no' );
		}
		if ( 'not-exists' === get_option( 'eslp_google_client_id', 'not-exists' ) ) {
			add_option( 'eslp_google_client_id', null );
		}
		if ( 'not-exists' === get_option( 'eslp_google_client_secret', 'not-exists' ) ) {
			add_option( 'eslp_google_client_secret', null );
		}
		if ( 'not-exists' === get_option( 'eslp_google_redirect_uri', 'not-exists' ) ) {
			add_option( 'eslp_google_redirect_uri', sanitize_url( ( home_url( '?eslp_google_oauth_callback=1' ) ) ) );
		}

		// Admin settings section
		add_settings_section(
			'eslp_google_settings_section',
			esc_html( __('Google Settings','easy-social-login') ),
			null,
			'eslp_google_settings_page'
		);

		// Field for Google Tutorial
		add_settings_field(
			'eslp_google_tutorial', // Field ID
			esc_html( __('Google Tutorial','easy-social-login') ), // Title
			[ $this, 'eslp_module_tutorial' ], // Callback for displaying the field
			'eslp_google_settings_page', // Page
			'eslp_google_settings_section' // Section
		);

		// Field for enabling Google OAuth
		add_settings_field(
			'eslp_google_enabled',
			esc_html( __('Enable Google','easy-social-login') ),
			[ $this, 'eslp_google_enabled_callback' ],
			'eslp_google_settings_page',
			'eslp_google_settings_section'
		);

		// Field for Google Client ID
		add_settings_field(
			'eslp_google_client_id',
			esc_html( __('Google Client ID','easy-social-login') ),
			[ $this, 'eslp_google_client_id_callback' ],
			'eslp_google_settings_page',
			'eslp_google_settings_section'
		);

		// Field for Google Client Secret
		add_settings_field(
			'eslp_google_client_secret',
			esc_html( __('Google Client Secret','easy-social-login') ),
			[ $this, 'eslp_google_client_secret_callback' ],
			'eslp_google_settings_page',
			'eslp_google_settings_section'
		);

		// Field for Authorized JavaScript Origins
		add_settings_field(
			'eslp_google_js_origins',
			esc_html( __('Authorized JavaScript Origins','easy-social-login') ),
			[ $this, 'eslp_google_oauth_js_origins' ],
			'eslp_google_settings_page',
			'eslp_google_settings_section'
		);

		// Field for Authorized Redirect URIs
		add_settings_field(
			'eslp_google_redirect_uri',
			esc_html( __('Authorized redirect URIs','easy-social-login') ),
			[ $this, 'eslp_google_oauth_redirect_uri_callback' ],
			'eslp_google_settings_page',
			'eslp_google_settings_section'
		);
	}

	/**
	 * Uninstalls the Google settings by deleting options from the database.
	 * 
	 * Removes the stored settings for Google OAuth, such as enabled status, client ID, 
	 * client secret, and redirect URI.
	 */
	public function eslp_uninstall(){
		delete_option('eslp_google_enabled');
		delete_option('eslp_google_client_id');
		delete_option('eslp_google_client_secret');
		delete_option('eslp_google_redirect_uri');
	}

	/**
	 * Renders the settings page for the Google module.
	 * 
	 * Outputs the settings fields and sections for the Google settings page in the admin 
	 * area.
	 */
	public function eslp_module_render_settings() {
		settings_fields( 'eslp_google_settings' );
		do_settings_sections( 'eslp_google_settings_page' );
	}

	/**
	 * Initialize hooks for displaying social login icons.
	 *
	 * This method sets up the hooks for adding social login buttons 
	 * on various forms, including WordPress login, registration, and WooCommerce forms.
	 */
	public function eslp_init_hook() {
		if ( method_exists($this, 'display_social_icon_form') ) {
			// WordPress login form
			if ( 'not-exists' !== get_option( 'eslp_easy_social_login_display_button_login', 'not-exists' )
				&& get_option( 'eslp_easy_social_login_display_button_login' ) == true ) {
				add_action( 'login_form', function() { self::display_social_icon_form('login_form'); } );
			}

			// WordPress register form
			if ( 'not-exists' !== get_option( 'eslp_easy_social_login_display_button_register', 'not-exists' )
				&& get_option( 'eslp_easy_social_login_display_button_register' ) == true ) {
				add_action( 'register_form', function() { self::display_social_icon_form('register_form'); } );
			}

			// WooCommerce integration
			$woo_status = self::$eslp_easy_social_login_extra->eslp_check_woocommerce_status();
			if ( $woo_status[0] == 'active' ) {
				// WooCommerce login and register forms
				if ( get_option('woocommerce_enable_myaccount_registration') === 'yes' ) {
					// WooCommerce login form
					if ( 'not-exists' !== get_option( 'eslp_easy_social_login_woocommerce_login', 'not-exists' )
						&& get_option( 'eslp_easy_social_login_woocommerce_login' ) == true ) {
						if ( 'not-exists' !== get_option( 'eslp_easy_social_login_button_position', 'not-exists' ) ) {
							$prefix = ( get_option( 'eslp_easy_social_login_button_position' ) == 'after' ) ? '_form_start' : '_form';
							add_action( 'woocommerce_login' . $prefix, function() { self::display_social_icon_form('woocommerce_login_form'); } );
						}
					}

					// WooCommerce register form
					if ( 'not-exists' !== get_option( 'eslp_easy_social_login_woocommerce_register', 'not-exists' )
						&& get_option( 'eslp_easy_social_login_woocommerce_register' ) == true ) {
						if ( 'not-exists' !== get_option( 'eslp_easy_social_login_button_position', 'not-exists' ) ) {
							$prefix = ( get_option( 'eslp_easy_social_login_button_position' ) == 'after' ) ? '_form_start' : '_form';
							add_action( 'woocommerce_register' . $prefix, function() { self::display_social_icon_form('woocommerce_register_form'); } );
						}
					}
				}

				// WooCommerce checkout login form
				if ( get_option('woocommerce_enable_signup_and_login_from_checkout') === 'yes' ) {
					if ( 'not-exists' !== get_option( 'eslp_easy_social_login_woocommerce_checkout', 'not-exists' ) 
						&& get_option( 'eslp_easy_social_login_woocommerce_checkout' ) == true ) {
						if ( !is_user_logged_in() ) {
							add_action( 'woocommerce_checkout_init', function() { self::display_social_icon_form('woocommerce_checkout_login_form'); } );
						}
					}
				}
			}
		}
	}
	
	/**
	 * Displays the Google authentication tutorial with step-by-step images.
	 * 
	 * Outputs a link to open the tutorial and a hidden container with the images for the tutorial.
	 * The images are displayed in a lightbox when clicked.
	 */
	public function eslp_module_tutorial() {
		// Retrieve the list of tutorial image URLs
		$images = self::eslp_get_module_tutorial_images();

		// Output the tutorial information and link to open the tutorial
		?>
		<p>
			<?php echo esc_html( __( 'How to set up authentication, take a look at Google´s tutorial with step-by-step images.','easy-social-login' ) ); ?>
			<a href="javascript:void(0);" id="eslp_open_tutorial">
				<?php echo esc_html( __( 'Open Tutorial','easy-social-login' ) ); ?>
			</a>
		</p>

		<?php // Hidden container for tutorial images ?>
		<div id="eslp-google-tutorial-container" style="display: none;">
		<?php
		// Generate image links for the lightbox
		if ($images) {
			foreach ($images as $index => $image_url) {
				?>
				<a href=" <?php echo esc_url( $image_url ); ?> " data-lightbox="tutorial" data-title=" <?php echo esc_attr( __( 'Step ','easy-social-login' ) . $index + 1 ); ?> "></a>
				<?php
			}
		}
		?>
		</div>
		<?php
	}

	/**
	 * Retrieves the tutorial images for the module.
	 * 
	 * Scans the plugin's directory for PNG images to be used as steps in the tutorial.
	 * 
	 * @return array An array of image URLs.
	 */
	public function eslp_get_module_tutorial_images() {
		$directory = plugin_dir_path(__FILE__) . sanitize_file_name( self::eslp_module_get_slug() ) . '/'; // Physical directory path
		$directory_url = plugin_dir_url(__FILE__) . sanitize_file_name( self::eslp_module_get_slug() ) . '/'; // Base URL of the directory
		$images = [];

		// Use glob() to get all PNG files in the directory
		$image_files = glob($directory . '*.png');

		// Process the found files
		if ($image_files) {
			foreach ($image_files as $file) {
				// Convert the file path to a URL
				$images[] = sanitize_url( $directory_url . basename($file) );
			}
		}

		return $images;
	}

	/**
	 * Displays the callback for enabling Google authentication.
	 * 
	 * Outputs a checkbox to enable or disable Google login functionality.
	 */
	public function eslp_google_enabled_callback() {
		?>
		<input type="checkbox" name="eslp_google_enabled" value="yes" <?php echo esc_attr( checked( get_option( 'eslp_google_enabled' ), 'yes' ) ); ?> />
		<?php
	}

	/**
	 * Displays the callback for setting the Google Client ID.
	 * 
	 * Outputs a text input field for the Google Client ID.
	 */
	public function eslp_google_client_id_callback() {
		?>
		<input type="text" name="eslp_google_client_id" value="<?php echo esc_attr( get_option( 'eslp_google_client_id' ) ); ?>" />
		<?php
	}

	/**
	 * Displays the callback for setting the Google Client Secret.
	 * 
	 * Outputs a password input field for the Google Client Secret and a button to toggle visibility.
	 */
	public function eslp_google_client_secret_callback() {
		$client_secret = get_option( 'eslp_google_client_secret' );
		?>
		<input type="password" id="eslp_google_client_secret" name="eslp_google_client_secret" value="<?php echo esc_attr( $client_secret ); ?>" />
		<button type="button" onclick="toggleSecret( 'eslp_google_client_secret' )">👁️ <?php echo esc_html( __( 'Show Client Secret','easy-social-login' )); ?></button>
		<?php
	}

	/**
	 * Displays the callback for setting the authorized JavaScript origins URL.
	 * 
	 * Outputs a readonly text input field with the current base URL and a button to copy it to the clipboard.
	 */
	public function eslp_google_oauth_js_origins() {
		$protocol = ( isset( $_SERVER['HTTPS'] ) && 'on' === $_SERVER['HTTPS'] ) ? 'https://' : 'http://';
		$host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
		$base_url = $protocol . $host;

		?>
		<input type="text" id="eslp_google_js_origins" name="eslp_google_js_origins" value="<?php echo esc_url( $base_url ); ?>" readonly />
		<a href="javascript:void(0);" class="eslp_copy_content" data-copy-target="eslp_google_js_origins"><?php echo esc_html( __( 'Copy URL','easy-social-login' ) ); ?></a>
		<p class="description"><?php echo esc_html( __( 'Enter this URL in the Authorized JavaScript Origins field of your Google OAuth configuration:','easy-social-login' ) ); ?> 
			<strong><?php echo esc_url( $base_url ); ?></strong>
		</p>
		<?php
	}

	/**
	 * Displays the callback for setting the authorized redirect URI.
	 * 
	 * Outputs a readonly text input field with the current redirect URI and a button to copy it to the clipboard.
	 */
	public function eslp_google_oauth_redirect_uri_callback() {
		$redirect_uri = get_option( 'eslp_google_redirect_uri' );
		?>
		<input type="text" id="eslp_google_redirect_uri" name="eslp_google_redirect_uri" value="<?php echo esc_url( $redirect_uri ); ?>" readonly />
		<a href="javascript:void(0);" class="eslp_copy_content" data-copy-target="eslp_google_redirect_uri"><?php echo esc_html( __( 'Copy URL','easy-social-login' ) ); ?></a>
		<p class="description"><?php echo esc_html( __( 'Enter this URL in the Authorized redirect URIs field of your Google OAuth configuration:','easy-social-login' ) ); ?> 
			<strong><?php echo esc_url( $redirect_uri ); ?></strong>
		</p>
		<?php
	}

	/**
	 * Generates the URL to redirect to after successful login.
	 * 
	 * Retrieves the redirect URL from the options or defaults to the current page's URL.
	 * 
	 * @return string The encoded URL with the state data for redirection after Google login.
	 */
	public function eslp_module_url_to_go() {
		$redirect_option = get_option( 'eslp_easy_social_login_redirect_url', 'not-exists' );
		if ( 'not-exists' !== $redirect_option && !empty( $redirect_option ) ) {
			$url_to_go =  $redirect_option;
		} else {
			global $wp;
			$url_to_go = home_url( add_query_arg( array(), $wp->request ) );
		}
		$state_data = [
			'redirect_url'  => sanitize_url( $url_to_go ),
			'nonce'          => wp_create_nonce('eslp_google_login'),
		];
		$encoded_state = urlencode( wp_json_encode($state_data ));
		return $encoded_state;
	}

	/**
	 * Displays the Google social icon login form.
	 * 
	 * Depending on the context (login, register, etc.), generates a Google OAuth login URL
	 * and displays the appropriate button with a label.
	 *
	 * @param string $param The form context to display the social icon button. It can be:
	 *                      'login_form', 'lostpassword_form', 'woocommerce_login_form', 
	 *                      'woocommerce_checkout_login_form', 'register_form', or 'woocommerce_register_form'.
	 */
	public function display_social_icon_form($param) {
		if ( get_option( 'eslp_google_enabled' ) === 'yes' ) {
			// Google OAuth URL
			$client_id = get_option( 'eslp_google_client_id' );
			$redirect_uri = get_option( 'eslp_google_redirect_uri' );

			$login_url = 'https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=' 
								. $client_id
								. '&state=' . self::eslp_module_url_to_go()
								. '&redirect_uri=' . urlencode( $redirect_uri )
								. '&scope=email profile';
			
			switch ($param) {
				case 'login_form':
				case 'lostpassword_form':
				case 'woocommerce_login_form':
				case 'woocommerce_checkout_login_form':
					$text = esc_html( __('Login with Google','easy-social-login') );
					break;
				case 'register_form':
				case 'woocommerce_register_form':
					$text = esc_html( __('Register with Google','easy-social-login') );
					break;
				default:
					$text = esc_html( __('Login with Google','easy-social-login') );
			}

			add_action( 'woocommerce_login_form', [ $this, 'eslp_module_enqueue_scripts' ] );
			add_action( 'woocommerce_register_form', [ $this, 'eslp_module_enqueue_scripts' ] );

			// Render the button
			?>
			<div id="eslp-google-btn" class="eslp-google-social-login social-buttons">
				<a href="<?php echo esc_url($login_url); ?>">
					<?php echo esc_html( self::icon() ); ?>
					<?php echo esc_html($text); ?>
				</a>
			</div>
			<?php
		}
	}
	
	/**
	 * Outputs the Social Icon as an inline.
	 * 
	 * This function generates a ICON element containing
	 * a predefined size for consistency in UI design.
	 *
	 * @return void Outputs icon directly to the HTML.
	 */
	public function icon(){
		?>
		<span class="dashicons dashicons-google"></span>
		<?php
	}

	/**
	 * Add custom query variable for the Google OAuth callback.
	 * 
	 * @param array $vars The existing query variables.
	 * @return array Modified array with the new query variable.
	 */
	public function eslp_google_add_query_vars( $vars ) {
		$vars[] = 'eslp_google_oauth_callback';
		return $vars;
	}

	/**
	 * Handle the OAuth request by including the callback handler.
	 * 
	 * This function checks if the callback query variable is present and,
	 * if so, includes the callback PHP file for further processing.
	 */
	public function eslp_google_handle_oauth_request() {
		if ( isset( $_GET['eslp_google_oauth_callback'] ) && wp_unslash( $_GET['eslp_google_oauth_callback'] === '1' ) ) {
			include_once plugin_dir_path( dirname( __FILE__ ) ) . 'oauth/eslp-google-callback.php';
			exit;
		}
	}
}