<?php
/**
 * REST API Extension plugin functionality.
 *
 * @package photoshelter-importer
 */

namespace PhotoShelter\Importer\REST_API;

use PhotoShelter\Importer\API\Media\Client as Media_Client;
use PhotoShelter\Importer\API\Media\DataSource as Media_DataSource;
use PhotoShelter\Importer\API\OAuth\Client as OAuth_Client;
use PhotoShelter\Importer\API\OAuth\DataSource as OAuth_DataSource;
use PhotoShelter\Importer\API\User\Client as User_Client;
use PhotoShelter\Importer\API\User\DataSource as User_DataSource;

use function PhotoShelter\Importer\Admin\admin_settings_url;
use function PhotoShelter\Importer\Helper\API\error_response;
use function PhotoShelter\Importer\Helper\File\get_mime_type;

// Constants.
define( 'PHOTOSHELTER_API_BASE', 'https://www.photoshelter.com/psapi/v4.0/' );
define( 'PHOTOSHELTER_API_NAMESPACE', 'photoshelter/v1' );
define( 'PHOTOSHELTER_API_V3_BASE', 'https://www.photoshelter.com/psapi/v3/' );
define( 'PHOTOSHELTER_API_V3_KEY', 'mob4GRwPkIc' );
define( 'PHOTOSHELTER_API_REGEX_KEY', '^[a-zA-Z0-9._]{11}$' );
define( 'PHOTOSHELTER_API_REGEX_COLLECTION_ID', 'C0000[a-zA-Z0-9._]{11}' );
define( 'PHOTOSHELTER_API_REGEX_GALLERY_ID', 'G0000[a-zA-Z0-9._]{11}' );
define( 'PHOTOSHELTER_API_REGEX_MEDIA_ID', '(AD|VD|DO|I0)000[a-zA-Z0-9._]{11}' );
define( 'PHOTOSHELTER_API_REGEX_ORG_ID', 'O0000[a-zA-Z0-9._]{11}' );

/**
 * Bootstrap.
 *
 * Things done on plugin initialization.
 *
 * @since 1.0.0
 */
function bootstrap() {
	add_action( 'rest_api_init', __NAMESPACE__ . '\\register_callback_routes' );
}

/**
 * Get Importer Auth REST Url string.
 *
 * @return string Rest URL.
 * @since 1.0.0
 */
function get_importer_auth_rest_url() {
	return get_rest_url( null, 'photoshelter/v1/importer/auth' );
}

/**
 * Get OAuth register endpoint URL.
 *
 * @return string
 * @since 1.0.0
 */
function get_oauth_register_endpoint_url() {
	// Generate a unique state value for CSRF protection.
	$state = wp_generate_password( 32, false );

	// Store state in transient for validation (expires in 10 minutes).
	set_transient(
		'photoshelter_importer_oauth_state',
		$state,
		10 * MINUTE_IN_SECONDS
	);

	return add_query_arg(
		array(
			'api_key'       => get_api_key(),
			'client_id'     => get_client_id(),
			'redirect_uri'  => get_importer_auth_rest_url(),
			'response_type' => 'code',
			'state'         => $state,
		),
		'https://www.photoshelter.com/psapi/v4.0/oauth/authorize'
	);
}

/**
 * Get API key string.
 *
 * @return string
 * @since 1.0.0
 */
function get_api_key() {
	$options = get_option( 'photoshelter_importer_options', array() );

	return isset( $options['api_key'] ) ? $options['api_key'] : '';
}

/**
 * Get Org ID string.
 *
 * @return string
 * @since 1.0.0
 */
function get_org_id() {
	$options = get_option( 'photoshelter_importer_options', array() );

	return isset( $options['org_id'] ) ? $options['org_id'] : '';
}

/**
 * Get Org ID string.
 *
 * @return string
 * @since 1.0.0
 */
function get_org_name() {
	return get_option( 'photoshelter_importer_org_name', __( 'Library', 'photoshelter-importer' ) );
}

/**
 * Get Client ID.
 *
 * @return string
 * @since 1.0.0
 */
function get_client_id() {
	return get_option( 'photoshelter_importer_oauth_client_id', '' );
}

/**
 * Get Client ID.
 *
 * @return string
 * @since 1.0.0
 */
function get_client_secret() {
	return get_option( 'photoshelter_importer_oauth_client_secret', '' );
}

