<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Command;

use CpCreation\VitiCore\Versioning\EcommerceVersionRecorder;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: 'viti-core:business-version:publish-due',
    description: 'Publie les versions metier planifiees dont la date est atteinte.'
)]
final class PublishDueBusinessVersionsCommand extends Command
{
    public function __construct(
        private readonly EcommerceVersionRecorder $ecommerceVersionRecorder,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Nombre maximal de versions a publier.', '100')
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Compte les versions eligibles sans ecrire en base.');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $limit = $this->parsePositiveInteger($input->getOption('limit'), $io);
        if (null === $limit) {
            return Command::INVALID;
        }

        $dryRun = (bool) $input->getOption('dry-run');
        $publishedCount = $this->ecommerceVersionRecorder->publishDueScheduledChanges(
            new \DateTimeImmutable(),
            $limit,
            $dryRun,
        );

        $io->definitionList(
            ['Dry run' => $dryRun ? 'oui' : 'non'],
            ['Limite' => (string) $limit],
            ['Versions traitees' => (string) $publishedCount],
        );

        $io->success(sprintf('%d version(s) metier planifiee(s) traitee(s).', $publishedCount));

        return Command::SUCCESS;
    }

    private function parsePositiveInteger(mixed $value, SymfonyStyle $io): ?int
    {
        if (!\is_scalar($value) && !$value instanceof \Stringable) {
            $io->error('L option --limit doit etre un entier positif.');

            return null;
        }

        $value = (string) $value;
        if (!ctype_digit($value) || (int) $value < 1) {
            $io->error('L option --limit doit etre un entier positif.');

            return null;
        }

        return (int) $value;
    }
}
