<?php

declare(strict_types=1);

namespace App\Administration\Application\Command\RemoveRole;

use App\Administration\Domain\Exception\UserNotFoundException;
use App\Administration\Domain\Model\User\Role;
use App\Administration\Domain\Model\User\User;
use App\Administration\Domain\Model\User\UserId;
use App\Administration\Domain\Repository\UserRepository;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use InvalidArgumentException;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler(bus: 'command.bus')]
final readonly class RemoveRoleHandler
{
    public function __construct(
        private UserRepository $userRepository,
        private Clock $clock,
    ) {
    }

    public function __invoke(RemoveRoleCommand $command): User
    {
        $userId = UserId::fromString($command->userId);
        $user = $this->userRepository->get($userId);

        if ($command->tenantId !== '' && !$user->tenantId->equals(TenantId::fromString($command->tenantId))) {
            throw UserNotFoundException::withId($userId);
        }

        $role = Role::tryFrom($command->role);
        if ($role === null) {
            throw new InvalidArgumentException("Rôle invalide : \"{$command->role}\".");
        }

        $user->retirerRole($role, $this->clock->now());

        $this->userRepository->save($user);

        return $user;
    }
}
