<?php

namespace App\Command;

use App\Entity\BilletOrder;
use App\Repository\BilletBuyerRepository;
use App\Service\AuditService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: 'app:orders:expire-pending',
    description: 'Cancel pending orders older than 30 minutes',
)]
class ExpirePendingOrdersCommand extends Command
{
    public function __construct(
        private EntityManagerInterface $em,
        private BilletBuyerRepository $buyerRepo,
        private AuditService $audit,
    ) {
        parent::__construct();
    }

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

        $threshold = new \DateTimeImmutable('-30 minutes');
        $orders = $this->buyerRepo->findExpiredPending($threshold);

        $count = \count($orders);

        if (0 === $count) {
            $io->success('No expired pending orders.');

            return Command::SUCCESS;
        }

        foreach ($orders as $order) {
            $order->setStatus('cancelled');

            $tickets = $this->em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
            foreach ($tickets as $ticket) {
                $ticket->setState(BilletOrder::STATE_INVALID);
            }

            foreach ($order->getItems() as $item) {
                $billet = $item->getBillet();
                if ($billet && null !== $billet->getQuantity()) {
                    $billet->setQuantity($billet->getQuantity() + $item->getQuantity());
                }
            }

            $this->audit->log('order_expired', 'BilletBuyer', $order->getId(), [
                'orderNumber' => $order->getOrderNumber(),
                'event' => $order->getEvent()->getTitle(),
            ]);
        }

        $this->em->flush();

        $io->success($count.' pending order(s) expired.');

        return Command::SUCCESS;
    }
}
