<?php
/**
 * Use stored Google profile image in get_avatar() when appropriate.
 *
 * @package GoogleSignIn
 */

namespace GoogleSignIn;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Order vs other PowerSuite modules:
 * - Local User Avatar: get_avatar_data (uploaded attachment URL)
 * - Alphabet Avatars: get_avatar @ 10 (initials fallback; skips local uploads)
 * - This filter: get_avatar @ 20 — Google URL when no local upload is set
 */
final class AvatarDisplay {

	private const META_GOOGLE  = 'wpps_google_avatar';
	private const META_LOCAL   = 'powersuite_avatar';

	public static function register(): void {
		add_filter( 'get_avatar', [ self::class, 'filterGetAvatar' ], 20, 6 );
	}

	/**
	 * @param \WP_User|\WP_Error|null|false $id_or_email mixed from core.
	 */
	public static function filterGetAvatar( string $avatar, $id_or_email, int $size, string $default, string $alt, array $args ): string {
		$user = self::resolveUser( $id_or_email );
		if ( ! $user instanceof \WP_User ) {
			return $avatar;
		}

		if ( self::userHasLocalAvatar( (int) $user->ID ) ) {
			return $avatar;
		}

		$url = get_user_meta( (int) $user->ID, self::META_GOOGLE, true );
		$url = is_string( $url ) ? esc_url_raw( $url ) : '';
		if ( $url === '' || ! self::isLikelyImageUrl( $url ) ) {
			return $avatar;
		}

		$w = isset( $args['width'] ) ? (int) $args['width'] : $size;
		$h = isset( $args['height'] ) ? (int) $args['height'] : $size;
		if ( $w < 1 ) {
			$w = $size;
		}
		if ( $h < 1 ) {
			$h = $size;
		}
		$alt_text = ( $alt !== '' ) ? $alt : ( $user->display_name ? $user->display_name : __( 'Profile photo', 'wp-powersuite' ) );
		$css_size = (int) $size;
		$classes  = [ 'avatar', 'avatar-' . $css_size, 'avatar-wpps-google' ];
		if ( ! empty( $args['class'] ) ) {
			$classes[] = is_array( $args['class'] ) ? implode( ' ', $args['class'] ) : (string) $args['class'];
		}
		$loading  = isset( $args['loading'] ) ? ' loading="' . esc_attr( (string) $args['loading'] ) . '"' : '';
		$decoding = isset( $args['decoding'] ) ? ' decoding="' . esc_attr( (string) $args['decoding'] ) . '"' : ' decoding="async"';
		$extra    = (string) apply_filters( 'wpps_google_avatar_img_attributes', '', $user, $url, $args, $size );
		$extra    = ( $extra !== '' && str_starts_with( $extra, ' ' ) ) ? $extra : ( $extra !== '' ? ' ' . $extra : '' );

		return sprintf(
			'<img src="%s" alt="%s" class="%s" width="%d" height="%d"%s%s%s />',
			esc_url( $url ),
			esc_attr( $alt_text ),
			esc_attr( implode( ' ', $classes ) ),
			$w,
			$h,
			$loading,
			$decoding,
			$extra
		);
	}

	private static function userHasLocalAvatar( int $user_id ): bool {
		$aid = (int) get_user_meta( $user_id, self::META_LOCAL, true );
		if ( $aid < 1 ) {
			return false;
		}
		return wp_attachment_is_image( $aid );
	}

	private static function isLikelyImageUrl( string $url ): bool {
		if ( $url === '' ) {
			return false;
		}
		return (bool) preg_match( '#^https?://#i', $url );
	}

	/**
	 * @param \WP_User|\WP_Error|\WP_Post|mixed $id_or_email
	 */
	private static function resolveUser( $id_or_email ): ?\WP_User {
		if ( is_numeric( $id_or_email ) ) {
			$u = get_user_by( 'id', (int) $id_or_email );
			return ( $u instanceof \WP_User ) ? $u : null;
		}
		if ( is_object( $id_or_email ) && isset( $id_or_email->ID ) && $id_or_email->ID > 0 ) {
			$u = get_user_by( 'id', (int) $id_or_email->ID );
			return ( $u instanceof \WP_User ) ? $u : null;
		}
		if ( is_string( $id_or_email ) && is_email( $id_or_email ) ) {
			$u = get_user_by( 'email', $id_or_email );
			return ( $u instanceof \WP_User ) ? $u : null;
		}
		if ( is_string( $id_or_email ) && $id_or_email !== '' && ! is_email( $id_or_email ) ) {
			$u = get_user_by( 'login', $id_or_email );
			return ( $u instanceof \WP_User ) ? $u : null;
		}
		return null;
	}
}
