<?php

namespace App\Command;

use App\Entity\Family;
use App\Entity\User;
use App\Repository\FamilyRepository;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
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\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

#[AsCommand(name: 'app:parent:create', description: 'Crée un compte parent sans inscription publique.')]
final class CreateParentCommand extends Command
{
    public function __construct(
        private readonly FamilyRepository $families,
        private readonly UserRepository $users,
        private readonly UserPasswordHasherInterface $hasher,
        private readonly EntityManagerInterface $entityManager,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('family-id', InputArgument::REQUIRED, 'Identifiant de la famille')
            ->addArgument('email', InputArgument::REQUIRED, 'Adresse email')
            ->addArgument('display-name', InputArgument::REQUIRED, 'Nom affiché');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $family = $this->families->find((int) $input->getArgument('family-id'));
        if (!$family instanceof Family) {
            $output->writeln('<error>Famille introuvable.</error>');

            return Command::INVALID;
        }

        $email = mb_strtolower(trim((string) $input->getArgument('email')));
        $displayName = trim((string) $input->getArgument('display-name'));
        if (false === filter_var($email, FILTER_VALIDATE_EMAIL) || '' === $displayName || mb_strlen($displayName) > 100) {
            $output->writeln('<error>Email ou nom affiché invalide.</error>');

            return Command::INVALID;
        }
        if (null !== $this->users->findOneBy(['email' => $email])) {
            $output->writeln('<error>Un compte utilise déjà cet email.</error>');

            return Command::FAILURE;
        }

        $question = new Question('Mot de passe : ');
        $question->setHidden(true);
        $question->setHiddenFallback(false);
        $password = (string) $this->getHelper('question')->ask($input, $output, $question);
        if (mb_strlen($password) < 12) {
            $output->writeln('<error>Le mot de passe doit contenir au moins 12 caractères.</error>');

            return Command::INVALID;
        }

        $user = new User($family, $email, $displayName);
        $user->setPassword($this->hasher->hashPassword($user, $password));
        $password = '';
        $this->entityManager->persist($user);
        $this->entityManager->flush();
        $output->writeln(sprintf('<info>Parent créé avec l’identifiant %d.</info>', $user->getId()));

        return Command::SUCCESS;
    }
}
