<?php

declare(strict_types=1);

namespace App\Module\Core\Infrastructure\Console;

use App\Module\Core\Domain\Entity\User;
use App\Module\Core\Domain\Repository\RoleRepositoryInterface;
use App\Module\Core\Domain\Repository\UserRepositoryInterface;
use App\Module\Core\Domain\Security\SystemRoles;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

#[AsCommand(
    name: 'app:create-user',
    description: 'Cree un utilisateur rattache au role systeme admin ou user.',
)]
final class CreateUserCommand extends Command
{
    public function __construct(
        private readonly UserRepositoryInterface $userRepository,
        private readonly UserPasswordHasherInterface $passwordHasher,
        private readonly RoleRepositoryInterface $roleRepository,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('username', InputArgument::REQUIRED, 'Nom d\'utilisateur')
            ->addArgument('password', InputArgument::REQUIRED, 'Mot de passe en clair')
            ->addOption('admin', null, InputOption::VALUE_NONE, 'Rattache au role systeme admin + active is_admin')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $username      = $input->getArgument('username');
        $plainPassword = $input->getArgument('password');
        $isAdmin       = (bool) $input->getOption('admin');

        $roleCode = $isAdmin ? SystemRoles::ADMIN_CODE : SystemRoles::USER_CODE;
        $role     = $this->roleRepository->findByCode($roleCode);

        if (null === $role) {
            $io->error(sprintf(
                'Le role systeme "%s" est introuvable. Lance "bin/console doctrine:migrations:migrate" pour le seeder.',
                $roleCode,
            ));

            return Command::FAILURE;
        }

        $user = new User();
        $user->setUsername($username);
        $user->setPassword($this->passwordHasher->hashPassword($user, $plainPassword));
        $user->setIsAdmin($isAdmin);
        $user->addRbacRole($role);

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

        $io->success(sprintf(
            'Utilisateur "%s" cree, rattache au role systeme "%s"%s.',
            $username,
            $roleCode,
            $isAdmin ? ' (bypass is_admin actif)' : '',
        ));

        return Command::SUCCESS;
    }
}
