<?php

declare(strict_types=1);

namespace App\Tests\Unit\Shared\Infrastructure\Tenant;

use App\Shared\Infrastructure\Tenant\InMemoryTenantRegistry;
use App\Shared\Infrastructure\Tenant\TenantConfig;
use App\Shared\Infrastructure\Tenant\TenantId;
use App\Shared\Infrastructure\Tenant\TenantNotFoundException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

#[CoversClass(InMemoryTenantRegistry::class)]
final class InMemoryTenantRegistryTest extends TestCase
{
    #[Test]
    public function itReturnsConfigByTenantId(): void
    {
        $tenantId = TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
        $config = new TenantConfig(
            tenantId: $tenantId,
            subdomain: 'ecole-alpha',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_alpha',
        );

        $registry = new InMemoryTenantRegistry([$config]);

        $result = $registry->getConfig($tenantId);

        self::assertSame($config, $result);
    }

    #[Test]
    public function itReturnsConfigBySubdomain(): void
    {
        $tenantId = TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
        $config = new TenantConfig(
            tenantId: $tenantId,
            subdomain: 'ecole-alpha',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_alpha',
        );

        $registry = new InMemoryTenantRegistry([$config]);

        $result = $registry->getBySubdomain('ecole-alpha');

        self::assertSame($config, $result);
    }

    #[Test]
    public function itThrowsExceptionForUnknownTenantId(): void
    {
        $registry = new InMemoryTenantRegistry([]);

        $this->expectException(TenantNotFoundException::class);

        $registry->getConfig(TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890'));
    }

    #[Test]
    public function itThrowsExceptionForUnknownSubdomain(): void
    {
        $registry = new InMemoryTenantRegistry([]);

        $this->expectException(TenantNotFoundException::class);

        $registry->getBySubdomain('ecole-inexistant');
    }

    #[Test]
    public function itChecksIfTenantExists(): void
    {
        $config = new TenantConfig(
            tenantId: TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890'),
            subdomain: 'ecole-alpha',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_alpha',
        );

        $registry = new InMemoryTenantRegistry([$config]);

        self::assertTrue($registry->exists('ecole-alpha'));
        self::assertFalse($registry->exists('ecole-inexistant'));
    }

    #[Test]
    public function itSupportsMultipleTenants(): void
    {
        $configAlpha = new TenantConfig(
            tenantId: TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890'),
            subdomain: 'ecole-alpha',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_alpha',
        );
        $configBeta = new TenantConfig(
            tenantId: TenantId::fromString('b2c3d4e5-f6a7-8901-bcde-f12345678901'),
            subdomain: 'ecole-beta',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_beta',
        );

        $registry = new InMemoryTenantRegistry([$configAlpha, $configBeta]);

        self::assertSame($configAlpha, $registry->getBySubdomain('ecole-alpha'));
        self::assertSame($configBeta, $registry->getBySubdomain('ecole-beta'));
    }
}
