<?php

namespace Comitium5\DesignerBundle\Command\RabbitMqConsumers;

use Comitium5\DesignerBundle\Entity\Page;
use Comitium5\DesignerBundle\Factory\Page\DesignerPageFactory;
use Comitium5\DesignerBundle\UseCase\Page\CreatePageUseCase;
use Comitium5\DesignerBundle\ValueObjects\PageMessageObject;
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

/**
 * Class PageCreatedConsumerCommand
 *
 * @author Oscar Jimenez <oscarjg19.developer@gmail.com>
 * @package Comitium5\DesignerBundle\Command\RabbitMqConsumers
 */
class PageCreatedConsumerCommand extends AbstractRabbitMqConsumerCommand implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    /**
     * @return string
     */
    protected function commandName(): string
    {
        return 'comitium:designer:consumer:page:created';
    }

    /**
     * @return string
     */
    protected function commandDescription(): string
    {
        return 'RabbitMQ consumer which create a queue to consume created pages';
    }

    /**
     * @param OutputInterface $output
     * @param int $maxMessages
     *
     * @return \Closure
     */
    protected function getClosure(OutputInterface $output, int $maxMessages): \Closure
    {
        return function (AMQPMessage $msg) use ($output, $maxMessages) {
            /**
             * @var AMQPChannel $channel
             */
            $channel     = $msg->getChannel();
            $deliveryTag = $msg->getDeliveryTag();

            try {
                $output->writeln(
                    sprintf('[x] Received: %s', $msg->body),
                    OutputInterface::VERBOSITY_VERBOSE
                );

                $pageMessage = new PageMessageObject($msg->body);

                $useCase = new CreatePageUseCase(
                    $this
                        ->container
                        ->get('doctrine')
                        ->getManager()
                        ->getRepository(Page::class),
                    new DesignerPageFactory()
                );

                $useCase($pageMessage->getId());

                $channel->basic_ack($deliveryTag);

                $output->writeln(
                    sprintf('Done - ack with tag %s', $deliveryTag),
                    OutputInterface::VERBOSITY_VERBOSE
                );

                $this->handleLimitMessages($output, $maxMessages);
            } catch (\Exception $e) {
                $channel->basic_reject($deliveryTag, false);

                $output->writeln(
                    sprintf('An error has been produced: %s', $e->getMessage()),
                    OutputInterface::VERBOSITY_VERBOSE
                );
            }
        };
    }
}