<?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\Form\DataMapper;

use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\PersonIdentifier\Exception\UnexpectedTypeException;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
use Symfony\Component\Form\DataMapperInterface;

final readonly class PersonIdentifiersDataMapper implements DataMapperInterface
{
    public function __construct(
        private PersonIdentifierManagerInterface $identifierManager,
    ) {}

    /**
     * @pure
     */
    public function mapDataToForms($viewData, \Traversable $forms): void
    {
        if (!$viewData instanceof PersonIdentifier) {
            throw new UnexpectedTypeException($viewData, PersonIdentifier::class);
        }

        $worker = $this->identifierManager->buildWorkerByPersonIdentifierDefinition($viewData->getDefinition());
        if (!$worker->getDefinition()->isEditableByUsers()) {
            return;
        }
        foreach ($forms as $key => $form) {
            $form->setData($viewData->getValue()[$key] ?? $worker->getDefaultValue()[$key] ?? '');
        }
    }

    /**
     * @pure
     */
    public function mapFormsToData(\Traversable $forms, &$viewData): void
    {
        if (!$viewData instanceof PersonIdentifier) {
            throw new UnexpectedTypeException($viewData, PersonIdentifier::class);
        }
        $worker = $this->identifierManager->buildWorkerByPersonIdentifierDefinition($viewData->getDefinition());
        if (!$worker->getDefinition()->isEditableByUsers()) {
            return;
        }

        $values = [];
        foreach ($forms as $name => $form) {
            $values[$name] = $form->getData();
        }

        $viewData->setValue($values);
        $viewData->setCanonical($worker->canonicalizeValue($viewData->getValue()));
    }
}
