<?php

namespace App\Shared\Event\Command;

use Doctrine\DBAL\Connection;
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: 'app:events:prune', description: 'Delete published domain events older than a retention window.')]
class PruneDomainEventsCommand extends Command
{
    public function __construct(private readonly Connection $connection)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption('days', null, InputOption::VALUE_REQUIRED, 'Retention window in days', '180')
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Report without deleting');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io     = new SymfonyStyle($input, $output);
        $before = time() - max(1, (int) $input->getOption('days')) * 86400;

        $count = (int) $this->connection->fetchOne(
            'SELECT COUNT(*) FROM domain_events WHERE published_at IS NOT NULL AND occurred_at < ?',
            [$before],
        );

        if ($count === 0) {
            $io->success('رویداد قابل حذفی نیست.');

            return Command::SUCCESS;
        }

        if ($input->getOption('dry-run')) {
            $io->note(sprintf('%d رویداد حذف می‌شد.', $count));

            return Command::SUCCESS;
        }

        $this->connection->executeStatement(
            'DELETE FROM domain_events WHERE published_at IS NOT NULL AND occurred_at < ?',
            [$before],
        );

        $io->success(sprintf('%d رویداد حذف شد.', $count));

        return Command::SUCCESS;
    }
}
