<?php

namespace MintyPHP\Tests\Service\Settings;

use MintyPHP\Repository\Settings\SettingRepositoryInterface;
use MintyPHP\Service\Settings\SettingsMetadataGateway;
use MintyPHP\Service\Settings\SettingsSmtpGateway;
use PHPUnit\Framework\TestCase;

class SettingsSmtpGatewayTest extends TestCase
{
    public function testGetSmtpHostReturnsNullWhenEmpty(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return null;
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertNull($gateway->getSmtpHost());
    }

    public function testGetSmtpHostReturnsTrimedValue(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_host' => '  mail.example.com  ',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertSame('mail.example.com', $gateway->getSmtpHost());
    }

    public function testGetSmtpPortReturnsNullWhenEmpty(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_port' => '',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertNull($gateway->getSmtpPort());
    }

    public function testGetSmtpPortReturnsValidPort(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_port' => '587',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(587, $gateway->getSmtpPort());
    }

    public function testGetSmtpPortReturnsNullForZero(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_port' => '0',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertNull($gateway->getSmtpPort());
    }

    public function testGetSmtpSecureReturnsNullForNone(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_secure' => 'none',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertNull($gateway->getSmtpSecure());
    }

    public function testGetSmtpSecureReturnsTls(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_secure' => '  TLS  ',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertSame('tls', $gateway->getSmtpSecure());
    }

    public function testGetSmtpSecureReturnsNullForInvalidValue(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            return match ($key) {
                'smtp_secure' => 'starttls',
                default => null,
            };
        });

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertNull($gateway->getSmtpSecure());
    }

    public function testSetSmtpPortRejectsNegativePort(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturn(null);
        $settings->expects($this->once())
            ->method('set')
            ->with('smtp_port', null, 'setting.smtp_port')
            ->willReturn(true);

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        // Negative port is treated as invalid; set stores null (clears the setting)
        $this->assertTrue($gateway->setSmtpPort(-1));
    }

    public function testSetSmtpSecureRejectsInvalidValue(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->expects($this->never())->method('set');

        $gateway = new SettingsSmtpGateway(new SettingsMetadataGateway($settings));
        $this->assertFalse($gateway->setSmtpSecure('starttls'));
    }
}
