<?php

declare(strict_types=1);

namespace App\Framework\MachineLearning\ModelManagement;

use App\Framework\DI\Container;
use App\Framework\Database\ConnectionInterface;
use App\Framework\DI\Initializer;
use App\Framework\Random\SecureRandomGenerator;
use App\Framework\Notification\NotificationDispatcher;

/**
 * ML Model Management Initializer
 *
 * Registers all ML Model Management services in the DI container.
 *
 * Registered Services:
 * - ModelRegistry (DatabaseModelRegistry)
 * - ABTestingService
 * - ModelPerformanceMonitor
 * - AutoTuningEngine
 * - PerformanceStorage (DatabasePerformanceStorage)
 * - AlertingService (LogAlertingService)
 */
final readonly class MLModelManagementInitializer
{
    public function __construct(
        private Container $container
    ) {}

    #[Initializer]
    public function initialize(): void
    {
        // Register MLConfig as singleton
        $this->container->singleton(
            MLConfig::class,
            fn(Container $c) => MLConfig::fromEnvironment()
        );

        // Register ModelRegistry as singleton (Database-backed)
        $this->container->singleton(
            ModelRegistry::class,
            fn(Container $c) => new DatabaseModelRegistry(
                connection: $c->get(ConnectionInterface::class)
            )
        );

        // Register PerformanceStorage as singleton (Database-backed)
        $this->container->singleton(
            PerformanceStorage::class,
            fn(Container $c) => new DatabasePerformanceStorage(
                connection: $c->get(ConnectionInterface::class)
            )
        );

        // Register AlertingService as singleton (Notification-based)
        $this->container->singleton(
            AlertingService::class,
            fn(Container $c) => new NotificationAlertingService(
                dispatcher: $c->get(NotificationDispatcher::class),
                config: $c->get(MLConfig::class),
                adminRecipientId: 'admin'
            )
        );

        // Register ABTestingService
        $this->container->bind(
            ABTestingService::class,
            fn(Container $c) => new ABTestingService(
                random: $c->get(SecureRandomGenerator::class),
                registry: $c->get(ModelRegistry::class)
            )
        );

        // Register ModelPerformanceMonitor
        $this->container->bind(
            ModelPerformanceMonitor::class,
            fn(Container $c) => new ModelPerformanceMonitor(
                registry: $c->get(ModelRegistry::class),
                storage: $c->get(PerformanceStorage::class),
                alerting: $c->get(AlertingService::class),
                config: $c->get(MLConfig::class)
            )
        );

        // Register AutoTuningEngine
        $this->container->bind(
            AutoTuningEngine::class,
            fn(Container $c) => new AutoTuningEngine(
                performanceMonitor: $c->get(ModelPerformanceMonitor::class),
                registry: $c->get(ModelRegistry::class),
                storage: $c->get(PerformanceStorage::class)
            )
        );
    }
}
