<?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\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Relationships\Relationship;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;

class RelationshipDocGenNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;

    public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {}

    /**
     * @param Relationship $relation
     * @param string|null  $format
     */
    public function normalize($relation, $format = null, array $context = [])
    {
        $counterpart = $context['docgen:relationship:counterpart'] ?? null;
        $contextPerson = array_merge($context, [
            'docgen:person:with-relations' => false,
            'docgen:relationship:counterpart' => null,
            'docgen:expects' => Person::class,
        ]);

        if (null !== $counterpart) {
            $opposite = $relation->getOpposite($counterpart);
        } else {
            $opposite = null;
        }

        if (null === $relation) {
            return [
                'id' => '',
                'fromPerson' => $nullPerson = $this->normalizer->normalize(null, $format, $contextPerson),
                'toPerson' => $nullPerson,
                'opposite' => $nullPerson,
                'text' => '',
                'relationId' => '',
            ];
        }

        return [
            'id' => $relation->getId(),
            'fromPerson' => $this->normalizer->normalize(
                $relation->getFromPerson(),
                $format,
                $contextPerson
            ),
            'toPerson' => $this->normalizer->normalize(
                $relation->getToPerson(),
                $format,
                $contextPerson
            ),
            'text' => $relation->getReverse() ?
                $this->translatableStringHelper->localize($relation->getRelation()->getReverseTitle()) :
                $this->translatableStringHelper->localize($relation->getRelation()->getTitle()),
            'opposite' => $this->normalizer->normalize($opposite, $format, $contextPerson),
            'relationId' => $relation->getRelation()->getId(),
        ];
    }

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

        return $data instanceof Relationship || (null === $data
            && Relationship::class === ($context['docgen:expects'] ?? null));
    }
}