/**
 * Get OAuth access token.
 *
 * @return string
 * @since 1.0.0
 */
function get_oauth_access_token() {
	return get_option( 'photoshelter_importer_oauth_access_token', '' );
}

/**
 * Get OAuth access token expiration (seconds until expiration).
 *
 * @return int Expiration time in seconds.
 * @since 1.0.0
 */
function get_oauth_access_token_expiration() {
	return intval( get_option( 'photoshelter_importer_oauth_access_token_expires', 0 ) );
}

/**
 * Get OAuth access token expiration timestamp.
 *
 * @return int Expiration timestamp, or 0 if not set.
 * @since 1.3.0
 */
function get_oauth_access_token_expires_at() {
	return intval( get_option( 'photoshelter_importer_oauth_access_token_expires_at', 0 ) );
}

/**
 * Check if OAuth access token is expired.
 *
 * @return bool True if token is expired or missing, false otherwise.
 * @since 1.3.0
 */
function is_oauth_token_expired() {
	$access_token = get_oauth_access_token();
	$expires_at   = get_oauth_access_token_expires_at();

	if ( true === empty( $access_token ) ) {
		return true;
	}

	// If expiration timestamp is not set, consider it expired for safety.
	if ( 0 === $expires_at ) {
		return true;
	}

	// Add 60 second buffer to refresh before actual expiration.
	return time() >= ( $expires_at - 60 );
}

/**
 * Refresh OAuth access token using refresh token.
 *
 * @return bool|\WP_Error True on success, \WP_Error on failure.
 * @since 1.3.0
 */
function refresh_oauth_token() {
	$refresh_token = get_oauth_refresh_token();
	$client_id     = get_client_id();
	$client_secret = get_client_secret();
	$api_key       = get_api_key();

	if ( true === empty( $refresh_token ) || true === empty( $client_id ) || true === empty( $client_secret ) || true === empty( $api_key ) ) {
		return new \WP_Error(
			'photoshelter-importer-oauth-refresh-missing-credentials',
			__( 'Missing OAuth credentials required for token refresh.', 'photoshelter-importer' )
		);
	}

	$oauth_client = new OAuth_Client( new OAuth_DataSource( $api_key ) );

	$token_response = $oauth_client->refresh_token(
		array(
			'refresh_token' => $refresh_token,
			'client_id'     => $client_id,
			'client_secret' => $client_secret,
			'redirect_uri'  => get_importer_auth_rest_url(),
		)
	);

	if ( true === is_wp_error( $token_response ) ) {
		return $token_response;
	}

	// Calculate expiration timestamp.
	$expires_in = true === isset( $token_response->expires_in ) ? intval( $token_response->expires_in ) : 0;
	$expires_at = 0 < $expires_in ? time() + $expires_in : 0;

	update_option( 'photoshelter_importer_oauth_access_token', $token_response->access_token );
	update_option( 'photoshelter_importer_oauth_access_token_expires', $expires_in );
	update_option( 'photoshelter_importer_oauth_access_token_expires_at', $expires_at );

	// Update refresh token if a new one is provided.
	if ( true === isset( $token_response->refresh_token ) ) {
		update_option( 'photoshelter_importer_oauth_refresh_token', $token_response->refresh_token );
	}

	return true;
}

/**
 * Get OAuth access token, refreshing if necessary.
 *
 * @return string|\WP_Error Access token string on success, \WP_Error on failure.
 * @since 1.3.0
 */
function get_oauth_access_token_with_refresh() {
	$access_token = get_oauth_access_token();

	if ( true === empty( $access_token ) ) {
		return new \WP_Error(
			'photoshelter-importer-oauth-no-access-token',
			__( 'No OAuth access token available.', 'photoshelter-importer' )
		);
	}

	// Check if token is expired and refresh if necessary.
	if ( true === is_oauth_token_expired() ) {
		$refresh_result = refresh_oauth_token();

		if ( is_wp_error( $refresh_result ) ) {
			return $refresh_result;
		}

		// Get the new token.
		$access_token = get_oauth_access_token();
	}

	return $access_token;
}

/**
 * Revoke OAuth tokens.
 *
 * @param string $token_type Optional. Token type to revoke: 'access_token' or 'refresh_token'. Default 'refresh_token'.
 *
 * @return bool|\WP_Error True on success, \WP_Error on failure.
 * @since 1.3.0
 */
