<?php

namespace MintyPHP\Module\Helpdesk;

use MintyPHP\App\AppContainer;
use MintyPHP\App\Container\ContainerRegistrar;
use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Module\Helpdesk\Service\BcODataGateway;
use MintyPHP\Module\Helpdesk\Service\BcSoapGateway;
use MintyPHP\Module\Helpdesk\Service\DebitorDetailService;
use MintyPHP\Module\Helpdesk\Service\DebitorSearchService;
use MintyPHP\Module\Helpdesk\Service\DomainDetailService;
use MintyPHP\Module\Helpdesk\Service\DomainListService;
use MintyPHP\Module\Helpdesk\Service\EffectiveHelpdeskSettingsService;
use MintyPHP\Module\Helpdesk\Service\HelpdeskOAuthTokenService;
use MintyPHP\Module\Helpdesk\Service\HelpdeskSettingsGateway;
use MintyPHP\Module\Helpdesk\Service\HelpdeskTenantSettingsGateway;
use MintyPHP\Module\Helpdesk\Repository\HelpdeskTenantSettingsRepository;
use MintyPHP\Module\Helpdesk\Repository\HelpdeskTokenRepository;
use MintyPHP\Module\Helpdesk\Service\SoftwareProductService;
use MintyPHP\Module\Helpdesk\Service\SoftwareProductSyncService;
use MintyPHP\Module\Helpdesk\Service\SystemRecommendationEngine;
use MintyPHP\Module\Helpdesk\Service\TicketCommunicationService;
use MintyPHP\Module\Helpdesk\Handler\SoftwareProductSyncJobHandler;
use MintyPHP\Module\Helpdesk\Repository\DomainSecurityLevelRepository;
use MintyPHP\Module\Helpdesk\Repository\HandoverRepository;
use MintyPHP\Module\Helpdesk\Repository\HandoverRevisionRepository;
use MintyPHP\Module\Helpdesk\Repository\SoftwareProductRepository;
use MintyPHP\Module\Helpdesk\Repository\UpdateRepository;
use MintyPHP\Module\Helpdesk\Service\DomainSecurityLevelService;
use MintyPHP\Module\Helpdesk\Service\HandoverNotificationService;
use MintyPHP\Module\Helpdesk\Service\HandoverRevisionService;
use MintyPHP\Module\Helpdesk\Service\HandoverService;
use MintyPHP\Service\Mail\MailService;
use MintyPHP\Module\Helpdesk\Service\UpdateService;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Settings\SettingServicesFactory;
use MintyPHP\Service\Settings\SettingsMetadataGateway;

