<?php

namespace Comitium5\DesignerBundle\Form\Model\WidgetParameters;

use Comitium5\DesignerBundle\Controller\Widget\AbstractDesignerWidgetController;
use Comitium5\DesignerBundle\Helper\Utils;
use Comitium5\DesignerBundle\Model\Interfaces\Subsite\SubsiteInterface;
use Comitium5\DesignerBundle\Model\Interfaces\Widget\WidgetInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\PropertyAccess\PropertyAccessor;

/**
 * Class WidgetParameters
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Form\Model\WidgetParameters
 */
class WidgetParameters
{
    /**
     * @var array
     */
    private $parameters;
    /**
     * @var WidgetInterface
     */
    private $widget;

    /**
     * @var array
     */
    private $locales;

    /**
     * @var string
     */
    private $uuid;

    /**
     * @var SubsiteInterface
     */
    private $subSite;

    /**
     * WidgetParameters constructor.
     *
     * @param array $parameters
     * @param WidgetInterface|null $widget
     * @param array $locales
     * @param null $uuid
     * @param array $subsite
     */
    public function __construct(
        array $parameters = [],
        WidgetInterface $widget = null,
        array $locales = [],
        $uuid = null,
        $subsite = []
    ) {
        $this->parameters = new ArrayCollection();

        if (count($parameters)) {
            $this->setParameters($parameters);
        }

        $this->widget = $widget;
        $this->locales = $locales;
        $this->uuid = $uuid ?: uniqid();
        $this->subSite = $subsite;
    }

    /**
     * @param WidgetParametersValue $parameter
     */
    public function addParameter(WidgetParametersValue $parameter)
    {
        $this->parameters->add($parameter);
    }

    /**
     * @param WidgetParametersValue $parameter
     */
    public function removeParameter(WidgetParametersValue $parameter)
    {
        $this->parameters->removeElement($parameter);
    }

    /**
     * @return array|ArrayCollection
     */
    public function getParameters()
    {
        return $this->parameters;
    }

    /**
     * @param array $parameters
     */
    public function setParameters(array $parameters)
    {
        foreach ($parameters as $name => $parameter) {
            $value = new WidgetParametersValue();

            $value->setWidgetParameter($this);

            $value->setName($name);

            if (isset($parameter['type'])) {
                $value->setType($parameter['type']);
            }

            if (isset($parameter['options'])) {
                $value->setOptions($parameter['options']);
            }

            if (isset($parameter['data'])) {
                $value->setData($parameter['data']);
            }

            if (isset($parameter['value'])) {
                $value->setValue($parameter['value']);
            }

            $this->parameters->add($value);
        }
    }

    /**
     * @return string
     */
    public function getUuid()
    {
        return $this->uuid;
    }

    /**
     * @param null $uuid
     */
    public function setUuid($uuid = null)
    {
        $this->uuid = $uuid === null ? Utils::uuidV4() : $uuid;
    }

    /**
     * @return array
     */
    public function toArray()
    {
        $array = [];

        $propertyAccessor = new PropertyAccessor();

        foreach ($this->parameters->toArray() as $parameter) {
            $reflection = new \ReflectionClass($parameter);

            foreach ($reflection->getProperties() as $property) {
                if (in_array($property->name, self::ignoreProperties())) {
                    continue;
                }

                $array['_parameters'][$parameter->getName()][$property->name] = $propertyAccessor->getValue($parameter, $property->name);
            }
        }

        $array[AbstractDesignerWidgetController::EDITOR_INDEX] = true;
        $array[AbstractDesignerWidgetController::UUID_INDEX] = $this->uuid;
        $array[AbstractDesignerWidgetController::LOCALES_INDEX] = $this->locales;
        $array[AbstractDesignerWidgetController::LOCALE_INDEX] = isset($this->locales[0]) ? $this->locales[0] : null;
        $array[AbstractDesignerWidgetController::WIDGET_INDEX] = [];
        $array[AbstractDesignerWidgetController::SUBSITE_INDEX] = [
            "id"      => $this->subSite->getId(),
            "acronym" => $this->subSite->getAcronym(),
        ];
        $array[AbstractDesignerWidgetController::SITE_INDEX] = [
            "id"     => $this->subSite->getSite()->getId(),
            "prefix" => $this->subSite->getSite()->getPrefix(),
        ];

        if ($this->widget !== null) {
            $array['_widget'] = [
                "id"   => $this->widget->getId(),
                "name" => $this->widget->getName(),
                "type" => $this->widget->getType(),
            ];
        }

        return $array;
    }

    /**
     * @return WidgetInterface
     */
    public function getWidget()
    {
        return $this->widget;
    }

    /**
     * @param WidgetInterface $widget
     */
    public function setWidget(WidgetInterface $widget)
    {
        $this->widget = $widget;
    }

    /**
     * @return array
     */
    public function getLocales()
    {
        return $this->locales;
    }

    /**
     * @param array $locales
     */
    public function setLocales(array $locales)
    {
        $this->locales = $locales;
    }

    /**
     * @return array
     */
    private static function ignoreProperties()
    {
        return [
            "widgetParameter",
        ];
    }
}
