<?php

declare(strict_types=1);

namespace App\Shared\Infrastructure\Tenant;

use InvalidArgumentException;

use function is_array;

use const JSON_THROW_ON_ERROR;

/**
 * Factory to create TenantRegistry from configuration arrays.
 * Used for dev/test (YAML config) and prod (env var JSON).
 */
final readonly class TenantRegistryFactory
{
    /**
     * Creates registry from YAML configuration array (dev/test).
     *
     * @param array<array{tenantId: string, subdomain: string, databaseUrl: string}> $configs
     */
    public function createFromConfig(array $configs): TenantRegistry
    {
        return new InMemoryTenantRegistry($this->parseConfigs($configs));
    }

    /**
     * Creates registry from JSON environment variable (prod).
     *
     * Expected format: [{"tenantId":"uuid","subdomain":"ecole","databaseUrl":"postgres://..."}]
     */
    public function createFromEnv(string $configsJson): TenantRegistry
    {
        if ($configsJson === '') {
            return new InMemoryTenantRegistry([]);
        }

        $decoded = json_decode($configsJson, true, 512, JSON_THROW_ON_ERROR);

        if (!is_array($decoded)) {
            throw new InvalidArgumentException('TENANT_CONFIGS must be a JSON array');
        }

        /** @var array<array{tenantId: string, subdomain: string, databaseUrl: string}> $configs */
        $configs = $decoded;

        return new InMemoryTenantRegistry($this->parseConfigs($configs));
    }

    /**
     * @param array<array{tenantId: string, subdomain: string, databaseUrl: string}> $configs
     *
     * @return TenantConfig[]
     */
    private function parseConfigs(array $configs): array
    {
        $tenantConfigs = [];

        foreach ($configs as $config) {
            $tenantConfigs[] = new TenantConfig(
                tenantId: TenantId::fromString($config['tenantId']),
                subdomain: $config['subdomain'],
                databaseUrl: $config['databaseUrl'],
            );
        }

        return $tenantConfigs;
    }
}
