<?php

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

class ESLP_WindowsLive_Module {
	
	private static $eslp_easy_social_login_extra = null;
	
	/**
	 * Class Constructor for initializing the Easy Social Login module.
	 *
	 * This constructor performs the following:
	 * - Includes the additional functionality file for the plugin.
	 * - Initializes an instance of the `ESLP_Easy_Social_Login_Extra` class.
	 * - Registers Windows Live settings with the `admin_init` hook.
	 * - Initializes social media icon hooks.
	 * - Sets up rewrite rules for query variables and handles OAuth requests.
	 * - Enqueues necessary scripts for the login, WooCommerce login, registration, and checkout forms.
	 */
	public function __construct() {
		// Include additional plugin functionality.
		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 the proper registration of settings and methods.
		add_action('admin_init', [$this, 'eslp_register_windowslive_settings']);

		// Initialize hooks for social media icons.
		self::eslp_init_hook();

		// Setup rewrite rules and handle query variables.
		add_filter('query_vars', array( $this, 'eslp_windowslive_add_query_vars' ) );
		add_action('template_redirect', array( $this, 'eslp_windowslive_handle_oauth_request' ) );

		// Load module scripts for specific forms.
		add_action('login_enqueue_scripts', [$this, 'eslp_module_enqueue_scripts']);
		add_action('woocommerce_login_form', [$this, 'eslp_module_enqueue_scripts']);
		add_action('woocommerce_register_form', [$this, 'eslp_module_enqueue_scripts']);
		if (!is_user_logged_in()) {
			add_action('woocommerce_checkout_init', [$this, 'eslp_module_enqueue_scripts']);
		}		
	}

	/**
	 * Retrieve the slug for the Windows Live module.
	 *
	 * @return string Returns the slug identifier for the Windows Live module.
	 */
	public function eslp_module_get_slug() {
		return 'windowslive';
	}

	/**
	 * Retrieve the name for the Windows Live module.
	 *
	 * @return string Returns the display name for the Windows Live module.
	 */
	public function eslp_module_get_name() {
		return 'Windows Live';
	}

	/**
	 * Enqueue styles and scripts specific to the Windows Live module.
	 *
	 * This function registers and enqueues the necessary CSS file for styling the Windows Live integration.
	 */
	public function eslp_module_enqueue_scripts() {
		wp_enqueue_style(
			'eslp-windowslive-css', 
			esc_url(plugins_url('windowslive.css', __FILE__)), 
			false, 
			ESLP_VERSION
		);
	}
	
