<?php

namespace NewsletterBridge\Utils;

use NewsletterBridge\Services\Query\QueryBuilder;
use NewsletterBridge\Services\Query\DateRangeBuilder;
use NewsletterBridge\Services\Query\TaxonomyQueryBuilder;
use NewsletterBridge\Services\Query\PostExclusionManager;
use NewsletterBridge\Services\Content\PostTemplateProcessor;
use NewsletterBridge\Services\Feed\RSSFormatter;
use NewsletterBridge\Services\Feed\FeedGenerator;
use NewsletterBridge\Services\Feed\XMLFileManager;
use NewsletterBridge\Services\Feed\XMLGenerationService;
use NewsletterBridge\Services\Newsletter\NewsletterSendingService;
use NewsletterBridge\Services\Newsletter\NewsletterOrchestrator;
use NewsletterBridge\Services\Newsletter\NewsletterFeed;
use NewsletterBridge\Services\External\Mailup;
use NewsletterBridge\Config\NewsletterConfig;

/**
 * Dependency Injection Container
 * Responsabilità: Gestione delle dipendenze e creazione oggetti
 */
class ServiceContainer {
    
    private array $services = [];
    private array $singletons = [];
    
    /**
     * Registra un servizio nel container
     */
    public function register(string $id, callable $factory, bool $singleton = false): void {
        $this->services[$id] = [
            'factory' => $factory,
            'singleton' => $singleton
        ];
    }
    
    /**
     * Ottiene un servizio dal container
     */
    public function get(string $id): mixed {
        if (!isset($this->services[$id])) {
            throw new \InvalidArgumentException("Service '{$id}' not found");
        }
        
        $service = $this->services[$id];
        
        if ($service['singleton']) {
            if (!isset($this->singletons[$id])) {
                $this->singletons[$id] = $service['factory']($this);
            }
            return $this->singletons[$id];
        }
        
        return $service['factory']($this);
    }
    
    /**
     * Configura i servizi predefiniti
     */
    public function configureDefaultServices(): void {
        $this->configureCoreServices();
        $this->configureBusinessServices();
        $this->configureOrchestrationServices();
    }
    
    /**
     * Configura i servizi core
     */
    private function configureCoreServices(): void {
        // DateRangeBuilder - Singleton
        $this->register('date_range_builder', function() {
            return new DateRangeBuilder();
        }, true);
        
        // TaxonomyQueryBuilder - Singleton
        $this->register('taxonomy_query_builder', function() {
            return new TaxonomyQueryBuilder();
        }, true);
        
        // QueryBuilder - Singleton
        $this->register('query_builder', function($container) {
            return new QueryBuilder(
                $container->get('date_range_builder'),
                $container->get('taxonomy_query_builder')
            );
        }, true);
        
        // PostExclusionManager - Singleton
        $this->register('post_exclusion_manager', function() {
            return new PostExclusionManager();
        }, true);
        
        // PostTemplateProcessor - Singleton
        $this->register('post_template_processor', function() {
            return new PostTemplateProcessor();
        }, true);
        
        // RSSFormatter - Singleton
        $this->register('rss_formatter', function() {
            return new RSSFormatter();
        }, true);
        
        // XMLFileManager - Singleton
        $this->register('xml_file_manager', function() {
            return new XMLFileManager();
        }, true);
    }
    
    /**
     * Configura i servizi business
     */
    private function configureBusinessServices(): void {
        // NewsletterConfig - Singleton
        $this->register('newsletter_config', function() {
            return NewsletterConfig::getConfig();
        }, true);
        
        // NewsletterFeed - Prototype (nuova istanza ogni volta)
        $this->register('newsletter_feed', function($container) {
            $config = $container->get('newsletter_config');
            return new NewsletterFeed(false);
        });
        
        // Mailup - Singleton
        $this->register('mailup', function() {
            return new Mailup();
        }, true);
    }
    
    /**
     * Configura i servizi di orchestrazione
     */
    private function configureOrchestrationServices(): void {
        // FeedGenerator - Singleton
        $this->register('feed_generator', function($container) {
            return new FeedGenerator(
                $container->get('query_builder'),
                $container->get('post_exclusion_manager'),
                $container->get('post_template_processor'),
                $container->get('rss_formatter'),
                $container->get('xml_file_manager')
            );
        }, true);
        
        // XMLGenerationService - Singleton
        $this->register('xml_generation_service', function($container) {
            return new XMLGenerationService(
                $container->get('feed_generator'),
                $container->get('xml_file_manager')
            );
        }, true);
        
        // NewsletterSendingService - Singleton
        $this->register('newsletter_sending_service', function($container) {
            return new NewsletterSendingService(
                $container->get('mailup')
            );
        }, true);
        
        // NewsletterOrchestrator - Singleton
        $this->register('newsletter_orchestrator', function($container) {
            return new NewsletterOrchestrator(
                $container->get('xml_generation_service'),
                $container->get('newsletter_sending_service'),
                $container->get('newsletter_feed')
            );
        }, true);
    }
}
