<?php

namespace App\Policy\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;

/**
 * اجراهای آزمایشیِ قدیمی ارزشی ندارند — جز **آخرینِ هر (قانون، نسخه)**.
 *
 * آن یکی حذف‌نشدنی است چون `activate` به وجودش وابسته است: پاک کردنش یعنی قانونی که
 * دیروز آزمایش شده امروز دیگر فعال‌شدنی نیست، بدون هیچ توضیحی برای کاربر.
 */
#[AsCommand(name: 'app:policy:prune-simulations', description: 'Delete old policy simulation runs, keeping the latest per policy version.')]
class PruneSimulationsCommand extends Command
{
    public function __construct(private readonly Connection $connection)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption('days', null, InputOption::VALUE_REQUIRED, 'Delete runs older than this many days', '90')
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Report what would be deleted without deleting');
    }

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

        $sql = <<<'SQL'
            SELECT r.id
            FROM policy_simulation_runs r
            WHERE r.created_at < :before
              AND r.id NOT IN (
                  SELECT keep_id FROM (
                      SELECT MAX(id) AS keep_id
                      FROM policy_simulation_runs
                      GROUP BY policy_id, policy_version
                  ) AS keepers
              )
            SQL;

        $ids = $this->connection->fetchFirstColumn($sql, ['before' => $before]);

        if ($ids === []) {
            $io->success('هیچ اجرای آزمایشیِ قابل حذفی نیست.');

            return Command::SUCCESS;
        }

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

            return Command::SUCCESS;
        }

        $this->connection->executeStatement(
            'DELETE FROM policy_simulation_runs WHERE id IN (:ids)',
            ['ids' => $ids],
            ['ids' => \Doctrine\DBAL\ArrayParameterType::INTEGER],
        );

        $io->success(sprintf('%d اجرای آزمایشی حذف شد.', count($ids)));

        return Command::SUCCESS;
    }
}
