<?php

namespace AutoAdmin\Bundle\Admin\Security;

use AutoAdmin\Bundle\Admin\Model\AdministratorInterface;
use AutoAdmin\Bundle\Content\Site\SiteContextHelper;
use Doctrine\ORM\EntityManagerInterface;
use ReflectionClass;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class AdministratorProvider implements UserProviderInterface
{
    public function __construct(
        protected EntityManagerInterface $em,
        private readonly SiteContextHelper $siteContextHelper,
    ) {
    }

    public function refreshUser(UserInterface $user): UserInterface
    {
        if (!$user instanceof AdministratorInterface) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }

        return $this->loadUserByIdentifier($user->getUserIdentifier());
    }

    public function supportsClass($class): bool
    {
        $refl = new ReflectionClass($class);

        return AdministratorInterface::class === $class || $refl->isSubclassOf(AdministratorInterface::class);
    }

    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        $repo = $this->em->getRepository(AdministratorInterface::class);

        $administrator = $repo->findOneBy(['username' => $identifier]);
        if (empty($administrator)) {
            $administrator = $repo->findOneBy(['email' => $identifier]);
        }

        if (
            $administrator
            && in_array($this->siteContextHelper->getSite(), $administrator->getAdministratorSites()->toArray())
        ) {
            return $administrator;
        }

        throw new UserNotFoundException();
    }
}
