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

use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserGroup;
use Chill\TicketBundle\Action\Ticket\SetAddresseesCommand;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

final class SetAddresseesCommandDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
    use DenormalizerAwareTrait;

    public function denormalize($data, string $type, ?string $format = null, array $context = [])
    {
        if (null === $data) {
            return null;
        }

        if (!array_key_exists('addressees', $data)) {
            throw new UnexpectedValueException("key 'addressees' does exists");
        }

        if (!is_array($data['addressees'])) {
            throw new UnexpectedValueException("key 'addressees' must be an array");
        }

        $addresses = [];
        foreach ($data['addressees'] as $address) {
            $addresses[] = match ($address['type'] ?? '') {
                'user_group' => $this->denormalizer->denormalize($address, UserGroup::class, $format, $context),
                'user' => $this->denormalizer->denormalize($address, User::class, $format, $context),
                default => throw new UnexpectedValueException('the type is not set or not supported'),
            };
        }

        return new SetAddresseesCommand($addresses);
    }

    public function supportsDenormalization($data, string $type, ?string $format = null)
    {
        return SetAddresseesCommand::class === $type && 'json' === $format;
    }
}
