<?php

namespace Src\Common\Pages\Sidebar;

use Src\Common\Interfaces\Pages\Sidebar\IFactory;
use Src\Common\Interfaces\Pages\Sidebar\IMenu;
use Src\Common\Interfaces\Pages\Sidebar\IItem;
use Src\Common\Interfaces\Pages\Sidebar\ISubItem;

/**
 * Фабрика для создания элементов сайдбара
 * Реализует паттерн "Абстрактная фабрика" для управления компонентами сайдбара
 */
class Factory implements IFactory
{
    /**
     * Основное меню сайдбара
     * @var IMenu|null Экземпляр меню (ленивая инициализация)
     */
    protected ?IMenu $menu = null;

    /**
     * Конфигурация фабрики
     * @var array {
     *     @type array $classMap Карта классов для создания элементов
     * }
     */
    protected array $conf;

    /**
     * Инициализация фабрики
     * @param array $conf Конфигурация фабрики:
     *     - Может содержать переопределения классов элементов
     */
    public function init(array $conf = []): void
    {
        $this->conf = $conf;

        // Установка классов по умолчанию
        $this->conf[IMenu::class] = [
            'class' => Menu::class,      // Класс основного меню
        ];
        $this->conf[IItem::class] = [
            'class' => Item::class,      // Класс пункта меню
        ];
        $this->conf[ISubItem::class] = [
            'class' => SubItem::class,   // Класс подпункта меню
        ];
    }

    /**
     * Получает главное меню сайдбара (с ленивой инициализацией)
     * @return Menu Экземпляр главного меню
     */
    public function getMenu(): Menu
    {
        if ($this->menu === null) {
            $this->menu = new $this->conf[IMenu::class]['class']();
            $this->menu->setSidebarFactory($this);
        }
        return $this->menu;
    }

    /**
     * Создает новый пункт меню
     * @return Item Экземпляр пункта меню
     */
    public function createItem(): Item
    {
        $item = new $this->conf[IItem::class]['class']();
        $item->setSidebarFactory($this);
        return $item;
    }

    /**
     * Создает новый подпункт меню
     * @return SubItem Экземпляр подпункта меню
     */
    public function createSubItem(): SubItem
    {
        $subItem = new $this->conf[ISubItem::class]['class']();
        $subItem->setSidebarFactory($this);
        return $subItem;
    }
}
