<?php

namespace Src;

use Src\Common\Interfaces\IModulesProvider as ICommonProvider;
use Src\Common\Interfaces\IFactory as ICommonFactory;
use Src\Common\Factory as CommonFactory;

use Src\Modules\Auth\Interfaces\IModulesProvider as IAuthModulesProvider;
use Src\Modules\Auth\Interfaces\IFactory as IAuthFactory;
use Src\Modules\Auth\Factory as AuthFactory;

use Src\Sidebar\Interfaces\IModulesProvider as ISidebarProvider;
use Src\Sidebar\Interfaces\IFactory as ISidebarFactory;
use Src\Sidebar\Factory as SidebarFactory;

use Src\Modules\JsonObjects\Interfaces\IModulesProvider as IJSONProvider;
use Src\Modules\JsonObjects\Interfaces\IFactory as IJSONFactory;
use Src\Modules\JsonObjects\Factory as JSONFactory;

// use Src\Lib\CategoriesTree\Interfaces\IFactory as IDirTreeFactory;
// use Src\Lib\CategoriesTree\Factory as DirTreeFactory;

use Src\Common\Interfaces\Dto\Object\IFactory as IObjFactory;

class ModulesProvider implements ICommonProvider, ISidebarProvider, IJSONProvider, IAuthModulesProvider
{

    protected ?ICommonFactory $commonFactory = null;

    protected ?ISidebarFactory $sidebarFactory = null;

    protected ?IJSONFactory $jsonFactory = null;

    protected ?IAuthFactory $authFactory = null;

    protected array $conf = [];

    public function init(array $conf = []): void
    {
        $this->conf = [
            'sidebar' => [
                'factory' => SidebarFactory::class,
            ],
            'common' => [
                'factory' => CommonFactory::class,
            ],
            // 'jsonObjectsDirs' => [
            //     'factory' => DirTreeFactory::class,
            //     'settings' => [
            //         IDirTreeFactory::DB_CHARSET => 'utf8',
            //         IDirTreeFactory::DB_HOST => env('DB_HOST'),
            //         IDirTreeFactory::DB_NAME => env('DB_DATABASE'),
            //         IDirTreeFactory::DB_PASS => env('DB_PASSWORD'),
            //         IDirTreeFactory::DB_USER => env('DB_USERNAME'),
            //         // IDirTreeFactory::TABLE_NAME => $dirsTable,
            //     ],
            // ],
            'jsonObjects' => [
                'factory' => JSONFactory::class,
                'settings' => [
                    IJSONFactory::DB_CHARSET => 'utf8',
                    IJSONFactory::DB_HOST => env('DB_HOST'),
                    IJSONFactory::DB_NAME => env('DB_DATABASE'),
                    IJSONFactory::DB_PASS => env('DB_PASSWORD'),
                    IJSONFactory::DB_USER => env('DB_USERNAME'),
                    IJSONFactory::ITEMS_DROPDOWN => [
                        [
                            IJSONFactory::ITEM_TITLE => 'Example',
                            IJSONFactory::ITEM_TYPE => \Src\Common\Dto\Object\ExampleComposit::EXAMPLE_COMPOSIT,
                        ]
                    ],
                    IJSONFactory::OBJECTS_FACTORY => new \Src\Common\Dto\Object\Factory(),
                    IJSONFactory::OBJECTS_TABLE => 'json_items',
                    IJSONFactory::DIRS_TABLE => 'json_dirs',
                ],
            ],
        ];
        $this->conf = array_replace_recursive($this->conf, $conf);
    }

    protected function createInstance($instance)
    {
        if (gettype($instance) == 'string') {
            return new $instance;
        }
        if (gettype($instance) == 'object') {
            return $instance;
        }
    }

    public function getSidebarFactory(): SidebarFactory
    {
        if ($this->sidebarFactory === null) {
            $this->sidebarFactory = $this->createInstance($this->conf['sidebar']['factory']);
            $this->sidebarFactory->init();
            $this->sidebarFactory->injectModules($this);
        }
        return $this->sidebarFactory;
    }

    public function getCommonFactory(): CommonFactory
    {
        if ($this->commonFactory === null) {
            $this->commonFactory = $this->createInstance($this->conf['common']['factory']);
            $this->commonFactory->init();
        }
        return $this->commonFactory;
    }

    // protected function createDirTreeFactory(): DirTreeFactory
    // {
    //     $factory = $this->createInstance($this->conf['jsonObjectsDirs']['factory']);
    //     $factory->loadSettings($this->conf['jsonObjectsDirs']['settings']);
    //     $factory->init();
    //     $factory->setCommonFactory($this->getCommonFactory());
    //     return $factory;
    // }

    public function getJsonObjectsFactory(): JSONFactory
    {
        if ($this->jsonFactory === null) {
            $this->jsonFactory = $this->createInstance($this->conf['jsonObjects']['factory']);
            $this->jsonFactory->init();
            $this->jsonFactory->loadSettings($this->conf['jsonObjects']['settings']);
            // $dirTreeFactory = $this->createDirTreeFactory();
            // $this->jsonFactory->setDirsTreeFactory($dirTreeFactory);
            $this->jsonFactory->injectModules($this);
        }
        return $this->jsonFactory;
    }

    public function getAuthFactory(): IAuthFactory
    {
        if ($this->authFactory === null) {
            $this->authFactory = new AuthFactory();
            $this->authFactory->loadSettings([
                IAuthFactory::ADMINS_TABLE => 'admins',
            ]);
            $this->authFactory->injectModules($this);
            // $this->authFactory->init();
        }
        return $this->authFactory;
    }
}
