<?php

namespace MintyPHP\Service\Directory;

use MintyPHP\Repository\Access\RoleRepository;
use MintyPHP\Repository\Org\DepartmentRepository;
use MintyPHP\Repository\Tenant\TenantRepository;
use MintyPHP\Service\Access\RoleService;
use MintyPHP\Service\Org\DepartmentService;
use MintyPHP\Service\Settings\SettingServicesFactory;
use MintyPHP\Service\Tenant\TenantServicesFactory;
use MintyPHP\Service\Tenant\TenantService;
use MintyPHP\Service\User\UserServicesFactory;

class DirectoryServicesFactory
{
    private ?TenantRepository $tenantRepository = null;
    private ?DepartmentRepository $departmentRepository = null;
    private ?RoleRepository $roleRepository = null;
    private ?DirectorySettingsGateway $directorySettingsGateway = null;
    private ?DirectoryScopeGateway $directoryScopeGateway = null;
    private ?TenantServicesFactory $tenantServicesFactory = null;
    private ?TenantService $tenantService = null;
    private ?DepartmentService $departmentService = null;
    private ?RoleService $roleService = null;
    private ?UserServicesFactory $userServicesFactory = null;
    private ?SettingServicesFactory $settingServicesFactory = null;

    public function createTenantService(): TenantService
    {
        return $this->tenantService ??= new TenantService(
            $this->createTenantRepository(),
            $this->createDepartmentRepository(),
            $this->createDirectorySettingsGateway()
        );
    }

    public function createDepartmentService(): DepartmentService
    {
        return $this->departmentService ??= new DepartmentService(
            $this->createDepartmentRepository(),
            $this->userServicesFactory(),
            $this->createDirectorySettingsGateway(),
            $this->createDirectoryScopeGateway()
        );
    }

    public function createRoleService(): RoleService
    {
        return $this->roleService ??= new RoleService(
            $this->createRoleRepository(),
            $this->createDirectorySettingsGateway()
        );
    }

    public function createTenantRepository(): TenantRepository
    {
        return $this->tenantRepository ??= new TenantRepository();
    }

    public function createDepartmentRepository(): DepartmentRepository
    {
        return $this->departmentRepository ??= new DepartmentRepository();
    }

    public function createRoleRepository(): RoleRepository
    {
        return $this->roleRepository ??= new RoleRepository();
    }

    public function createDirectorySettingsGateway(): DirectorySettingsGateway
    {
        return $this->directorySettingsGateway ??= new DirectorySettingsGateway(
            $this->settingServicesFactory()->createSettingGateway()
        );
    }

    public function createDirectoryScopeGateway(): DirectoryScopeGateway
    {
        return $this->directoryScopeGateway ??= new DirectoryScopeGateway(
            $this->tenantServicesFactory()->createTenantScopeService()
        );
    }

    private function userServicesFactory(): UserServicesFactory
    {
        return $this->userServicesFactory ??= new UserServicesFactory();
    }

    private function settingServicesFactory(): SettingServicesFactory
    {
        return $this->settingServicesFactory ??= new SettingServicesFactory();
    }

    private function tenantServicesFactory(): TenantServicesFactory
    {
        return $this->tenantServicesFactory ??= new TenantServicesFactory();
    }
}
