<?php

declare(strict_types=1);

namespace App\Security;

use App\Entity\Profile;
use App\Repository\ProfileRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;

final class SessionProfileAuthenticator extends AbstractAuthenticator
{
    public function __construct(
        private readonly ProfileRepository $profiles,
    ) {}

    public function supports(Request $request): ?bool
    {
        if (!$request->hasSession()) {
            return false;
        }

        return $request->getSession()->has('profileId');
    }

    public function authenticate(Request $request): Passport
    {
        $profileId = $request->getSession()->get('profileId');

        return new SelfValidatingPassport(
            new UserBadge($profileId, function (string $id): Profile {
                $profile = $this->profiles->find($id);

                if (!$profile || !$profile->isActive()) {
                    throw new CustomUserMessageAuthenticationException('Profil introuvable ou inactif.');
                }

                return $profile;
            })
        );
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        // Let the request continue normally
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {
        return new JsonResponse(
            ['message' => $exception->getMessageKey()],
            JsonResponse::HTTP_UNAUTHORIZED,
        );
    }
}