function revoke_oauth_token( $token_type = 'refresh_token' ) {
	$client_id     = get_client_id();
	$client_secret = get_client_secret();
	$api_key       = get_api_key();

	if ( true === empty( $client_id ) || true === empty( $client_secret ) || true === empty( $api_key ) ) {
		return new \WP_Error(
			'photoshelter-importer-oauth-revoke-missing-credentials',
			__( 'Missing OAuth credentials required for token revocation.', 'photoshelter-importer' )
		);
	}

	// Get the appropriate token to revoke.
	if ( 'refresh_token' === $token_type ) {
		$token = get_oauth_refresh_token();
	} else {
		$token = get_oauth_access_token();
	}

	if ( true === empty( $token ) ) {
		return new \WP_Error(
			'photoshelter-importer-oauth-revoke-no-token',
			/* translators: %s: token type */
			sprintf( __( 'No %s available to revoke.', 'photoshelter-importer' ), $token_type )
		);
	}

	$oauth_client = new OAuth_Client( new OAuth_DataSource( $api_key ) );

	$revoke_response = $oauth_client->revoke_token(
		array(
			'client_id'     => $client_id,
			'client_secret' => $client_secret,
			'token'         => $token,
		)
	);

	if ( true === is_wp_error( $revoke_response ) ) {
		return $revoke_response;
	}

	return true;
}

/**
 * Get OAuth refresh token.
 *
 * @return string
 * @since 1.0.0
 */
function get_oauth_refresh_token() {
	return get_option( 'photoshelter_importer_oauth_refresh_token', '' );
}

/**
 * Get User ID.
 *
 * @return string
 * @since 1.0.2
 */
function get_user_id() {
	return get_option( 'photoshelter_importer_user_id', '' );
}

/**
 * Register Importer callback routes.
 *
 * @since 1.0.0
 */
function register_callback_routes() {
	register_rest_route(
		PHOTOSHELTER_API_NAMESPACE,
		'/importer/auth/',
		array(
			'methods'             => \WP_REST_Server::READABLE,
			'callback'            => __NAMESPACE__ . '\\handle_importer_auth_callback',
			'permission_callback' => '__return_true',
		)
	);

	register_rest_route(
		PHOTOSHELTER_API_NAMESPACE,
		'/importer/token/',
		array(
			'methods'             => \WP_REST_Server::EDITABLE,
			'callback'            => __NAMESPACE__ . '\\handle_importer_token_callback',
			'permission_callback' => __NAMESPACE__ . '\\permission_callback',
		)
	);

	register_rest_route(
		PHOTOSHELTER_API_NAMESPACE,
		'/importer/sideload/',
		array(
			'methods'             => \WP_REST_Server::READABLE,
			'callback'            => __NAMESPACE__ . '\\handle_importer_sideload',
			'permission_callback' => __NAMESPACE__ . '\\permission_callback',
		)
	);
}

/**
 * Permission callback.
 *
 * @return bool
 * @since 1.0.0
 */
function permission_callback() {
	return current_user_can( 'edit_others_posts' );
}

/**
 * Handle Importer Auth callback response.
 *
 * @param \WP_REST_Request $request REST API response.
 *
 * @since 1.0.0
 */
