<?php

namespace Drupal\miniorange_webauthn\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Utility\Error;
use Drupal\miniorange_webauthn\Entity\MoWebauthnCredential;
use Drupal\miniorange_webauthn\MoCredOptBuilder\MoProfileBasedReqOptBuilderInterface;
use Drupal\miniorange_webauthn\MoDto\MoPubKeyCredAssertionRespDto;
use Drupal\miniorange_webauthn\MoProtector\MoHandler\MoFailureHandlerInterface;
use Drupal\user\Entity\User;
use ParagonIE\ConstantTime\Base64UrlSafe;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Webauthn\PublicKeyCredentialRequestOptions;
use Webauthn\PublicKeyCredentialRpEntity;
use Symfony\Component\HttpFoundation\JsonResponse;

class MoAssertionOptionController extends ControllerBase
{

  public function __construct(
    private MoProfileBasedReqOptBuilderInterface $optionsBuilder,
    private readonly PrivateTempStoreFactory $tempStore,
    private readonly MoFailureHandlerInterface $moFailureHandler
  ) {
  }

  public static function create(ContainerInterface $container)
  {
    return new static(
      $container->get('mo_webauthn.profile_based_req_opt_builder'),
      $container->get('tempstore.private'),
      $container->get('mo_webauthn.failure_handler')
    );
  }

  /**
   * @throws InvalidDataException
   * @throws \JsonException
   */
  public function __invoke(Request $request) {
    try {
      $rpEntity = new PublicKeyCredentialRpEntity(
        $this->config('system.site')->get('name'), // Site name
        \Drupal::request()->getHost() // Domain (e.g., "example.com")
      );
      $challenge = rand(1, 128);
      $tempStore = $this->tempStore->get('miniorange_webauthn');
      $tempStore->set('mo_webauthn_assertion_options', base64_encode($challenge));


      $options = new PublicKeyCredentialRequestOptions(
        challenge: $challenge,
        timeout: 60000, // Timeout (ms)
        rpId: $rpEntity->id, // RP ID
        allowCredentials: [], // Optional: Filter credentials
        userVerification: PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_DISCOURAGED // User verification (use 'required' for stricter auth)
      );
      return new JsonResponse($options);
    } catch (\Exception $exception){
      Error::logException($this->getLogger('miniorange_webauthn'), $exception);
      return new JsonResponse([]);
    }
  }
}
