<?php
/**
 * OAuth 2.0 "authorization code" flow handler for Google Sheets/Drive access.
 *
 * @package MetForm_Pro\Core\Integrations\Google_Sheet
 */

namespace MetForm_Pro\Core\Integrations\Google_Sheet;

use MetForm\Core\Admin\Base;

defined( 'ABSPATH' ) || exit;

/**
 * Handles the admin-facing OAuth handshake with Google:
 * - Builds the consent-screen URL the admin is redirected to.
 * - Exchanges the returned authorization code for an access/refresh token pair.
 */
class Google_Access_Token {

	/**
	 * Google OAuth token endpoint.
	 *
	 * @var string
	 */
	const TOKEN_URL = 'https://oauth2.googleapis.com/token';

	/**
	 * Google OAuth consent endpoint.
	 *
	 * @var string
	 */
	const AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';

	/**
	 * OAuth scopes requested during consent.
	 *
	 * @var string[]
	 */
	const SCOPES = array(
		'https://www.googleapis.com/auth/drive',
		'https://www.googleapis.com/auth/spreadsheets',
	);

	/**
	 * URI Google redirects back to after the user grants/denies access.
	 *
	 * @var string
	 */
	public $redirect_uri;

	/**
	 * Google OAuth client ID, from plugin settings.
	 *
	 * @var string
	 */
	public $google_client_id;

	/**
	 * Google OAuth client secret, from plugin settings.
	 *
	 * @var string
	 */
	public $google_client_secret;

	/**
	 * Loads client credentials from stored plugin settings and sets the redirect URI.
	 */
	public function __construct() {
		$settings = Base::instance()->get_settings_option();

		$this->google_client_id     = isset( $settings['mf_google_sheet_client_id'] ) ? $settings['mf_google_sheet_client_id'] : '';
		$this->google_client_secret = isset( $settings['mf_google_sheet_client_secret'] ) ? $settings['mf_google_sheet_client_secret'] : '';
		$this->redirect_uri         = admin_url( '/admin.php?page=metform-menu-settings' );
	}

	/**
	 * Exchanges the `code` query parameter (returned by Google after consent)
	 * for an access token / refresh token pair.
	 *
	 * @return array|false Raw `wp_remote_post()` response array on success, false on failure.
	 */
	public function get_access_token() {
		$code = isset( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( '' === $code ) {
			return false;
		}

		$params = array(
			'code'          => $code,
			'client_id'     => $this->google_client_id,
			'client_secret' => $this->google_client_secret,
			'redirect_uri'  => $this->redirect_uri,
			'grant_type'    => 'authorization_code',
			'access_type'   => 'offline',
		);

		$response = wp_remote_post(
			self::TOKEN_URL,
			array(
				'method' => 'POST',
				'body'   => $params,
			)
		);

		if ( is_wp_error( $response ) ) {
			return false;
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );

		if ( JSON_ERROR_NONE !== json_last_error() || isset( $body['error'] ) ) {
			return false;
		}

		return $response;
	}

	/**
	 * Builds the Google OAuth consent-screen URL the admin should be redirected to
	 * in order to authorize Drive/Sheets access for this site.
	 *
	 * @return string Fully qualified consent URL.
	 */
	public function get_code() {
		$params = array(
			'response_type'   => 'code',
			'client_id'       => $this->google_client_id,
			'redirect_uri'    => $this->redirect_uri,
			'scope'           => implode( ' ', self::SCOPES ),
			'approval_prompt' => 'force',
			'access_type'     => 'offline',
		);

		return self::AUTH_URL . '?' . http_build_query( $params );
	}
}