<?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\AdminBundle\Components;

use Contao\CoreBundle\Repository\WebauthnCredentialRepository;
use Ferienpass\CoreBundle\Entity\User;
use Ferienpass\CoreBundle\Repository\WebauthnUserEntityRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;

/**
 * Renders the two account-level login-method toggles on /admin/sicherheit:
 *   - "Remove password" — only available when the user has ≥1 passkey
 *   - "Disable magic links for my account" — toggle, hidden when the global
 *     `ferienpass_admin.enable_admin_magic_links` flag is FALSE (the default)
 *     AND the current user is ROLE_ADMIN (since the per-user toggle is moot
 *     then — admins can't use magic links unless the operator opts in).
 *     ROLE_HOST users see the toggle regardless — the global flag doesn't
 *     affect them.
 */
#[AsTwigComponent]
final class LoginMethods extends AbstractController
{
    public function __construct(
        private readonly WebauthnUserEntityRepository $userEntities,
        #[Autowire(service: 'contao.repository.webauthn_credential')]
        private readonly WebauthnCredentialRepository $credentials,
        #[Autowire('%ferienpass_admin.enable_admin_magic_links%')]
        private readonly bool $enableAdminMagicLinks,
        private readonly Security $security,
    ) {
    }

    #[ExposeInTemplate]
    public function hasPassword(): bool
    {
        $user = $this->currentUser();

        return $user instanceof User && null !== $user->getPassword();
    }

    #[ExposeInTemplate]
    public function passkeyCount(): int
    {
        $user = $this->currentUser();
        if (!$user instanceof User) {
            return 0;
        }

        $entity = $this->userEntities->findOneByUsername($user->getUsername());

        return null !== $entity ? \count($this->credentials->findAllForUserEntity($entity)) : 0;
    }

    #[ExposeInTemplate]
    public function magicLinksDisabledByUser(): bool
    {
        $user = $this->currentUser();

        return $user instanceof User && $user->isMagicLinksDisabled();
    }

    /**
     * Whether magic links are unavailable for the current user because of the
     * global flag — true only when the flag is OFF (default) AND the user
     * holds ROLE_ADMIN (which via the role hierarchy includes
     * ROLE_SUPER_ADMIN).
     */
    #[ExposeInTemplate]
    public function magicLinksUnavailableForMe(): bool
    {
        $user = $this->currentUser();
        if (!$user instanceof User) {
            return false;
        }

        return !$this->enableAdminMagicLinks && $this->security->isGranted('ROLE_ADMIN', $user);
    }

    private function currentUser(): ?User
    {
        $user = $this->getUser();

        return $user instanceof User ? $user : null;
    }
}
