<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\Security;

use Contao\CoreBundle\Repository\WebauthnCredentialRepository;
use Ferienpass\CoreBundle\Entity\User;
use Ferienpass\CoreBundle\Repository\WebauthnUserEntityRepository;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Tells whether a user can actually sign in with what they have configured.
 *
 * A member who registered with a passkey has no password; if they never
 * completed the passkey ceremony (e.g. activated the account from the e-mail on
 * another device), they would be left without any way to log in. This service
 * detects that state so the onboarding can force the passkey setup.
 */
final class PasskeyRequirement
{
    public function __construct(
        private readonly WebauthnUserEntityRepository $userEntities,
        #[Autowire(service: 'contao.repository.webauthn_credential')]
        private readonly WebauthnCredentialRepository $credentials,
    ) {
    }

    public function hasPasskey(User $user): bool
    {
        $userEntity = $this->userEntities->findOneByUsername($user->getUsername());
        if (null === $userEntity) {
            return false;
        }

        return [] !== $this->credentials->findAllForUserEntity($userEntity);
    }

    public function needsPasskey(User $user): bool
    {
        return null === $user->getPassword() && !$this->hasPasskey($user);
    }
}
