<?php
declare(strict_types=1);

namespace FreshCloud\Mail\Tests\BaseUtils;

use PHPUnit\Framework\TestCase;
use FreshCloud\Mail\BaseUtils\TextHelper;
use FreshCloud\Mail\BaseUtils\EmailAddress;
use FreshCloud\Mail\BaseUtils\DateHelper;

final class TextHelperTest extends TestCase
{
    public function testIsValidEmail(): void
    {
        $this->assertTrue(TextHelper::isValidEmail('user@example.com'));
        $this->assertFalse(TextHelper::isValidEmail('not-an-email'));
    }

    public function testTruncate(): void
    {
        // truncate(11, '...') = 'hello world' (no truncation needed)
        $this->assertEquals('hello world', TextHelper::truncate('hello world', 11));
        // truncate(8, '...') = 'hello...'
        $this->assertEquals('hello...', TextHelper::truncate('hello world', 8));
        // truncate(5, '...') = 'he...' (max 5 = 2 chars + 3-char ellipsis)
        $this->assertEquals('he...', TextHelper::truncate('hello world', 5));
    }

    public function testRandomTokenLength(): void
    {
        // randomToken(N) returns base64 of N random bytes (~1.33x N chars)
        $t = TextHelper::randomToken(16);
        // base64 of 16 bytes is 24 chars
        $this->assertEquals(24, strlen($t));
        $this->assertMatchesRegularExpression('/^[A-Za-z0-9+\/=]+$/', $t);
    }

    public function testDecodeHeaderPlain(): void
    {
        $this->assertEquals('Hello World', TextHelper::decodeHeader('Hello World'));
    }

    public function testDecodeHeaderEncoded(): void
    {
        $encoded = '=?utf-8?B?' . base64_encode('Hello World') . '?=';
        $this->assertEquals('Hello World', TextHelper::decodeHeader($encoded));
    }
}

final class EmailAddressTest extends TestCase
{
    public function testParseSimple(): void
    {
        $e = EmailAddress::parse('user@example.com');
        $this->assertEquals('user@example.com', $e->address);
        $this->assertNull($e->displayName);
    }

    public function testParseWithName(): void
    {
        $e = EmailAddress::parse('"John Doe" <john@example.com>');
        $this->assertEquals('john@example.com', $e->address);
        $this->assertEquals('John Doe', $e->displayName);
    }

    public function testToStringWithName(): void
    {
        $e = new EmailAddress('John Doe', 'john@example.com');
        $this->assertEquals('John Doe <john@example.com>', (string) $e);
    }

    public function testToStringWithoutName(): void
    {
        $e = new EmailAddress(null, 'john@example.com');
        $this->assertEquals('john@example.com', (string) $e);
    }
}

final class DateHelperTest extends TestCase
{
    public function testNowUtcReturnsImmutable(): void
    {
        $now = DateHelper::nowUtc();
        $this->assertInstanceOf(\DateTimeImmutable::class, $now);
        $this->assertEquals('UTC', $now->getTimezone()->getName());
    }

    public function testIso8601RoundTrip(): void
    {
        $original = DateHelper::nowUtc();
        $iso = DateHelper::toIso8601($original);
        $parsed = DateHelper::fromIso8601($iso);
        $this->assertEquals($original->format('c'), $parsed->format('c'));
    }
}