function handle_importer_auth_callback( \WP_REST_Request $request ) {
	// Check for error parameter from PhotoShelter (user denial, etc.).
	$error = $request->get_param( 'error' );
	if ( false === empty( $error ) ) {
		$error_description = $request->get_param( 'error_description' );
		$error_message     = false === empty( $error_description ) ? $error_description : __( 'Authorization was denied or failed.', 'photoshelter-importer' );

		set_transient(
			'photoshelter_importer_token_set',
			array(
				'type'    => 'error',
				'message' => $error_message,
			),
			HOUR_IN_SECONDS
		);

		update_option( 'photoshelter_importer_user_id', null );
		update_option( 'photoshelter_importer_user_logged_in', false );

		wp_safe_redirect( admin_settings_url( 'settings&authorized=false' ) );
		exit;
	}

	// Validate state parameter for CSRF protection.
	$state        = $request->get_param( 'state' );
	$stored_state = get_transient( 'photoshelter_importer_oauth_state' );

	if ( true === empty( $state ) || $stored_state !== $state ) {
		set_transient(
			'photoshelter_importer_token_set',
			array(
				'type'    => 'error',
				'message' => __( 'Invalid authorization request. Please try again.', 'photoshelter-importer' ),
			),
			HOUR_IN_SECONDS
		);

		// Delete the state transient since it's been used or invalid.
		delete_transient( 'photoshelter_importer_oauth_state' );

		update_option( 'photoshelter_importer_user_id', null );
		update_option( 'photoshelter_importer_user_logged_in', false );

		wp_safe_redirect( admin_settings_url( 'settings&authorized=false' ) );
		exit;
	}

	// Delete the state transient since it's been validated.
	delete_transient( 'photoshelter_importer_oauth_state' );

	// Check for authorization code.
	$code = $request->get_param( 'code' );
	if ( true === empty( $code ) ) {
		set_transient(
			'photoshelter_importer_token_set',
			array(
				'type'    => 'error',
				'message' => __( 'Authorization code is missing. Please try again.', 'photoshelter-importer' ),
			),
			HOUR_IN_SECONDS
		);

		update_option( 'photoshelter_importer_user_id', null );
		update_option( 'photoshelter_importer_user_logged_in', false );

		wp_safe_redirect( admin_settings_url( 'settings&authorized=false' ) );
		exit;
	}

	$oauth_client = new OAuth_Client( new OAuth_DataSource( get_api_key() ) );

	$token_response = $oauth_client->get_token(
		array(
			'client_id'     => get_client_id(),
			'client_secret' => get_client_secret(),
			'code'          => $code,
			'redirect_uri'  => get_importer_auth_rest_url(),
		)
	);

	if ( true === is_wp_error( $token_response ) ) {
		set_transient(
			'photoshelter_importer_token_set',
			array(
				'type'    => 'error',
				'message' => $token_response->get_error_message(),
			),
			HOUR_IN_SECONDS
		);

		update_option( 'photoshelter_importer_user_id', null );
		update_option( 'photoshelter_importer_user_logged_in', false );

		wp_safe_redirect( admin_settings_url( 'settings&authorized=false' ) );
		exit;
	}

	// Calculate expiration timestamp.
	$expires_in = true === isset( $token_response->expires_in ) ? intval( $token_response->expires_in ) : 0;
	$expires_at = 0 < $expires_in ? time() + $expires_in : 0;

	update_option( 'photoshelter_importer_oauth_access_token', $token_response->access_token );
	update_option( 'photoshelter_importer_oauth_access_token_expires', $expires_in );
	update_option( 'photoshelter_importer_oauth_access_token_expires_at', $expires_at );
	update_option( 'photoshelter_importer_oauth_refresh_token', $token_response->refresh_token );
	update_option( 'photoshelter_importer_user_logged_in', true );

	set_transient(
		'photoshelter_importer_token_set',
		array(
			'type'    => 'success',
			'message' => __( 'Access granted.', 'photoshelter-importer' ),
		),
		HOUR_IN_SECONDS
	);

	$access_token = get_oauth_access_token_with_refresh();
	if ( true === is_wp_error( $access_token ) ) {
		set_transient(
			'photoshelter_importer_token_set',
			array(
				'type'    => 'error',
				'message' => $access_token->get_error_message(),
			),
			HOUR_IN_SECONDS
		);

		update_option( 'photoshelter_importer_user_id', null );
		update_option( 'photoshelter_importer_user_logged_in', false );

		wp_safe_redirect( admin_settings_url( 'settings&authorized=false' ) );
		exit;
	}

	$user         = new User_Client( new User_DataSource( get_api_key(), $access_token ) );
	$user_session = $user->get_session();

	if ( isset( $user_session->data->id ) ) {
		update_option( 'photoshelter_importer_user_id', $user_session->data->id );
	}

	// Redirect to our Settings page URL.
	wp_safe_redirect( admin_settings_url() );
	exit;
}

/**
 * Handle Importer Token callback response.
 *
 * @param \WP_REST_Request $request REST API request.
 *
 * @return \WP_REST_Response|\WP_Error
 * @since 1.0.0
 */
