<?php

namespace App\EventListener;

use App\Entity\Client;
use App\Entity\Trace;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\ORM\Events;
use Doctrine\ORM\Event\PostUpdateEventArgs;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;

#[AsEntityListener(event: Events::postUpdate, method: 'postUpdate', entity: Trace::class)]
class TraceStatusProgressNotifier
{
    private LoggerInterface $logger;

    public function __construct(
        LoggerInterface $logger,
        private readonly HubInterface $hub
    )
    {
        $this->logger = $logger;
    }

    public function postUpdate(Trace $trace, PostUpdateEventArgs $event): void
    {
        try {
            $this->notifyTraceStatusProgressChange($trace);
        } catch (\Exception $e) {
            $this->logger->error('Error al notificar el cambio de estado de una traza/log: ', [
                'client' => $trace->getUuid(),
                'status' => $trace->getStatus(),
                'progress' => $trace->getProgress(),
                'error' => $e->getMessage(),
            ]);
        }
    }

    private function notifyTraceStatusProgressChange(Trace $trace): void
    {
        $update = new Update(
            'traces',
            json_encode(['@id' => '/traces/' . $trace->getUuid(), 'status' => $trace->getStatus(), 'progress' => $trace->getProgress()])
        );
        $this->hub->publish($update);

        $this->logger->info('Evento Mercure disparado. Cambio en el estado de una traza/log: ', [
            'client' => $trace->getUuid(),
            'status' => $trace->getStatus(),
            'progress' => $trace->getProgress(),
        ]);
    }
}