<?php

namespace WPUltimateSecurity\UltimateSecurity\Infrastructure\Container;

use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsInterface;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsRepository;

/**
 * Container Builder
 *
 * Fluent builder for configuring and building the service container.
 * Provides a clean API for registering core services and allowing
 * plugins to extend the container.
 *
 * Usage:
 * ```php
 * $container = ContainerBuilder::create()
 *     ->registerCoreServices()
 *     ->register(function ($container) {
 *         $container->singleton(MyService::class, fn($c) => new MyService());
 *     })
 *     ->build();
 * ```
 *
 * @package WPUltimateSecurity\UltimateSecurity\Infrastructure\Container
 * @since 2.0.0
 */
class ContainerBuilder
{
    /**
     * The container instance being built.
     *
     * @var Container
     */
    private Container $container;

    /**
     * Registration callbacks to be executed.
     *
     * @var array<callable>
     */
    private array $registrations = [];

    /**
     * Whether core services have been registered.
     *
     * @var bool
     */
    private bool $coreServicesRegistered = false;

    /**
     * Private constructor - use create() static method.
     */
    private function __construct()
    {
        $this->container = Container::getInstance();
    }

    /**
     * Create a new builder instance.
     *
     * @return self
     */
    public static function create(): self
    {
        return new self();
    }

    /**
     * Register core plugin services.
     *
     * @return self
     */
    public function registerCoreServices(): self
    {
        if ($this->coreServicesRegistered) {
            return $this;
        }

        // Settings Repository (singleton)
        $this->container->singleton(SettingsInterface::class, function () {
            return SettingsRepository::getInstance();
        });

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

        // Allow plugins to extend core services
        do_action('ultimate_security_container_core_services', $this->container);

        $this->coreServicesRegistered = true;

        return $this;
    }

    /**
     * Register additional services via callback.
     *
     * @param callable $callback A callback that receives the container.
     *
     * @return self
     */
    public function register(callable $callback): self
    {
        $this->registrations[] = $callback;

        return $this;
    }

    /**
     * Register a singleton service.
     *
     * @param string   $id       The service identifier.
     * @param callable $resolver The resolver callback.
     *
     * @return self
     */
    public function singleton(string $id, callable $resolver): self
    {
        $this->container->singleton($id, $resolver);

        return $this;
    }

    /**
     * Register a factory binding.
     *
     * @param string   $id       The service identifier.
     * @param callable $resolver The resolver callback.
     *
     * @return self
     */
    public function bind(string $id, callable $resolver): self
    {
        $this->container->bind($id, $resolver);

        return $this;
    }

    /**
     * Register an existing instance.
     *
     * @param string $id       The service identifier.
     * @param mixed  $instance The instance to register.
     *
     * @return self
     */
    public function instance(string $id, mixed $instance): self
    {
        $this->container->instance($id, $instance);

        return $this;
    }

    /**
     * Create an alias.
     *
     * @param string $alias    The alias name.
     * @param string $abstract The target binding.
     *
     * @return self
     */
    public function alias(string $alias, string $abstract): self
    {
        $this->container->alias($alias, $abstract);

        return $this;
    }

    /**
     * Build and return the configured container.
     *
     * @return Container
     */
    public function build(): Container
    {
        // Execute all registration callbacks
        foreach ($this->registrations as $callback) {
            $callback($this->container);
        }

        // Allow final modifications via hook
        do_action('ultimate_security_container_built', $this->container);

        return $this->container;
    }

    /**
     * Get the container being built (for inspection).
     *
     * @return Container
     */
    public function getContainer(): Container
    {
        return $this->container;
    }
}
