<?php
/**
 * @author      Alex Bilbie <hello@alexbilbie.com>
 * @copyright   Copyright (c) Alex Bilbie
 * @license     http://mit-license.org/
 *
 * @link        https://github.com/thephpleague/oauth2-server
 */

namespace Docuform\Api\Authentication\Entities;

use Docuform\Api\Authentication\Repositories\UserRepository;
use Docuform\Api\UserType;
use Lcobucci\JWT\Encoding\ChainedFormatter;
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
use InvalidArgumentException;

trait AccessTokenTraitDfm
{
  use AccessTokenTrait;

  /**
   * @return \Lcobucci\JWT\Token
   * @throws \DI\DependencyException
   * @throws \DI\NotFoundException
   * @throws \Docuform\Database\DbException
   */
  private function convertToJWT()
  {
    $userType = $this->getUserType();

    $this->initJwtConfiguration();

    $defaultTimeZone = date_default_timezone_get();

    $dt = new \DateTimeImmutable();
    $iat= $dt->sub(new \DateInterval('PT5S'));

    $builder = $this->jwtConfiguration->builder(ChainedFormatter::withUnixTimestampDates())
    ->permittedFor($this->getClient()->getIdentifier())
    ->identifiedBy($this->getIdentifier())
    ->issuedAt($iat)
    //->canOnlyBeUsedAfter(new \DateTimeImmutable())
    ->expiresAt($this->getExpiryDateTime())
    ->relatedTo((string) $this->getUserIdentifier())
    ->withClaim('scopes', $this->getScopes())

    // Public claims:
    ->withClaim('zoneinfo', $defaultTimeZone)

    // Private claims:
    ->withClaim('apiver', (string)(int)(RESTAPI_VERSION))
    ->withClaim('tver', TOKEN_VERSION)
    ->withClaim('usertype', $userType);

    try
    {
      $token = $builder->getToken($this->jwtConfiguration->signer(), $this->jwtConfiguration->signingKey());
    }
    catch (InvalidArgumentException $e)
    { // Invalid passphrase?
      // No Exception possible here!
      $token = '';
    }

    return $token;
  }


  /**
   * @return mixed
   */
  private function getUserType(): mixed
  {
    /** @var string $uuid */
    $uuid = $this->getUserIdentifier();

    $userType = UserType::USERTYPE_UNKNOWN;

    if (!empty($uuid))
    {
      $userrepo = new UserRepository($this->m_container);

      $user = $userrepo->getUserEntityByUuid($uuid);

      if (!empty($user))
      {
        $userType = $user->userType;
      }
    }

    return $userType;
  }
}