<?php


namespace AutoAdmin\Bundle\Admin\Form\Transformer;


use Doctrine\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

/**
 * Class EntityHiddenTransformer
 *
 */
class HiddenEntityTransformer implements DataTransformerInterface
{
    private ObjectManager $objectManager;
    private string $className;
    private ?string $primaryKey = null;

    public function __construct(ObjectManager $objectManager, string $className, ?string $primaryKey = null)
    {
        $this->objectManager = $objectManager;
        $this->className = $className;
        $this->primaryKey = $primaryKey ?? 'id';
    }

    /**
     * Transforms an object (entity) to a string (number).
     */
    public function transform($entity): string
    {
        if (null === $entity) {
            return '';
        }

        $method = 'get' . ucfirst($this->getPrimaryKey());

        // Probably worth throwing an exception if the method doesn't exist
        // Note: you can always use reflection to get the PK even though there's no public getter for it
        $pkValue = $entity->$method();

        return $this->objectManager->find($this->className, $pkValue);
    }

    public function getPrimaryKey(): ?string
    {
        return $this->primaryKey;
    }

    /**
     * Transforms a string (number) to an object (entity).
     *
     * @throws TransformationFailedException if object (entity) is not found.
     */
    public function reverseTransform($identifier): ?object
    {
        if (!$identifier) {
            return null;
        }

        $entity = $this->getObjectManager()
            ->getRepository($this->getClassName())
            ->find($identifier);

        if (null === $entity) {
            // causes a validation error
            // this message is not shown to the user
            // see the invalid_message option
            throw new TransformationFailedException(sprintf(
                'An entity with ID "%s" does not exist!',
                $identifier
            ));
        }

        return $entity;
    }

    public function getObjectManager(): ObjectManager
    {
        return $this->objectManager;
    }

    public function getClassName(): string
    {
        return $this->className;
    }
}
