<?php

namespace App\User\Framework\Security;

use App\User\Framework\Entity\User;
use App\User\Framework\Repository\UserRepository;
use Drenso\OidcBundle\Exception\OidcException;
use Drenso\OidcBundle\Model\OidcTokens;
use Drenso\OidcBundle\Model\OidcUserData;
use Drenso\OidcBundle\Security\UserProvider\OidcUserProviderInterface;
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\OidcUser;
use Symfony\Component\Security\Core\User\UserInterface;

class OidcUserProvider implements OidcUserProviderInterface
{
    public function __construct(
        private readonly UserRepository $userRepository,
    ) {}

    public function ensureUserExists(string $userIdentifier, OidcUserData $userData, OidcTokens $tokens): void
    {
        $user = $this->userRepository->findOneBy(['email' => $userIdentifier]);

        if (null === $user) {
            $user = new User()
                ->setEmail(!empty($userData->getEmail()) ? $userData->getEmail() : $userData->getSub())
                ->setName(!empty($userData->getFullName()) ? $userData->getFullName() : $userData->getGivenName())
                ->setPassword('n/a')
                ;
            $this->userRepository->getEntityManager()->persist($user);
            $this->userRepository->getEntityManager()->flush();
        }
    }

    public function loadOidcUser(string $userIdentifier): UserInterface
    {
        return $this->userRepository->findOneBy(['email' => $userIdentifier]);
    }

    public function refreshUser(UserInterface $user): UserInterface
    {
        return $this->userRepository->findOneBy(['email' => $user->getUserIdentifier()]);
    }

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

    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        return $this->userRepository->findOneBy(['email' => $identifier]);
    }
}
