<?php

declare(strict_types=1);

namespace App\Framework\Redis;

use InvalidArgumentException;

/**
 * Redis connection pool that manages multiple named connections
 * for different purposes (cache, queue, sessions, etc.)
 */
final class RedisConnectionPool
{
    /** @var array<string, RedisConnectionInterface> */
    private array $connections = [];

    /** @var array<string, RedisConfig> */
    private array $configs = [];

    /**
     * Register a connection configuration
     */
    public function registerConnection(string $name, RedisConfig $config): void
    {
        $this->configs[$name] = $config;
    }

    /**
     * Get a connection by name, creating it if it doesn't exist
     */
    public function getConnection(string $name = 'default'): RedisConnectionInterface
    {
        if (! isset($this->connections[$name])) {
            if (! isset($this->configs[$name])) {
                throw new InvalidArgumentException("Redis connection '{$name}' is not configured");
            }

            $this->connections[$name] = new RedisConnection($this->configs[$name], $name);
        }

        return $this->connections[$name];
    }

    /**
     * Get connection specifically for caching
     */
    public function getCacheConnection(): RedisConnectionInterface
    {
        return $this->getConnection('cache');
    }

    /**
     * Get connection specifically for queues
     */
    public function getQueueConnection(): RedisConnectionInterface
    {
        return $this->getConnection('queue');
    }

    /**
     * Get connection specifically for sessions
     */
    public function getSessionConnection(): RedisConnectionInterface
    {
        return $this->getConnection('session');
    }

    /**
     * Check if a connection is registered
     */
    public function hasConnection(string $name): bool
    {
        return isset($this->configs[$name]);
    }

    /**
     * Get all registered connection names
     * @return string[]
     */
    public function getConnectionNames(): array
    {
        return array_keys($this->configs);
    }

    /**
     * Remove a connection (will be recreated on next access)
     */
    public function removeConnection(string $name): void
    {
        unset($this->connections[$name]);
    }

    /**
     * Close all connections
     */
    public function closeAll(): void
    {
        $this->connections = [];
    }

    /**
     * Get connection health status for all connections
     * @return array<string, bool>
     */
    public function getHealthStatus(): array
    {
        $status = [];

        foreach ($this->configs as $name => $config) {
            try {
                $connection = $this->getConnection($name);
                $status[$name] = $connection->isConnected();
            } catch (RedisConnectionException) {
                $status[$name] = false;
            }
        }

        return $status;
    }
}
