<?php
/**
 * Wemeet OAuth Handler Class
 *
 * Handles OAuth authentication callbacks from external services like Webex.
 *
 * @package SOVLIX\WEMEET\Admin
 */

namespace SOVLIX\WEMEET\Admin;

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

/**
 * Wemeet_OAuth_Handler Class
 *
 * Manages OAuth authentication flow and callback handling.
 *
 * @since 1.0.0
 */
class Wemeet_OAuth_Handler {

	/**
	 * Webex API instance.
	 *
	 * @var \SOVLIX\WEMEET\API\Webex_Api
	 */
	private $webex_api;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->webex_api = \SOVLIX\WEMEET\API\Webex_Api::get_instance();
		$this->handle_oauth_callback();
	}

	/**
	 * Handle OAuth callback from Webex.
	 *
	 * This method processes the OAuth authorization callback from Webex,
	 * validates the state parameter, and fetches the access token.
	 *
	 * @return void
	 */
	public function handle_oauth_callback() {
		/*
		 * OAuth callback parameters from external Webex service.
		 * These parameters are sent by Webex during the OAuth authorization flow and cannot include WordPress nonces.
		 * Security is ensured through:
		 * 1. OAuth state parameter validation (verify_oauth_state method) - prevents CSRF attacks
		 * 2. Input sanitization using WordPress functions
		 * 3. Page allowlist validation
		 * 4. Timing-safe comparison using hash_equals()
		 */
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		$code  = isset( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : '';
		$page  = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
		$state = isset( $_GET['state'] ) ? sanitize_text_field( wp_unslash( $_GET['state'] ) ) : '';
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		// Validate page parameter against allowlist.
		$allowed_pages = array( 'wemeet-settings' );

		// Only process OAuth callback on allowed pages.
		if ( ! in_array( $page, $allowed_pages, true ) ) {
			return;
		}

		// Process OAuth callback if code is present.
		if ( ! empty( $code ) ) {
			if ( ! empty( $state ) && $this->verify_oauth_state( $state ) ) {
				// Handle Webex token fetch with validated state.
				$this->webex_api->fetch_access_token();
			}
		}
	}

	/**
	 * Verify OAuth state to prevent CSRF attacks.
	 *
	 * This method validates the OAuth state parameter by comparing it with
	 * the stored state value using a timing-safe comparison.
	 *
	 * @param string $state The state value to verify.
	 * @return bool True if state is valid, false otherwise.
	 */
	private function verify_oauth_state( $state ) {
		$stored_state = get_transient( 'wemeet_oauth_state_' . get_current_user_id() );
		delete_transient( 'wemeet_oauth_state_' . get_current_user_id() );
		return ! empty( $stored_state ) && hash_equals( $stored_state, $state );
	}
}
