<?php
/**
 * Shared bootstrap for Google / Facebook / GitHub sign-in modules.
 *
 * @package WP_PowerSuite\OAuth
 */

namespace WP_PowerSuite\OAuth;

use WP_PowerSuite\OAuth\UI\ButtonStyleHelper;
use WP_PowerSuite\OAuth\UI\SocialLoginErrorHandler;
use WP_PowerSuite\OAuth\UI\SocialLoginFormGroup;
use WP_PowerSuite\OAuth\UI\SocialLoginStyles;

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

trait SocialSignInModuleTrait {

	abstract protected function getSocialProviderSlug(): string;

	abstract protected function getSocialProvider(): object;

	abstract protected function getSocialLegacyShortcodeTag(): string;

	/**
	 * @return array<string, mixed>
	 */
	abstract protected function getSocialProviderSettings(): array;

	protected function bootSocialSignInModule( bool $woo_login ): void {
		$provider = $this->getSocialProvider();
		if ( ! $provider instanceof AbstractProvider ) {
			return;
		}

		OAuthManager::register( $provider );
		SocialLoginErrorHandler::register();
		SocialLoginStyles::registerProvider( $this->getSocialProviderSlug() );
		SocialLoginStyles::ensureLoginPageStyles();
		SocialLoginFormGroup::register(
			$this->getSocialProviderSlug(),
			function ( string $context ) {
				return $this->buildSocialEmbedButton( $context );
			},
			class_exists( 'WooCommerce' ) && $woo_login
		);
		add_shortcode( $this->getSocialLegacyShortcodeTag(), [ $this, 'shortcodeLegacy' ] );
		SocialShortcodeService::register(
			$this->getSocialProviderSlug(),
			function ( array $opt ) {
				$p = $this->getSocialProvider();
				return ( $p instanceof AbstractProvider ) ? $p->renderButtonMarkup( $opt ) : '';
			}
		);
		if ( class_exists( 'WooCommerce' ) && $woo_login ) {
			SocialLoginStyles::ensureWooCommerceButtonStyles();
		}
		SocialLoginStyles::ensureShortcodeStyles();
	}

	/**
	 * @return ?array{html: string, icon_only: bool, row_inline: bool}
	 */
	protected function buildSocialEmbedButton( string $context ): ?array {
		$provider = $this->getSocialProvider();
		if ( ! $provider instanceof AbstractProvider || ! method_exists( $provider, 'renderButtonMarkup' ) ) {
			return null;
		}
		$redirect = '';
		if ( SocialLoginFormGroup::CONTEXT_WOO === $context ) {
			if ( function_exists( 'is_account_page' ) && is_account_page() && function_exists( 'wc_get_page_permalink' ) ) {
				$redirect = (string) wc_get_page_permalink( 'myaccount' );
			} elseif ( function_exists( 'is_checkout' ) && is_checkout() && function_exists( 'wc_get_checkout_url' ) ) {
				$redirect = (string) wc_get_checkout_url();
			}
		} else {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$redirect = isset( $_GET['redirect_to'] ) ? esc_url_raw( wp_unslash( (string) $_GET['redirect_to'] ) ) : '';
		}
		$s    = $this->getSocialProviderSettings();
		$disp = ButtonStyleHelper::sanitizeDisplay( (string) ( $s['button_display'] ?? 'label' ) );
		$html = $provider->renderButtonMarkup(
			[
				'redirect'  => $redirect,
				'type'      => 'button',
				'size'      => 'medium',
				'show_text' => true,
			]
		);
		if ( $html === '' ) {
			return null;
		}
		$icon_only  = ( 'icon' === $disp );
		$row_inline = $icon_only || ( ( 'label' === $disp ) && ! empty( $s['button_label_inline'] ) );
		return [
			'html'       => $html,
			'icon_only'  => $icon_only,
			'row_inline' => $row_inline,
		];
	}

	/**
	 * @param array<string, string>|\string $atts
	 */
	public function shortcodeLegacy( $atts ): string {
		$tag  = $this->getSocialLegacyShortcodeTag();
		$atts = shortcode_atts(
			[
				'redirect'     => '',
				'label'        => '',
				'style'        => '',
				'width'        => '',
				'width_custom' => '',
				'align'        => '',
				'display'      => '',
			],
			is_array( $atts ) ? $atts : [],
			$tag
		);
		$provider = $this->getSocialProvider();
		if ( ! $provider instanceof AbstractProvider ) {
			return '';
		}
		$args = [
			'redirect'     => (string) $atts['redirect'],
			'label'        => (string) $atts['label'],
			'style'        => (string) $atts['style'],
			'width'        => (string) $atts['width'],
			'width_custom' => (string) $atts['width_custom'],
			'align'        => (string) $atts['align'],
			'display'      => (string) $atts['display'],
			'type'         => 'button',
			'size'         => 'medium',
			'show_text'    => true,
		];
		if ( (string) $atts['display'] !== '' && 'icon' === ButtonStyleHelper::sanitizeDisplay( (string) $atts['display'] ) ) {
			$args['type']      = 'icon';
			$args['show_text'] = false;
		}
		return $provider->renderButtonMarkup( $args );
	}
}