	/**
	 * Register settings for Windows Live integration.
	 *
	 * This method defines and registers the settings, sections, and fields 
	 * required for configuring the Windows Live module within the plugin.
	 */
	public function eslp_register_windowslive_settings() {
		// Register the primary settings
		register_setting('eslp_windowslive_settings', 'eslp_windowslive_enabled', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => 'no',
		));
		register_setting('eslp_windowslive_settings', 'eslp_windows_live_client_id', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => null,
		));
		register_setting('eslp_windowslive_settings', 'eslp_windows_live_client_secret', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => null,
		));
		register_setting('eslp_windowslive_settings', 'eslp_windowslive_oauth_redirect_uri', array(
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_url',
			'default'           => home_url(),
		));
		
		// Initialize default options if not already set
		if ('not-exists' === get_option('eslp_windowslive_enabled', 'not-exists')) {
			add_option('eslp_windowslive_enabled', 'no');
		}
		if ('not-exists' === get_option('eslp_windows_live_client_id', 'not-exists')) {
			add_option('eslp_windows_live_client_id', null);
		}
		if ('not-exists' === get_option('eslp_windows_live_client_secret', 'not-exists')) {
			add_option('eslp_windows_live_client_secret', null);
		}
		if ('not-exists' === get_option('eslp_windowslive_oauth_redirect_uri', 'not-exists')) {
			add_option('eslp_windowslive_oauth_redirect_uri', sanitize_url( home_url() ) );
		}

		// Add sections and fields for the Windows Live settings page
		add_settings_section(
			'eslp_windowslive_settings_section', // Section ID
			esc_html( __('Windows Live Settings', 'easy-social-login') ), // Section title
			null, // Optional description callback
			'eslp_windowslive_settings_page' // Page where the section is displayed
		);

		// Field for Windows Live setup tutorial
		add_settings_field(
			'eslp_windowslive_tutorial', // Field ID
			esc_html( __('Windows Live Tutorial', 'easy-social-login') ), // Title
			[$this, 'eslp_module_tutorial'], // Callback to display the field
			'eslp_windowslive_settings_page', // Page
			'eslp_windowslive_settings_section' // Section
		);

		// Field to enable/disable Windows Live integration
		add_settings_field(
			'eslp_windowslive_enabled', // Field ID
			esc_html( __('Enable Windows Live', 'easy-social-login') ), // Title
			[$this, 'eslp_windowslive_enabled_callback'], // Callback to display the field
			'eslp_windowslive_settings_page', // Page
			'eslp_windowslive_settings_section' // Section
		);

		// Field for Windows Live Client ID
		add_settings_field(
			'eslp_windows_live_client_id',
			esc_html( __('Windows Live Client ID', 'easy-social-login') ),
			[$this, 'eslp_windows_live_client_id_callback'],
			'eslp_windowslive_settings_page',
			'eslp_windowslive_settings_section'
		);
		// Field for Windows Live Client SECRET
		add_settings_field(
			'eslp_windows_live_client_secret',
			esc_html( __('Windows Live Client SECRET', 'easy-social-login') ),
			[$this, 'eslp_windows_live_client_secret_callback'],
			'eslp_windowslive_settings_page',
			'eslp_windowslive_settings_section'
		);

		// Field for OAuth Redirect URI
		add_settings_field(
			'eslp_windowslive_oauth_redirect_uri',
			esc_html( __('Redirect URL OAuth', 'easy-social-login') ),
			[$this, 'eslp_windowslive_oauth_redirect_uri_callback'],
			'eslp_windowslive_settings_page',
			'eslp_windowslive_settings_section'
		);
	}

	/**
	 * Uninstall and clean up plugin options.
	 *
	 * This method deletes all the options related to the Windows Live module 
	 * during the uninstallation process.
	 */
	public function eslp_uninstall() {
		delete_option('eslp_windowslive_enabled');
		delete_option('eslp_windows_live_client_id');
		delete_option('eslp_windows_live_client_secret');
		delete_option('eslp_windowslive_oauth_redirect_uri');
	}

	/**
	 * Render the settings page for Windows Live module.
	 *
	 * This method outputs the settings fields and sections for the Windows Live 
	 * settings page in the WordPress admin area.
	 */
	public function eslp_module_render_settings() {
		settings_fields( 'eslp_windowslive_settings' );
		do_settings_sections( 'eslp_windowslive_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 Windows Live 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 Windows Live´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-windowslive-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
	}

	/**
	 * Retrieve Tutorial Images.
	 *
	 * Fetches a list of image URLs from the module's tutorial directory for use in the tutorial display.
	 *
	 * @return array List of tutorial 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;
	}

	/**
	 * Callback for Windows Live Enabled Setting.
	 *
	 * Renders a checkbox input to enable or disable Windows Live integration.
	 */
	public function eslp_windowslive_enabled_callback() {
		?>
		<input type="checkbox" name="eslp_windowslive_enabled" value="yes" <?php echo esc_attr( checked( get_option( 'eslp_windowslive_enabled' ), 'yes' ) ); ?> />
		<?php
	}

	/**
	 * Callback for Windows Live Client ID Setting.
	 *
	 * Renders a text input field for entering the Windows Live Client ID.
	 */
	public function eslp_windows_live_client_id_callback() {
		?>
		<input type="text" name="eslp_windows_live_client_id" value="<?php echo esc_attr( get_option( 'eslp_windows_live_client_id' ) ); ?>" />
		<?php
	}

	/**
	 * Callback for Windows Live Client SECRET Setting.
	 *
	 * Renders a text input field for entering the Windows Live Client SECRET.
	 */
	public function eslp_windows_live_client_secret_callback() {
		?>
		<input type="text" name="eslp_windows_live_client_secret" value="<?php echo esc_attr( get_option( 'eslp_windows_live_client_secret' ) ); ?>" />
		<?php
	}

	/**
	 * Callback for Windows Live OAuth Redirect URI Setting.
	 *
	 * Renders a read-only text field showing the Windows Live OAuth redirect URI with a copy button and description.
	 */
	public function eslp_windowslive_oauth_redirect_uri_callback() {
		$redirect_uri = get_option( 'eslp_windowslive_oauth_redirect_uri' );
		?>
		<input type="text" id="eslp_windowslive_oauth_redirect_uri" name="eslp_windowslive_oauth_redirect_uri" value="<?php echo esc_url( $redirect_uri ); ?>" readonly>
		<a href="javascript:void(0);" class="eslp_copy_content" data-copy-target="eslp_windowslive_oauth_redirect_uri"><?php echo esc_html( __( 'Copy URL', 'easy-social-login' ) ); ?></a>
		<p class="description"><?php echo esc_html( __( 'Enter this URL in the redirect field of your Windows Live OAuth configuration:', 'easy-social-login' ) ); ?>
			<strong><?php echo esc_url( $redirect_uri ); ?></strong>
		</p>
		<?php
	}
	
	/**
	 * Get URL to Redirect After Social Login.
	 *
	 * Determines the redirect URL based on the stored option or defaults to the current page.
	 *
	 * @return string The URL to redirect to after 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 ) );
		}
		return sanitize_url( $url_to_go );
	}

	/**
	 * Display Social Icon Form for Windows Live Login.
	 *
	 * Generates a Windows Live login URL and displays it as a social login button based on the specified form context.
	 *
	 * @param string $param Context of the form (e.g., login, register, etc.).
	 */
	public function display_social_icon_form($param) {
		if (get_option('eslp_windowslive_enabled') === 'yes') {
			// Windows Live App Credentials
			$client_id = get_option('eslp_windows_live_client_id');
			$callback_url = get_option('eslp_windowslive_oauth_redirect_uri');

			// Generate Facebook OAuth URL
			$state_data = array(
				'redirect_url' => self::eslp_module_url_to_go(),
				'nonce'        => wp_create_nonce('eslp_windowslive_login'),
			);
			$encoded_state = urlencode( wp_json_encode($state_data ));

			// Windows Live OAuth Login URL
			$login_url = add_query_arg(array(
				'client_id'     => $client_id,
				'response_type' => 'code',
				'redirect_uri'  => sanitize_url( $callback_url ),
				'scope'         => 'https://graph.microsoft.com/User.Read',
				'response_mode' => 'query',
				'state'         => $encoded_state,
			), 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize');

			// Determine button text based on context
			switch ($param) {
				case 'login_form':
				case 'lostpassword_form':
				case 'woocommerce_login_form':
				case 'woocommerce_checkout_login_form':
					$text = esc_html( __('Login with Windows Live', 'easy-social-login') );
					break;
				case 'register_form':
				case 'woocommerce_register_form':
					$text = esc_html( __('Register with Windows Live', 'easy-social-login') );
					break;
				default:
					$text = esc_html( __('Login with Windows Live', 'easy-social-login') );
			}

			// Render the button
			?>
			<div id="eslp-windowslive-btn" class="eslp-windowslive-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="eslp-windows-live-icon">
			<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
				<path fill="#3c434a" d="M0 3l10.5-1.5v9.5h-10.5v-8zM11.5 1.5l11-1.5v11h-11v-9.5zM0 12.5h10.5v9.5l-10.5-1.5v-8zM11.5 12.5h11v11l-11-1.5v-9.5z"/>
			</svg>
		</span>
		<?php
	}

	/**
	 * Adds query variables for Windows Live OAuth.
	 * 
	 * Adds the 'eslp_windowslive_oauth_callback' query variable to be recognized in 
	 * WordPress URL requests.
	 * 
	 * @param array $vars Existing query variables.
	 * 
	 * @return array The query variables, including the newly added variable.
	 */
	public function eslp_windowslive_add_query_vars( $vars ) {
		$vars[] = 'eslp_windowslive_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_windowslive_handle_oauth_request() {
		if ( isset($_GET['code']) && isset($_GET['state']) ) {
			$state_raw = sanitize_text_field( wp_unslash( $_GET['state'] ) ); // Verifica e "desescapa" o valor
			if ( !empty( $state_raw ) ) {
				$state_decoded = json_decode( $state_raw, true ); // Converte o JSON para array
				// Verifica se a decodificação foi bem-sucedida
				if ( is_array( $state_decoded ) ) {
					$state = $state_decoded;
					// Verifica se o nonce (state) recebido é válido
					if (wp_verify_nonce($state['nonce'], 'eslp_windowslive_login')) {
						include_once plugin_dir_path( dirname( __FILE__ ) ) . 'oauth/eslp-windowslive-callback.php';
						exit;
					}
				}
			}
		}
	}
}