<?php

declare(strict_types=1);

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

use App\Shared\Infrastructure\Tenant\TenantConfig;
use App\Shared\Infrastructure\Tenant\TenantContext;
use App\Shared\Infrastructure\Tenant\TenantId;
use App\Shared\Infrastructure\Tenant\TenantNotSetException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

#[CoversClass(TenantContext::class)]
final class TenantContextTest extends TestCase
{
    #[Test]
    public function itCanSetAndRetrieveCurrentTenant(): 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',
        );

        $context = new TenantContext();
        $context->setCurrentTenant($config);

        self::assertTrue($tenantId->equals($context->getCurrentTenantId()));
        self::assertSame($config, $context->getCurrentTenantConfig());
    }

    #[Test]
    public function itThrowsExceptionWhenNoTenantIsSet(): void
    {
        $context = new TenantContext();

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

        $context->getCurrentTenantId();
    }

    #[Test]
    public function itThrowsExceptionWhenGettingConfigWithNoTenantSet(): void
    {
        $context = new TenantContext();

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

        $context->getCurrentTenantConfig();
    }

    #[Test]
    public function itCanCheckIfTenantIsSet(): void
    {
        $context = new TenantContext();

        self::assertFalse($context->hasTenant());

        $config = new TenantConfig(
            tenantId: TenantId::fromString('a1b2c3d4-e5f6-7890-abcd-ef1234567890'),
            subdomain: 'ecole-alpha',
            databaseUrl: 'postgresql://user:pass@localhost:5432/classeo_alpha',
        );
        $context->setCurrentTenant($config);

        self::assertTrue($context->hasTenant());
    }

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

        $context = new TenantContext();
        $context->setCurrentTenant($config);

        self::assertTrue($context->hasTenant());

        $context->clear();

        self::assertFalse($context->hasTenant());
    }
}