function handle_importer_token_callback( \WP_REST_Request $request ) {
	$token         = strval( $request->get_param( 'token' ) );
	$expires       = intval( $request->get_param( 'expires' ) );
	$refresh_token = strval( $request->get_param( 'refresh_token' ) );

	if ( true === empty( $token ) || true === empty( $expires ) || true === empty( $refresh_token ) ) {
		return new \WP_Error(
			'bad-input',
			__( 'Unexpected input', 'photoshelter-importer' ),
			array(
				'status' => 500,
			)
		);
	}

	// Calculate expiration timestamp.
	$expires_at = 0 < $expires ? time() + $expires : 0;

	update_option( 'photoshelter_importer_oauth_access_token', $token );
	update_option( 'photoshelter_importer_oauth_access_token_expires', $expires );
	update_option( 'photoshelter_importer_oauth_access_token_expires_at', $expires_at );
	update_option( 'photoshelter_importer_oauth_refresh_token', $refresh_token );

	return new \WP_REST_Response(
		array(
			'code'    => 'success',
			'message' => __( 'OK', 'photoshelter-importer' ),
			'data'    => array(
				'status' => 200,
			),
		),
		200
	);
}

/**
 * Handle Importer Sideload callback response.
 *
 * @param \WP_REST_Request $request REST API request.
 *
 * @return \WP_Error|\WP_REST_Response
 * @since 1.0.0
 */
function handle_importer_sideload( \WP_REST_Request $request ) {
	/**
	 * WordPress filesystem.
	 *
	 * @var \WP_Filesystem_Direct
	 */
	global $wp_filesystem;

	require_once ABSPATH . '/wp-admin/includes/image.php';
	require_once ABSPATH . '/wp-admin/includes/media.php';

	// Initialize the WP filesystem.
	if ( true === empty( $wp_filesystem ) ) {
		require_once ABSPATH . '/wp-admin/includes/file.php';
		\WP_Filesystem();
	}

	$file_type        = strval( $request->get_param( 'file_type' ) );
	$file_type        = empty( $file_type ) ? 'original' : $file_type;
	$file_quality     = strval( $request->get_param( 'file_quality' ) );
	$media_id         = strval( $request->get_param( 'media_id' ) );
	$set_file_name    = strval( $request->get_param( 'name' ) );
	$set_file_alt     = strval( $request->get_param( 'alt' ) );
	$set_file_caption = strval( $request->get_param( 'caption' ) );

	// Debug logging for sideload request.
	log_sideload_request( $media_id, $file_type, $file_quality, $set_file_name );

	$file_extension = pathinfo( $set_file_name, PATHINFO_EXTENSION );

	if ( 'original' !== $file_quality ) {
		if ( 'pdf' === $file_extension ) {
			$file_type = 'original';
		} elseif ( 'image' === $file_type ) {
			$file_type = 'jpeg';

			if ( 'original_size' === $file_quality ) {
				$file_quality = '';
			}
		} elseif ( 'video' === $file_type ) {
			$file_type = 'mp4';

			if ( 'original_size' === $file_quality ) {
				$file_quality = '';
			}
		} else {
			$file_type = 'original';
		}
	} else {
		$file_type = 'original';
	}

	if ( true === empty( $media_id ) ) {
		return new \WP_Error(
			'bad-input',
			__( 'Unexpected input', 'photoshelter-importer' ),
			array(
				'status' => 500,
			)
		);
	}

	$access_token = get_oauth_access_token_with_refresh();

	// Debug logging for token status.
	log_sideload_token_status( $access_token );

	if ( true === is_wp_error( $access_token ) ) {
		return new \WP_Error(
			'photoshelter-importer-oauth-token-error',
			$access_token->get_error_message(),
			array(
				'status' => 401,
			)
		);
	}

	$media = new Media_Client( new Media_DataSource( get_api_key(), $access_token ) );

	$info = $media->get_media(
		array(
			'media_id'     => $media_id,
			'file_quality' => $file_quality,
		)
	);

	if ( true === is_wp_error( $info ) ) {
		return error_response( $info, 400 );
	}

	if ( false === property_exists( $info->data->attributes, 'file_name' ) ) {
		return new \WP_Error(
			'api-fetch-error',
			sprintf(
				/* translators: %s is the tmp file path */
				__( 'Response in unexpected format: %s', 'photoshelter-importer' ),
				wp_json_encode( $info )
			),
			array(
				'status' => 500,
			)
		);
	}

	$file_name = $info->data->attributes->file_name;

	$tmp_path = sprintf( '/tmp/%s', $file_name );
	$download = $media->download_media(
		compact( 'file_type', 'file_quality', 'media_id' )
	);

	if ( true === is_wp_error( $download ) ) {
		return error_response( $download, 400 );
	}

	if ( false === $wp_filesystem->put_contents( $tmp_path, $download ) ) {
		return new \WP_Error(
			'file-error',
			sprintf(
				/* translators: %s is the tmp file path */
				__( 'Unable to write to file system: %s', 'photoshelter-importer' ),
				$tmp_path
			),
			array(
				'status' => 500,
			)
		);
	}

	$mime_type = get_mime_type( $tmp_path );

	try {
		$attachment_id = \media_handle_sideload(
			array(
				'name'           => $file_name,
				'tmp_name'       => $tmp_path,
				'post_mime_type' => $mime_type,
			),
			0
		);
	} catch ( \Exception $e ) {
		return new \WP_Error(
			'sideload-error',
			sprintf(
				/* translators: %s is the tmp file path */
				__( 'Unable to sideload attachment: %s', 'photoshelter-importer' ),
				$e->getMessage()
			),
			array(
				'status' => 500,
			)
		);
	}

	if ( true === is_wp_error( $attachment_id ) ) {
		return error_response( $attachment_id, 400 );
	}

	update_post_meta(
		$attachment_id,
		'photoshelter_importer_id',
		$media_id
	);

	if ( true === wp_attachment_is_image( $attachment_id ) ) {
		$image_meta = array(
			'ID' => $attachment_id,
		);

		if ( false === empty( $set_file_name ) ) {
			$image_meta['post_title'] = $set_file_name;
		}

		if ( false === empty( $set_file_caption ) ) {
			$image_meta['post_excerpt'] = $set_file_caption;
		}

		update_post_meta( $attachment_id, '_wp_attachment_image_alt', $set_file_alt );

		wp_update_post( $image_meta );
	}

	return new \WP_REST_Response(
		array(
			'code'    => 'success',
			'message' => __( 'OK', 'photoshelter-importer' ),
			'data'    => array(
				'status' => 200,
				'asset'  => array(
					'id'        => $attachment_id,
					'caption'   => wp_get_attachment_caption( $attachment_id ),
					'mime_type' => get_post_mime_type( $attachment_id ),
					'url'       => wp_get_attachment_url( $attachment_id ),
				),
			),
		),
		200
	);
}

