<?php

namespace MintyPHP\Service\Import;

use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Service\Access\AccessServicesFactory;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Audit\ImportAuditInterface;
use MintyPHP\Service\Directory\DirectoryServicesFactory;
use MintyPHP\Service\Import\Profile\DepartmentImportGateway;
use MintyPHP\Service\Import\Profile\DepartmentImportProfile;
use MintyPHP\Service\Import\Profile\UserImportGateway;
use MintyPHP\Service\Import\Profile\UserImportProfile;
use MintyPHP\Service\Settings\SettingsDefaultsGateway;
use MintyPHP\Service\Settings\SettingServicesFactory;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserServicesFactory;

class ImportServicesFactory
{
    private ?CsvReaderService $csvReaderService = null;
    private ?ImportTempFileService $importTempFileService = null;
    private ?ImportStateStoreService $importStateStoreService = null;
    private ?PermissionService $permissionService = null;
    private ?SettingsDefaultsGateway $settingsDefaultsGateway = null;
    private ?ImportService $importService = null;

    public function __construct(
        private readonly UserServicesFactory $userServicesFactory,
        private readonly AccessServicesFactory $accessServicesFactory,
        private readonly SettingServicesFactory $settingServicesFactory,
        private readonly DirectoryServicesFactory $directoryServicesFactory,
        private readonly ImportAuditInterface $importAudit,
        private readonly TenantScopeService $tenantScopeService,
        private readonly SessionStoreInterface $sessionStore
    ) {
    }

    public function createImportService(): ImportService
    {
        if ($this->importService !== null) {
            return $this->importService;
        }

        $profiles = [
            'users' => new UserImportProfile(
                new UserImportGateway(
                    $this->userServicesFactory->createUserReadRepository(),
                    $this->directoryServicesFactory->createTenantRepository(),
                    $this->directoryServicesFactory->createRoleRepository(),
                    $this->directoryServicesFactory->createDepartmentRepository(),
                ),
                $this->userServicesFactory->createUserAccountService()
            ),
            'departments' => new DepartmentImportProfile(
                new DepartmentImportGateway(
                    $this->directoryServicesFactory->createDepartmentRepository(),
                    $this->directoryServicesFactory->createTenantRepository()
                ),
                $this->directoryServicesFactory->createDepartmentService()
            ),
        ];

        return $this->importService = new ImportService(
            $this->getCsvReaderService(),
            $this->getImportTempFileService(),
            $this->importAudit,
            $this->createImportStateStoreService(),
            $profiles,
            $this->createPermissionService(),
            $this->createSettingsDefaultsGateway(),
            $this->tenantScopeService,
            $this->sessionStore
        );
    }

    public function createImportStateStoreService(): ImportStateStoreService
    {
        return $this->importStateStoreService ??= new ImportStateStoreService(
            $this->getImportTempFileService(),
            $this->sessionStore
        );
    }

    private function getCsvReaderService(): CsvReaderService
    {
        return $this->csvReaderService ??= new CsvReaderService();
    }

    private function getImportTempFileService(): ImportTempFileService
    {
        return $this->importTempFileService ??= new ImportTempFileService();
    }

    private function createPermissionService(): PermissionService
    {
        return $this->permissionService ??= $this->accessServicesFactory->createPermissionService();
    }

    private function createSettingsDefaultsGateway(): SettingsDefaultsGateway
    {
        return $this->settingsDefaultsGateway ??= $this->settingServicesFactory->createSettingsDefaultsGateway();
    }
}
