<?php

namespace Comitium5\DesignerBundle\Form\DataTransformer;

use Doctrine\Common\Collections\Collection;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\PropertyAccess\PropertyAccess;

/**
 * Class SuggestDataTransformer
 *
 * @author David Carrascosa <david@bab-soft.com>
 * @package Comitium5\DesignerBundle\Form\DataTransformer
 */
class SuggestDataTransformer extends AbstractSuggestDataTransformer
{
    /**
     * @param mixed $entity
     *
     * @return string
     * @throws \Exception
     */
    public function transform($entity): string
    {
        if (empty($entity)) {
            return "";
        }

        $accessor = PropertyAccess::createPropertyAccessor();

        if (false === $this->multiple) {
            $entity = $this->fetchEntity($entity);

            if (!$entity) {
                return '';
            }

            if (!($accessor->isReadable($entity, self::resolvePropertyAccesParameter($entity, $this->property)))) {
                throw new TransformationFailedException(
                    sprintf(
                        'Entity "%s" has no such property "%s"!',
                        $this->contentType,
                        $this->property
                    )
                );
            }

            $values = [
                'id'      => $accessor->getValue($entity, self::resolvePropertyAccesParameter($entity, 'id')),
                'text'    => $this->resolveText($entity),
                'date'    => self::resolveEntityDate($entity),
                'future'  => self::resolveFuture($entity),
                'enabled' => self::resolveEnabledEntity($entity),
            ];

            return json_encode($values);
        }

        if ($entity instanceof Collection) {
            if (!$entity->count()) {
                return "";
            }

            $values = [];

            foreach ($entity as $data) {
                $data = $this->fetchEntity($data);

                if (empty($data)) {
                    continue;
                }

                if (!($accessor->isReadable($data, self::resolvePropertyAccesParameter($data, $this->property)))) {
                    throw new TransformationFailedException(
                        sprintf(
                            'Entity "%s" has no such property "%s"!',
                            $this->contentType,
                            $this->property
                        )
                    );
                }

                $values[] = [
                    'id'      => $accessor->getValue($data, self::resolvePropertyAccesParameter($data, 'id')),
                    'text'    => $this->resolveText($data),
                    'future'  => self::resolveFuture($data),
                    'date'    => self::resolveEntityDate($data),
                    'enabled' => self::resolveEnabledEntity($data),
                ];
            }

            return json_encode($values);
        }

        return "";
    }

    /**
     * @param mixed $id
     *
     * @return mixed|null
     */
    public function reverseTransform($id)
    {
        if (!$id) {
            return null;
        }

        if (false === $this->multiple) {
            $data = json_decode($id, true);

            $id = isset($data["id"]) ? $data["id"] : $data;
        }

        return $id;
    }
}
