<?php
declare(strict_types=1);

namespace App\Command;

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;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;

#[AsCommand(
    name: 'app:mercure:publish',
    description: 'Publishes a test update to the Mercure hub.'
)]
final class MercurePublishCommand extends Command
{
    public function __construct(private readonly HubInterface $hub)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('topic', InputArgument::OPTIONAL, 'Topic URL to publish to', $_ENV['MERCURE_TOPIC_BASE'] . '/game/hub')
            ->addOption('type', null, InputOption::VALUE_REQUIRED, 'Update type (for clients to filter)', 'game.event')
            ->addOption('data', null, InputOption::VALUE_REQUIRED, 'JSON payload to send', '{"message":"Hello from Mercure!"}')
            ->addOption('private', null, InputOption::VALUE_NONE, 'Mark the update as private');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $topic = (string) $input->getArgument('topic');
        $type = (string) $input->getOption('type');
        $data = (string) $input->getOption('data');
        $isPrivate = (bool) $input->getOption('private');

        // Validate JSON
        $decoded = json_decode($data, true);
        if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
            $output->writeln('<error>Invalid JSON provided for --data.</error>');
            return Command::FAILURE;
        }

        $update = new Update(
            topics: $topic,
            data: json_encode([
                'type' => $type,
                'payload' => $decoded,
                'ts' => date('c'),
            ], JSON_THROW_ON_ERROR),
            private: $isPrivate
        );

        $this->hub->publish($update);

        $output->writeln('<info>Published update to topic:</info> ' . $topic);
        return Command::SUCCESS;
    }
}
