<?php
/**
 * Microsoft (Azure AD) OAuth Provider for Guard Dog Social Login.
 *
 * Implements the social provider interface for Microsoft account authentication.
 * Wraps the thenetworg/oauth2-azure package and normalizes user data from JWT claims.
 *
 * @package GuardDog
 * @since 1.9.30
 */

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

/**
 * Class Guard_Dog_Microsoft_Provider
 *
 * Microsoft OAuth 2.0 social login provider implementation.
 * Uses Azure AD v2.0 endpoints to support both personal Microsoft accounts
 * and organizational (work/school) accounts.
 *
 * @since 1.9.30
 */
class Guard_Dog_Microsoft_Provider implements Guard_Dog_Social_Provider_Interface {

    /**
     * Get the unique provider identifier.
     *
     * @since 1.9.30
     * @return string Provider identifier.
     */
    public function get_id(): string {
        return 'microsoft';
    }

    /**
     * Get the human-readable provider name.
     *
     * @since 1.9.30
     * @return string Translated provider display name.
     */
    public function get_name(): string {
        return __( 'Microsoft', 'guard-dog' );
    }

    /**
     * Get the Microsoft brand icon as an inline SVG string.
     *
     * Uses the official Microsoft four-square logo.
     *
     * @since 1.9.30
     * @return string SVG markup for the Microsoft brand icon.
     */
    public function get_icon_svg(): string {
        return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21" width="20" height="20">'
            . '<rect x="1" y="1" width="9" height="9" fill="#f25022"/>'
            . '<rect x="1" y="11" width="9" height="9" fill="#00a4ef"/>'
            . '<rect x="11" y="1" width="9" height="9" fill="#7fba00"/>'
            . '<rect x="11" y="11" width="9" height="9" fill="#ffb900"/>'
            . '</svg>';
    }

    /**
     * Get the Microsoft primary brand color.
     *
     * @since 1.9.30
     * @return string CSS hex color value.
     */
    public function get_color(): string {
        return '#00a4ef';
    }

    /**
     * Get the OAuth scopes required for Microsoft authentication.
     *
     * Requests OpenID Connect scopes for identity, email, and profile data.
     *
     * @since 1.9.30
     * @return array List of Microsoft OAuth scope strings.
     */
    public function get_scopes(): array {
        return array( 'openid', 'email', 'profile' );
    }

    /**
     * Create the League OAuth2 Azure provider instance.
     *
     * Uses Azure AD v2.0 endpoints with the 'common' tenant to support
     * both personal Microsoft accounts and organizational accounts.
     *
     * @since 1.9.30
     *
     * @param array $config {
     *     Provider configuration.
     *
     *     @type string $client_id     Azure Application (client) ID.
     *     @type string $client_secret Azure client secret.
     *     @type string $redirect_uri  OAuth callback URL.
     * }
     * @return \GuardDog\Vendor\League\OAuth2\Client\Provider\AbstractProvider Configured Azure provider.
     */
    public function create_league_provider( array $config ): \GuardDog\Vendor\League\OAuth2\Client\Provider\AbstractProvider {
        return new \GuardDog\Vendor\TheNetworg\OAuth2\Client\Provider\Azure(
            array(
                'clientId'                => $config['client_id'] ?? '',
                'clientSecret'            => $config['client_secret'] ?? '',
                'redirectUri'             => $config['redirect_uri'] ?? '',
                'defaultEndPointVersion'  => '2.0',
                'scope'                   => $this->get_scopes(),
            )
        );
    }

    /**
     * Normalize an Azure resource owner into a standard user data array.
     *
     * Maps Azure JWT claims to the common format:
     * - oid           -> provider_user_id
     * - email or upn  -> email
     * - name          -> name
     * - given_name    -> first_name
     * - family_name   -> last_name
     *
     * Note: Microsoft does not include avatar URLs in JWT claims.
     * Avatar would require a separate Microsoft Graph API call.
     *
     * @since 1.9.30
     *
     * @param \GuardDog\Vendor\League\OAuth2\Client\Provider\ResourceOwnerInterface $resource_owner The Azure user resource owner.
     * @return array Normalized user data array.
     */
    public function normalize_resource_owner( \GuardDog\Vendor\League\OAuth2\Client\Provider\ResourceOwnerInterface $resource_owner ): array {
        /** @var \GuardDog\Vendor\TheNetworg\OAuth2\Client\Provider\AzureResourceOwner $resource_owner */
        $data = $resource_owner->toArray();

        return array(
            'provider_user_id' => (string) ( $resource_owner->getId() ?? '' ),
            'email'            => $data['email'] ?? ( $data['upn'] ?? '' ),
            'email_verified'   => $data['email_verified'] ?? false,
            'name'             => $data['name'] ?? '',
            'first_name'       => $resource_owner->getFirstName() ?? '',
            'last_name'        => $resource_owner->getLastName() ?? '',
            'avatar_url'       => null,
        );
    }

    /**
     * Check if this provider has all required configuration.
     *
     * Microsoft requires a Client ID and Client Secret.
     *
     * @since 1.9.30
     * @return bool True if client_id and client_secret are both set.
     */
    public function is_configured(): bool {
        $client_id     = get_option( 'guard_dog_social_microsoft_client_id', '' );
        $client_secret = get_option( 'guard_dog_social_microsoft_client_secret', '' );

        return ! empty( $client_id ) && ! empty( $client_secret );
    }

    /**
     * Get the admin settings fields for Microsoft OAuth configuration.
     *
     * Defines the Application ID and Client Secret fields needed to configure
     * Microsoft OAuth in the Guard Dog admin settings.
     *
     * @since 1.9.30
     *
     * @return array List of settings field definitions.
     */
    public function get_settings_fields(): array {
        return array(
            array(
                'id'          => 'client_id',
                'label'       => __( 'Application (client) ID', 'guard-dog' ),
                'type'        => 'text',
                'required'    => true,
                'description' => __( 'From Azure Portal > App registrations > Your app > Overview.', 'guard-dog' ),
            ),
            array(
                'id'          => 'client_secret',
                'label'       => __( 'Client Secret', 'guard-dog' ),
                'type'        => 'password',
                'required'    => true,
                'description' => __( 'From Azure Portal > Certificates & secrets.', 'guard-dog' ),
            ),
        );
    }
}
