<?php

namespace humhub\modules\custom_pages\modules\template\services;

use humhub\modules\custom_pages\modules\template\elements\ActivitiesElement;
use humhub\modules\custom_pages\modules\template\elements\BaseElementContent;
use humhub\modules\custom_pages\modules\template\elements\ContainerElement;
use humhub\modules\custom_pages\modules\template\elements\FileDownloadElement;
use humhub\modules\custom_pages\modules\template\elements\FileElement;
use humhub\modules\custom_pages\modules\template\elements\HtmlElement;
use humhub\modules\custom_pages\modules\template\elements\ImageElement;
use humhub\modules\custom_pages\modules\template\elements\MarkdownElement;
use humhub\modules\custom_pages\modules\template\elements\PostElement;
use humhub\modules\custom_pages\modules\template\elements\RssElement;
use humhub\modules\custom_pages\modules\template\elements\SpaceElement;
use humhub\modules\custom_pages\modules\template\elements\SpacesElement;
use humhub\modules\custom_pages\modules\template\elements\TextElement;
use humhub\modules\custom_pages\modules\template\elements\UserElement;
use humhub\modules\custom_pages\modules\template\elements\UsersElement;
use yii\base\Component;

/**
 * ElementTypeService provides a list of available element types.
 *
 * Module API:
 *
 * Inject own element types via Module Event.
 *
 * `config.php`:
 *
 * ```php
 *  [
 *      '\humhub\modules\custom_pages\modules\template\services\ElementTypeService', 'init',
 *      [Events::class, 'onCustomPagesTemplateElementTypeServiceInit']
 *  ],
 * ```
 * `Events.php`:
 *
 * ```php
 *      public static function onCustomPagesTemplateElementAvailableTypes(Event $event)
 *      {
 *         $elementTypeService = $event->sender;
 *         $elementTypeService->addType(CalendarsElement::class);
 *      }
 *  }
 *  ```
 */
final class ElementTypeService extends Component
{
    private const DEFAULT_TYPES = [
        TextElement::class,
        HtmlElement::class,
        MarkdownElement::class,
        ImageElement::class,
        FileElement::class,
        FileDownloadElement::class,
        ContainerElement::class,
        RssElement::class,
        UserElement::class,
        SpaceElement::class,
        UsersElement::class,
        SpacesElement::class,
        PostElement::class,
        ActivitiesElement::class,
    ];

    private array $types = [];

    public const EVENT_INIT = 'init';

    public function init()
    {
        $this->types = self::DEFAULT_TYPES;
        $this->trigger(self::EVENT_INIT);
    }

    public function addType(string $type): void
    {
        $this->types[] = $type;
    }

    /**
     * @param string|null $group 'default', 'module', null - 'all'
     * @return BaseElementContent[]
     */
    public function getTypeInstances(?string $group = null): array
    {
        $instances = [];

        foreach ($this->types as $type) {
            if ($group === null
                || ($group === 'default' && in_array($type, self::DEFAULT_TYPES))
                || ($group === 'module' && !in_array($type, self::DEFAULT_TYPES))) {
                $instances[] = new $type();
            }
        }

        return $instances;
    }
}
