<?php

namespace App\EventListener;

use App\Entity\Client;
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: Client::class)]
class ClientStatusNotifier
{
    private LoggerInterface $logger;

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

    public function postUpdate(Client $client, PostUpdateEventArgs $event): void
    {
        $em = $event->getObjectManager();
        $uow = $em->getUnitOfWork();
        $changeSet = $uow->getEntityChangeSet($client);

        if (!array_key_exists('status', $changeSet)) {
            return;
        }

        try {
            $this->notifyClientStatusChange($client);
        } catch (\Exception $e) {
            $this->logger->error('Error al notificar el cambio de estado de un cliente: ', [
                'client' => $client->getUuid(),
                'status' => $client->getStatus(),
                'error' => $e->getMessage(),
            ]);
        }
    }

    private function notifyClientStatusChange(Client $client): void
    {
        $data[] = [
            '@id' => '/clients/' . $client->getUuid(),
            'status' => $client->getStatus(),
        ];

        $update = new Update(
            'clients',
            json_encode($data)
        );
        $this->hub->publish($update);

        $this->logger->info('Evento Mercure disparado. Cambio en el estado de un cliente: ', [
            'client' => $client->getUuid(),
            'status' => $client->getStatus(),
        ]);
    }
}