/**
 * Log sideload request details for debugging.
 *
 * @since 1.3.0
 *
 * @param string $media_id     Media ID being requested.
 * @param string $file_type    File type.
 * @param string $file_quality File quality setting.
 * @param string $file_name    File name.
 * @return void
 */
function log_sideload_request( $media_id, $file_type, $file_quality, $file_name ) {
	// Only log if WP_DEBUG is enabled.
	if ( false === defined( 'WP_DEBUG' ) || true !== WP_DEBUG ) {
		return;
	}

	// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log
	error_log( '=== PhotoShelter Sideload Request Debug ===' );
	error_log( 'Media ID: ' . $media_id );
	error_log( 'File Type: ' . $file_type );
	error_log( 'File Quality: ' . $file_quality );
	error_log( 'File Name: ' . $file_name );
	error_log( '=== End PhotoShelter Sideload Request Debug ===' );
	// phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log
}

/**
 * Log token status for sideload debugging.
 *
 * @since 1.3.0
 *
 * @param string|\WP_Error $access_token Access token or WP_Error.
 * @return void
 */
function log_sideload_token_status( $access_token ) {
	// Only log if WP_DEBUG is enabled.
	if ( false === defined( 'WP_DEBUG' ) || true !== WP_DEBUG ) {
		return;
	}

	$is_error        = is_wp_error( $access_token );
	$token_expired   = is_oauth_token_expired();
	$token_truncated = true === $is_error ? 'error' : substr( $access_token, 0, 10 ) . '...';

	// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log
	error_log( '=== PhotoShelter Sideload Token Status ===' );
	error_log( 'Token Is Error: ' . ( true === $is_error ? 'yes' : 'no' ) );
	if ( true === $is_error ) {
		error_log( 'Token Error Code: ' . $access_token->get_error_code() );
		error_log( 'Token Error Message: ' . $access_token->get_error_message() );
	}
	error_log( 'Token Expired Check: ' . ( true === $token_expired ? 'expired' : 'valid' ) );
	error_log( 'Token (truncated): ' . $token_truncated );
	error_log( '=== End PhotoShelter Sideload Token Status ===' );
	// phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log
}
