<?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\MainBundle\Serializer\Normalizer;

use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\UserRepository;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;

class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;

    public function __construct(private readonly UserRepository $userRepository) {}

    /**
     * @param CommentEmbeddable $object
     *
     * @throws ExceptionInterface
     */
    public function normalize($object, ?string $format = null, array $context = []): array
    {
        if (null === $object || $object->isEmpty()) {
            return [
                'comment' => '',
                'isNull' => true,
                'date' => $this->normalizer->normalize(null, $format, array_merge($context, [
                    'docgen:expects' => \DateTime::class,
                ])),
                'user' => $this->normalizer->normalize(null, $format, array_merge($context, [
                    'docgen:expects' => User::class,
                ])),
            ];
        }

        if (null === $object->getUserId()) {
            $user = null;
        } else {
            $user = $this->userRepository->find($object->getUserId());
        }

        return [
            'comment' => $object->getComment(),
            'isNull' => false,
            'date' => $this->normalizer->normalize($object->getDate(), $format, array_merge($context, [
                'docgen:expects' => \DateTime::class,
            ])),
            'user' => $this->normalizer->normalize($user, $format, array_merge($context, [
                'docgen:expects' => User::class,
            ])),
        ];
    }

    public function supportsNormalization($data, ?string $format = null, array $context = []): bool
    {
        if ('docgen' !== $format) {
            return false;
        }

        if ($data instanceof CommentEmbeddable) {
            return true;
        }

        if (
            null === $data
            && \array_key_exists('docgen:expects', $context)
            && CommentEmbeddable::class === $context['docgen:expects']) {
            return true;
        }

        return false;
    }
}
