<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Domain\Model\SchoolBranding;

use App\Administration\Domain\Exception\LogoUrlInvalideException;
use App\Administration\Domain\Model\SchoolBranding\LogoUrl;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class LogoUrlTest extends TestCase
{
    #[Test]
    public function constructWithValidHttpsUrl(): void
    {
        $url = new LogoUrl('https://s3.example.com/logos/school-logo.png');

        self::assertSame('https://s3.example.com/logos/school-logo.png', $url->value);
    }

    #[Test]
    public function constructWithValidHttpUrl(): void
    {
        $url = new LogoUrl('http://localhost:9000/logos/test.png');

        self::assertSame('http://localhost:9000/logos/test.png', $url->value);
    }

    #[Test]
    #[DataProvider('validUrlsProvider')]
    public function constructWithValidUrls(string $input): void
    {
        $url = new LogoUrl($input);

        self::assertSame($input, $url->value);
    }

    /**
     * @return iterable<string, array{string}>
     */
    public static function validUrlsProvider(): iterable
    {
        yield 'https with path' => ['https://s3.amazonaws.com/bucket/logos/school.png'];
        yield 'https with query' => ['https://cdn.example.com/logo.png?v=12345'];
        yield 'http localhost' => ['http://localhost:9000/logos/test.jpg'];
        yield 'https with subdomain' => ['https://storage.googleapis.com/classeo/logos/abc.png'];
    }

    #[Test]
    #[DataProvider('invalidUrlsProvider')]
    public function constructThrowsExceptionForInvalidUrl(string $invalidUrl): void
    {
        $this->expectException(LogoUrlInvalideException::class);

        new LogoUrl($invalidUrl);
    }

    /**
     * @return iterable<string, array{string}>
     */
    public static function invalidUrlsProvider(): iterable
    {
        yield 'empty string' => [''];
        yield 'not a url' => ['not-a-url'];
        yield 'just path' => ['/logos/school.png'];
        yield 'missing scheme' => ['s3.example.com/logo.png'];
        yield 'ftp scheme' => ['ftp://files.example.com/logo.png'];
    }

    #[Test]
    public function equalsReturnsTrueForSameValue(): void
    {
        $url1 = new LogoUrl('https://s3.example.com/logo.png');
        $url2 = new LogoUrl('https://s3.example.com/logo.png');

        self::assertTrue($url1->equals($url2));
    }

    #[Test]
    public function equalsReturnsFalseForDifferentValue(): void
    {
        $url1 = new LogoUrl('https://s3.example.com/logo1.png');
        $url2 = new LogoUrl('https://s3.example.com/logo2.png');

        self::assertFalse($url1->equals($url2));
    }

    #[Test]
    public function toStringReturnsValue(): void
    {
        $url = new LogoUrl('https://s3.example.com/logo.png');

        self::assertSame('https://s3.example.com/logo.png', (string) $url);
    }
}
