<?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\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\PersonRepository;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

/**
 * Find a Person entity by his id during the denormalization process.
 */
readonly class PersonJsonReadDenormalizer implements DenormalizerInterface
{
    public function __construct(private PersonRepository $repository) {}

    public function denormalize($data, string $type, ?string $format = null, array $context = []): Person
    {
        if (!is_array($data)) {
            throw new InvalidArgumentException();
        }

        if (\array_key_exists('id', $data)) {
            $person = $this->repository->find($data['id']);

            if (null === $person) {
                throw new UnexpectedValueException("The person with id \"{$data['id']}\" does ".'not exists');
            }

            return $person;
        }

        throw new LogicException();
    }

    public function supportsDenormalization($data, string $type, ?string $format = null)
    {
        return is_array($data) && Person::class === $type && 'person' === ($data['type'] ?? null) && isset($data['id']);
    }
}
