<?php

declare(strict_types=1);

namespace App\SuperAdmin\Infrastructure\Security;

use App\SuperAdmin\Domain\Repository\SuperAdminRepository;
use InvalidArgumentException;
use Override;
use Symfony\Component\Security\Core\Exception\UserNotFoundException as SymfonyUserNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

/**
 * User provider for Super Admin authentication.
 *
 * Separate from the regular DatabaseUserProvider because Super Admins
 * live in the master database and are not scoped by tenant.
 *
 * @implements UserProviderInterface<SecuritySuperAdmin>
 */
final readonly class SuperAdminUserProvider implements UserProviderInterface
{
    public function __construct(
        private SuperAdminRepository $superAdminRepository,
    ) {
    }

    #[Override]
    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        $superAdmin = $this->superAdminRepository->findByEmail($identifier);

        if ($superAdmin === null) {
            throw new SymfonyUserNotFoundException();
        }

        if (!$superAdmin->peutSeConnecter()) {
            throw new SymfonyUserNotFoundException();
        }

        /** @var non-empty-string $email */
        $email = $superAdmin->email;

        return new SecuritySuperAdmin(
            superAdminId: $superAdmin->id,
            email: $email,
            hashedPassword: $superAdmin->hashedPassword,
        );
    }

    #[Override]
    public function refreshUser(UserInterface $user): UserInterface
    {
        if (!$user instanceof SecuritySuperAdmin) {
            throw new InvalidArgumentException('Expected instance of ' . SecuritySuperAdmin::class);
        }

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

    #[Override]
    public function supportsClass(string $class): bool
    {
        return $class === SecuritySuperAdmin::class;
    }
}
