<?php

declare(strict_types=1);

namespace App\Command;

use App\Entity\IngestJob;
use App\Service\IngestOrchestrator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'mto:agent:ingest:run')]
final class IngestRunJobCommand extends Command
{
    public function __construct(
        private readonly IngestOrchestrator $orchestrator,
        private readonly EntityManagerInterface $em,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('jobId', InputArgument::REQUIRED, 'UUID of IngestJob')
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Run without executing heavy operations');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $jobId = (string) $input->getArgument('jobId');
        $dryRun = (bool) $input->getOption('dry-run');

        /** @var IngestJob|null $job */
        $job = $this->em->getRepository(IngestJob::class)->find($jobId);

        if (!$job) {
            $output->writeln('<error>IngestJob not found.</error>');
            return Command::FAILURE;
        }

        // Idempotenz: Bereits abgeschlossene Jobs nicht erneut ausführen
        if (in_array($job->getStatus(), [
            IngestJob::STATUS_COMPLETED,
            IngestJob::STATUS_FAILED,
            IngestJob::STATUS_ABORTED,
        ], true)) {
            $output->writeln('<info>Job already finished.</info>');
            return Command::SUCCESS;
        }

        try {
            $output->writeln(sprintf(
                '<info>Running ingest job %s (type: %s)...</info>',
                (string) $job->getId(),
                $job->getType()
            ));

            $this->orchestrator->runExistingJob($job, $dryRun);

            $output->writeln('<info>Job completed successfully.</info>');

            return Command::SUCCESS;

        } catch (\Throwable $e) {

            // Wichtig: Status wird im Orchestrator gesetzt
            $output->writeln(sprintf(
                '<error>Job failed: %s</error>',
                $e->getMessage()
            ));

            return Command::FAILURE;
        }
    }
}
