<?php

namespace WPUltimateSecurity\UltimateSecurity\Bootstrap\Providers;

use WPUltimateSecurity\UltimateSecurity\Config\ConfigLoader;
use WPUltimateSecurity\UltimateSecurity\Contracts\ServiceProviderInterface;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Container\Container;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsInterface;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsRepository;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsService;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\ApiKeyCryptoService;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\CryptoHelper;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\DateHelper;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\IpHelper;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\StringHelper;

/**
 * Container Service Provider
 *
 * Registers core services in the dependency injection container.
 * This provider runs first to ensure all services are available
 * to other providers.
 *
 * @package WPUltimateSecurity\UltimateSecurity\Bootstrap\Providers
 * @since 2.0.0
 */
class ContainerServiceProvider implements ServiceProviderInterface
{
    /**
     * Register core services in the container.
     *
     * @return void
     */
    public function register(): void
    {
        $container = Container::getInstance();

        $this->registerSettings($container);
        $this->registerConfig($container);
        $this->registerHelpers($container);

        // Allow Pro plugin and other extensions to register services
        do_action('ultimate_security_container_services', $container);
    }

    /**
     * Register settings-related services.
     *
     * @param Container $container The container instance.
     *
     * @return void
     */
    private function registerSettings(Container $container): void
    {
        // Settings Repository (singleton)
        $container->singleton(SettingsInterface::class, function () {
            return SettingsRepository::getInstance();
        });

        // Aliases for convenience
        $container->alias('settings', SettingsInterface::class);
        $container->alias(SettingsRepository::class, SettingsInterface::class);

        // Settings Service (singleton) - high-level API
        $container->singleton(SettingsService::class, function () {
            return SettingsService::getInstance();
        });

        $container->alias('settings.service', SettingsService::class);
    }

    /**
     * Register configuration services.
     *
     * @param Container $container The container instance.
     *
     * @return void
     */
    private function registerConfig(Container $container): void
    {
        // Config Loader (singleton - uses static caching internally)
        $container->singleton(ConfigLoader::class, function () {
            return new ConfigLoader();
        });

        $container->alias('config', ConfigLoader::class);
    }

    /**
     * Register helper services.
     *
     * @param Container $container The container instance.
     *
     * @return void
     */
    private function registerHelpers(Container $container): void
    {
        // IP Helper (singleton)
        $container->singleton(IpHelper::class, function () {
            return new IpHelper();
        });

        // Date Helper (singleton)
        $container->singleton(DateHelper::class, function () {
            return new DateHelper();
        });

        // String Helper (singleton)
        $container->singleton(StringHelper::class, function () {
            return new StringHelper();
        });

        // Crypto Helper (singleton)
        $container->singleton(CryptoHelper::class, function () {
            return new CryptoHelper();
        });

        // API Key Crypto Service (singleton)
        $container->singleton(ApiKeyCryptoService::class, function () {
            return new ApiKeyCryptoService();
        });

        // Aliases
        $container->alias('ip', IpHelper::class);
        $container->alias('date', DateHelper::class);
        $container->alias('string', StringHelper::class);
        $container->alias('crypto', CryptoHelper::class);
    }
}
