<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Serializer\Normalizer;

use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Serializer\Normalizer\UserNormalizer;
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Workflow\Registry;

class WorkflowNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;

    private const IGNORE_ENTITY_WORKFLOW = 'ignore:entity_workflow';

    public function __construct(private readonly Registry $registry, private readonly MetadataExtractor $metadataExtractor) {}

    /**
     * @param EntityWorkflow $object
     *
     * @return array|\ArrayObject|bool|float|int|string|void|null
     *
     * @throws ExceptionInterface
     */
    public function normalize($object, ?string $format = null, array $context = []): array
    {
        $data = $this->normalizer->normalize($object, $format, array_merge(
            $context,
            [self::IGNORE_ENTITY_WORKFLOW => spl_object_hash($object)]
        ));

        $workflow = $this->registry->get($object, $object->getWorkflowName());

        $data['workflow'] = $this->metadataExtractor->buildArrayPresentationForWorkflow($workflow);
        $data['current_place'] = $this->metadataExtractor->buildArrayPresentationForPlace($object);
        $data['current_place_at'] = $this->normalizer->normalize($object->getCurrentStepCreatedAt(), 'json', ['groups' => ['read']]);
        $data['current_place_by'] = $this->normalizer->normalize($object->getCurrentStepCreatedBy(), 'json', ['groups' => ['read'], UserNormalizer::AT_DATE => $object->getCurrentStepCreatedAt()]);

        return $data;
    }

    public function supportsNormalization($data, ?string $format = null, array $context = []): bool
    {
        return 'json' === $format
            && $data instanceof EntityWorkflow
            && !\array_key_exists(self::IGNORE_ENTITY_WORKFLOW, $context);
    }
}
