<?php

namespace Comitium5\DesignerBundle\Form\DataTransformer;

use Comitium5\DesignerBundle\ValueObjects\SearchEntityObject;

/**
 * Js file associated is suggest.js. Init search requires a json string if multiple option is
 * defined or a id if is not defined. Reverse transform get an string with a single id or with
 * multiples id separated by commas. Fetch entity must be by id always.
 *
 * Class MultipleSubSiteSuggestDataTransformer
 *
 * @author David Carrascosa <david@bab-soft.com>
 * @package Comitium5\DesignerBundle\Form\DataTransformer
 */
class MultipleSubSiteSuggestDataTransformer extends AbstractSuggestDataTransformer
{
    /**
     * @param mixed $entity
     *
     * @return string
     * @throws \Exception
     */
    public function transform($entity): string
    {
        if (empty($entity)) {
            return "";
        }

        if (is_array($entity)) {
            if (!count($entity)) {
                return "";
            }

            $values = [];

            foreach ($entity as $entityData) {
                $data = $this->fetchEntity($entityData['id']);

                if (!$data) {
                    continue;
                }

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

            if (!empty($values)) {
                if (false === $this->multiple) {
                    $values = $values[0];
                }
            }

            return json_encode($values);
        }

        return '';
    }

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

        $values = explode($this->separator, $data);

        $resolveData = [];

        foreach ($values as $value) {
            $interData = explode(":", $value);

            $resolveData[] = [
                "id"       => $interData[0],
                "subsites" => explode(",", $interData[1]),
            ];
        }

        return $resolveData;
    }

    /**
     * @param $entity
     *
     * @return string
     */
    public static function buildSubSiteIdString($entity): string
    {
        if ($entity instanceof SearchEntityObject) {
            $id = $entity->getId();
        }

        if (is_array($entity)) {
            $id = $entity['id'];
        }

        if (empty($id)) {
            return '';
        }

        return sprintf(
            '%s:%s',
            $id,
            implode(',', self::resolveEntitySubsites($entity))
        );
    }

    /**
     * @param SearchEntityObject $entity
     *
     * @return string
     */
    public static function resolveDataDescription(SearchEntityObject $entity): string
    {
        $description = parent::resolveDataDescription($entity);

        $subSites = self::resolveEntitySubsites($entity, true);

        if (!empty($subSites)) {
            $description .= ' ('.implode(', ', $subSites).')';
        }

        return $description;
    }

    /**
     * @param $entity
     * @param bool $subSiteName
     *
     * @return array
     */
    protected static function resolveEntitySubsites($entity, bool $subSiteName = false): array
    {
        if ($entity instanceof SearchEntityObject) {
            $entitySubSites = $entity->getSubsite();
        }

        if (is_array($entity)) {
            $entitySubSites = $entity['subSite'];
        }

        if (empty($entitySubSites)) {
            return [];
        }

        $subSites = [];

        foreach ($entitySubSites as $subSite) {
            if ($subSiteName && !empty($subSite['name'])) {
                $subSites[] = $subSite['name'];
            } elseif (!empty($subSite['acronym'])) {
                $subSites[] = $subSite['acronym'];
            }
        }

        return $subSites;
    }
}