final class HelpdeskContainerRegistrar implements ContainerRegistrar
{
    public function register(AppContainer $container): void
    {
        $container->set(HelpdeskAuthorizationPolicy::class, static fn (AppContainer $c): HelpdeskAuthorizationPolicy => new HelpdeskAuthorizationPolicy(
            $c->get(PermissionService::class)
        ));

        $container->set(HelpdeskSettingsGateway::class, static fn (AppContainer $c): HelpdeskSettingsGateway => new HelpdeskSettingsGateway(
            $c->get(SettingsMetadataGateway::class),
            $c->get(SettingServicesFactory::class)->createSettingsCryptoGateway()
        ));

        $container->set(HelpdeskTenantSettingsRepository::class, static fn (): HelpdeskTenantSettingsRepository => new HelpdeskTenantSettingsRepository());

        $container->set(HelpdeskTenantSettingsGateway::class, static fn (AppContainer $c): HelpdeskTenantSettingsGateway => new HelpdeskTenantSettingsGateway(
            $c->get(HelpdeskTenantSettingsRepository::class),
            $c->get(SettingServicesFactory::class)->createSettingsCryptoGateway()
        ));

        $container->set(EffectiveHelpdeskSettingsService::class, static fn (AppContainer $c): EffectiveHelpdeskSettingsService => new EffectiveHelpdeskSettingsService(
            $c->get(HelpdeskSettingsGateway::class),
            $c->get(HelpdeskTenantSettingsGateway::class),
            $c->get(SessionStoreInterface::class)
        ));

        $container->set(BcODataGateway::class, static fn (AppContainer $c): BcODataGateway => new BcODataGateway(
            $c->get(EffectiveHelpdeskSettingsService::class),
            $c->get(HelpdeskOAuthTokenService::class),
            $c->get(SessionStoreInterface::class)
        ));

        $container->set(BcSoapGateway::class, static fn (AppContainer $c): BcSoapGateway => new BcSoapGateway(
            $c->get(EffectiveHelpdeskSettingsService::class),
            $c->get(HelpdeskOAuthTokenService::class),
            $c->get(SessionStoreInterface::class)
        ));

        $container->set(HelpdeskTokenRepository::class, static fn (AppContainer $c): HelpdeskTokenRepository => new HelpdeskTokenRepository(
            $c->get(SettingServicesFactory::class)->createSettingsCryptoGateway()
        ));

        $container->set(HelpdeskOAuthTokenService::class, static fn (AppContainer $c): HelpdeskOAuthTokenService => new HelpdeskOAuthTokenService(
            $c->get(EffectiveHelpdeskSettingsService::class),
            $c->get(HelpdeskTokenRepository::class)
        ));

        $container->set(DebitorSearchService::class, static fn (AppContainer $c): DebitorSearchService => new DebitorSearchService(
            $c->get(BcODataGateway::class),
            $c->get(EffectiveHelpdeskSettingsService::class)
        ));

        $container->set(DebitorDetailService::class, static fn (AppContainer $c): DebitorDetailService => new DebitorDetailService(
            $c->get(BcODataGateway::class),
            $c->get(EffectiveHelpdeskSettingsService::class)
        ));

        $container->set(DomainDetailService::class, static fn (AppContainer $c): DomainDetailService => new DomainDetailService(
            $c->get(BcODataGateway::class),
            $c->get(EffectiveHelpdeskSettingsService::class),
            $c->get(HandoverRepository::class),
            $c->get(UpdateRepository::class)
        ));

        $container->set(TicketCommunicationService::class, static fn (AppContainer $c): TicketCommunicationService => new TicketCommunicationService(
            $c->get(BcSoapGateway::class),
            $c->get(BcODataGateway::class)
        ));

        $container->set(SystemRecommendationEngine::class, static fn (): SystemRecommendationEngine => new SystemRecommendationEngine());

        $container->set(SoftwareProductRepository::class, static fn (): SoftwareProductRepository => new SoftwareProductRepository());

        $container->set(SoftwareProductSyncService::class, static fn (AppContainer $c): SoftwareProductSyncService => new SoftwareProductSyncService(
            $c->get(BcODataGateway::class),
            $c->get(SoftwareProductRepository::class),
            $c->get(HelpdeskSettingsGateway::class)
        ));

        $container->set(SoftwareProductService::class, static fn (AppContainer $c): SoftwareProductService => new SoftwareProductService(
            $c->get(SoftwareProductRepository::class)
        ));

        $container->set(SoftwareProductSyncJobHandler::class, static fn (AppContainer $c): SoftwareProductSyncJobHandler => new SoftwareProductSyncJobHandler(
            $c->get(SoftwareProductSyncService::class)
        ));

        $container->set(DomainSecurityLevelRepository::class, static fn (): DomainSecurityLevelRepository => new DomainSecurityLevelRepository());

        $container->set(DomainSecurityLevelService::class, static fn (AppContainer $c): DomainSecurityLevelService => new DomainSecurityLevelService(
            $c->get(DomainSecurityLevelRepository::class)
        ));

        $container->set(DomainListService::class, static fn (AppContainer $c): DomainListService => new DomainListService(
            $c->get(BcODataGateway::class),
            $c->get(DomainSecurityLevelService::class)
        ));

        $container->set(HandoverRepository::class, static fn (): HandoverRepository => new HandoverRepository());

        $container->set(HandoverRevisionRepository::class, static fn (): HandoverRevisionRepository => new HandoverRevisionRepository());

        $container->set(HandoverRevisionService::class, static fn (AppContainer $c): HandoverRevisionService => new HandoverRevisionService(
            $c->get(HandoverRevisionRepository::class),
            $c->get(HandoverRepository::class)
        ));

        $container->set(HandoverNotificationService::class, static fn (AppContainer $c): HandoverNotificationService => new HandoverNotificationService(
            $c->get(MailService::class)
        ));

        $container->set(HandoverService::class, static fn (AppContainer $c): HandoverService => new HandoverService(
            $c->get(HandoverRepository::class),
            $c->get(SoftwareProductService::class),
            $c->get(HandoverRevisionService::class),
            $c->get(HandoverNotificationService::class)
        ));

        $container->set(UpdateRepository::class, static fn (): UpdateRepository => new UpdateRepository());

        $container->set(UpdateService::class, static fn (AppContainer $c): UpdateService => new UpdateService(
            $c->get(UpdateRepository::class),
            $c->get(BcODataGateway::class)
        ));
    }
}
