<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Security\UserProvider;

use Chill\MainBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NoResultException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserProvider implements UserProviderInterface
{
    public function __construct(protected EntityManagerInterface $em) {}

    public function loadUserByUsername($username): UserInterface
    {
        try {
            $user = $this->em->createQuery(sprintf(
                'SELECT u FROM %s u '
                    .'WHERE u.usernameCanonical = UNACCENT(LOWER(:pattern)) '
                    .'OR '
                    .'u.emailCanonical = UNACCENT(LOWER(:pattern))',
                User::class
            ))
                ->setParameter('pattern', $username)
                ->getSingleResult();
        } catch (NoResultException $e) {
            throw new \Symfony\Component\Security\Core\Exception\UserNotFoundException('Bad credentials.', 0, $e);
        }

        return $user;
    }

    public function refreshUser(UserInterface $user): UserInterface
    {
        if (!$user instanceof User) {
            throw new UnsupportedUserException('Unsupported user class: cannot reload this user');
        }

        $reloadedUser = $this->em->getRepository(User::class)->find($user->getId());

        if (null === $reloadedUser) {
            throw new \Symfony\Component\Security\Core\Exception\UserNotFoundException(sprintf('User with ID "%s" could not be reloaded.', $user->getId()));
        }

        return $reloadedUser;
    }

    public function supportsClass($class): bool
    {
        return User::class === $class;
    }
}
