<?php

namespace Trainingssystem\Module\App\RestHandler;

use Lcobucci\JWT\Configuration;
use Trainingssystem\Module\App\Exception\AuthException;

class IssueJwtRestHandler
{
    private Configuration $jwtConfiguration;

    public function __construct(Configuration $jwtConfiguration)
    {
        $this->jwtConfiguration = $jwtConfiguration;
    }

    /**
     * @param \WP_REST_Request $request
     * @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response
     */
    public function handle(\WP_REST_Request $request)
    {
        $username = $request->get_param('username');
        $password = $request->get_param('password');

        if (!is_string($username) || !is_string($password)) {
            throw new AuthException('No Username or Password given.');
        }

        $user = wp_authenticate_username_password(
            wp_authenticate_email_password(
                null,
                $username,
                $password
            ),
            $username,
            $password
        );

        if (!$user instanceof \WP_User) {
            return rest_ensure_response($user);
        }

        $now = new \DateTimeImmutable();

        $token = $this->jwtConfiguration->builder()
                                        ->issuedBy(get_site_url())
                                        ->permittedFor(get_site_url())
                                        ->identifiedBy(microtime())
                                        ->issuedAt($now)
                                        ->expiresAt($now->modify('+1 month'))
                                        ->withClaim('uid', $user->ID)
                                        ->withHeader('username', $username)
                                        ->getToken(
                                            $this->jwtConfiguration->signer(),
                                            $this->jwtConfiguration->signingKey()
                                        );

        $response = [
            'username' => $user->user_login,
            'email' => $user->user_email,
            'displayname' => $user->display_name,
            'jwt' => $token->toString(),
        ];

        return rest_ensure_response($response);
    }
}
