<?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\DocGeneratorBundle\Serializer\Helper;

use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class NormalizeNullValueHelper
{
    public function __construct(private readonly NormalizerInterface $normalizer, private readonly ?string $discriminatorType = null, private readonly ?string $discriminatorValue = null) {}

    public function normalize(array $attributes, string $format = 'docgen', ?array $context = [], ?ClassMetadataInterface $classMetadata = null)
    {
        $data = [];
        $data['isNull'] = true;

        if (null !== $this->discriminatorType) {
            $data[$this->discriminatorType] = $this->discriminatorValue;
        }

        foreach ($attributes as $key => $class) {
            if (is_numeric($key)) {
                $data[$class] = '';
            } else {
                $data[$key] = match ($class) {
                    'array', 'bool', 'double', 'float', 'int', 'resource', 'string', 'null' => '',
                    default => $this->normalizer->normalize(null, $format, \array_merge(
                        $this->getContextForAttribute($key, $context, $classMetadata),
                        ['docgen:expects' => $class]
                    )),
                };
            }
        }

        return $data;
    }

    private function getContextForAttribute(string $key, array $initialContext, ?ClassMetadataInterface $classMetadata): array
    {
        if (null === $classMetadata) {
            return $initialContext;
        }

        $attributeMetadata = $classMetadata->getAttributesMetadata()[$key] ?? null;

        if (null !== $attributeMetadata) {
            /** @var \Symfony\Component\Serializer\Mapping\AttributeMetadata $attributeMetadata */
            $initialContext = \array_merge(
                $initialContext,
                $attributeMetadata->getNormalizationContextForGroups(
                    \is_array($initialContext['groups']) ? $initialContext['groups'] : [$initialContext['groups']]
                )
            );
        }

        return $initialContext;
    }
}
