<?php

namespace HelpGent\App\Providers;

defined( 'ABSPATH' ) || exit;

use HelpGent\WpMVC\Contracts\Provider;
use HelpGent\App\DTO\UserDTO;
use HelpGent\App\Repositories\UserRepository;
use HelpGent\App\Models\HelpGentUser as HelpGentUserModel;
use WP_User;
use Exception;

class UserServiceProvider implements Provider {
    public function boot() {
        add_action( 'wp_login', [ $this, 'action_wp_login' ], 10, 2 );
        add_filter( 'get_avatar_url', [ $this, 'filter_get_avatar_url' ], 10, 2 );
        add_action( 'helpgent_maybe_create_user', [$this, 'maybe_add_user'] );
        add_action( 'profile_update', [ $this, 'update_user_profile' ], 10, 3 );
    }

    /**
     * Filters the avatar URL.
     *
     * @param string $url         The URL of the avatar.
     * @param mixed  $user The avatar to retrieve. Accepts a user ID, Gravatar MD5 hash, user email, WP_User object, WP_Post object, or WP_Comment object.
     * @return string The URL of the avatar.
     */
    public function filter_get_avatar_url( string $url, $user ) : string {
        /**
         * if user variable value is a user id.
         */
        if ( is_int( $user ) ) {
            $attachment_id = get_user_meta( $user, 'helpgent_avatar', true );
            /**
             * if user variable value is a user email.
             */
        } elseif ( is_string( $user ) ) {
            $user_object = get_user_by( 'email', $user );
            if ( $user_object instanceof \WP_User ) {
                $attachment_id = get_user_meta( $user_object->ID, 'helpgent_avatar', true );
            }
            /**
             * f user variable value is a wp user object.
             */
        } elseif ( $user instanceof \WP_User ) {
            $attachment_id = get_user_meta( $user->ID, 'helpgent_avatar', true );
        }

        if ( empty( $attachment_id ) ) {
            return $url;
        }

        $avatar_url = wp_get_attachment_url( $attachment_id );

        if ( ! $avatar_url ) {
            return $url;
        }

        return $avatar_url;
    }

    /**
     * Fires after the user has successfully logged in.
     *
     * @param string   $user_login Username.
     * @param \WP_User $user       WP_User object of the logged-in user.
     */
    public function action_wp_login( string $user_login, \WP_User $user ) : void {
        delete_user_meta( $user->ID, 'helpgent_delete_scheduled' );
    }

    public function maybe_add_user() {
        if ( ! is_user_logged_in() ) {
            return;
        }

        $current_user = wp_get_current_user();

        /**
         * @var UserRepository $repo
         */
        $repo    = helpgent_singleton( UserRepository::class );
        $hg_user = $repo->get_by( 'registered_id', $current_user->data->ID );

        if ( $hg_user ) {
            return;
        }

        $dto = ( new UserDTO() )
            ->set_email( $current_user->data->user_email )
            ->set_name( $current_user->data->display_name )
            ->set_registered_id( $current_user->data->ID )
            ->set_token( helpgent_generate_token() )
            ->set_token_expires_at( helpgent_now()->add_days( 365 ) );
        
        try {
            $repo->create( $dto );
        } catch ( Exception $e ) {
        }
    }

    public function update_user_profile( int $user_id, WP_User $old_user_data, array $userdata ): void {
        $helpgent_user = HelpGentUserModel::query()->where( 'registered_id', $user_id )->first();

        if ( ! $helpgent_user ) {
            return;
        }

        $update_data = [];

        if ( $helpgent_user->name != $userdata['display_name'] ) {
            $update_data['name'] = $userdata['display_name'];
        }

        if ( $helpgent_user->email != $userdata['user_email'] ) {
            $update_data['email'] = $userdata['user_email'];
        }

        if ( empty( $update_data ) ) {
            return;
        }

        HelpGentUserModel::query()->where( 'id', $helpgent_user->id )->update( $update_data );
    }
}