<?php

namespace MintyPHP\Tests\Service\Settings;

use MintyPHP\Service\Settings\SettingsLoginPersistenceGateway;
use MintyPHP\Service\Settings\SettingsMetadataGateway;
use PHPUnit\Framework\TestCase;

class SettingsLoginPersistenceGatewayTest extends TestCase
{
    // ---------------------------------------------------------------
    // isMicrosoftAutoRememberDefault
    // ---------------------------------------------------------------

    public function testAutoRememberDefaultReturnsFalseWhenNotSet(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getValue')->willReturn(null);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertFalse($gateway->isMicrosoftAutoRememberDefault());
    }

    public function testAutoRememberDefaultReturnsFalseForZero(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getValue')->willReturn('0');

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertFalse($gateway->isMicrosoftAutoRememberDefault());
    }

    public function testAutoRememberDefaultReturnsTrueForOne(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getValue')->willReturn('1');

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertTrue($gateway->isMicrosoftAutoRememberDefault());
    }

    public function testAutoRememberDefaultReturnsFalseForEmptyString(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getValue')->willReturn('');

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertFalse($gateway->isMicrosoftAutoRememberDefault());
    }

    public function testSetAutoRememberDefaultPersistsValue(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->once())
            ->method('set')
            ->with('microsoft_auto_remember_default', '1', $this->anything())
            ->willReturn(true);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertTrue($gateway->setMicrosoftAutoRememberDefault(true));
    }

    public function testSetAutoRememberDefaultPersistsFalseAsZero(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->once())
            ->method('set')
            ->with('microsoft_auto_remember_default', '0', $this->anything())
            ->willReturn(true);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertTrue($gateway->setMicrosoftAutoRememberDefault(false));
    }

    // ---------------------------------------------------------------
    // getRememberTokenLifetimeDays
    // ---------------------------------------------------------------

    public function testLifetimeDaysReturnsFallbackWhenNotSet(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(null);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(30, $gateway->getRememberTokenLifetimeDays());
    }

    public function testLifetimeDaysReturnsConfiguredValue(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(7);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(7, $gateway->getRememberTokenLifetimeDays());
    }

    public function testLifetimeDaysReturnsFallbackForZero(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(0);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(30, $gateway->getRememberTokenLifetimeDays());
    }

    public function testLifetimeDaysReturnsFallbackForValueAboveMax(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(500);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(30, $gateway->getRememberTokenLifetimeDays());
    }

    public function testSetLifetimeDaysAcceptsValidRange(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->once())
            ->method('set')
            ->with('remember_token_lifetime_days', '14', $this->anything())
            ->willReturn(true);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertTrue($gateway->setRememberTokenLifetimeDays(14));
    }

    public function testSetLifetimeDaysRejectsZero(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->never())->method('set');

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertFalse($gateway->setRememberTokenLifetimeDays(0));
    }

    public function testSetLifetimeDaysRejectsAboveMax(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->never())->method('set');

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertFalse($gateway->setRememberTokenLifetimeDays(400));
    }

    public function testSetLifetimeDaysNullFallsBackToDefault(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->expects($this->once())
            ->method('set')
            ->with('remember_token_lifetime_days', '30', $this->anything())
            ->willReturn(true);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertTrue($gateway->setRememberTokenLifetimeDays(null));
    }

    // ---------------------------------------------------------------
    // getRememberTokenLifetimeSeconds
    // ---------------------------------------------------------------

    public function testLifetimeSecondsComputesCorrectly(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(7);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(7 * 86400, $gateway->getRememberTokenLifetimeSeconds());
    }

    public function testLifetimeSecondsFallbackIs30Days(): void
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getInt')->willReturn(null);

        $gateway = new SettingsLoginPersistenceGateway($metadata);
        $this->assertSame(30 * 86400, $gateway->getRememberTokenLifetimeSeconds());
    }
}
