<?php

namespace MintyPHP\Tests\Service\Settings;

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

class SettingsSessionGatewayTest extends TestCase
{
    public function testGetSessionIdleTimeoutMinutesDefaultsTo30WhenNoSetting(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturn(null);

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(30, $gateway->getSessionIdleTimeoutMinutes());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(60, $gateway->getSessionIdleTimeoutMinutes());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(30, $gateway->getSessionIdleTimeoutMinutes());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(30, $gateway->getSessionIdleTimeoutMinutes());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertFalse($gateway->setSessionIdleTimeoutMinutes(3));
    }

    public function testGetSessionAbsoluteTimeoutHoursDefaultsTo8(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturn(null);

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(8, $gateway->getSessionAbsoluteTimeoutHours());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(12, $gateway->getSessionAbsoluteTimeoutHours());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(3600, $gateway->getSessionIdleTimeoutSeconds());
    }

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

        $gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(43200, $gateway->getSessionAbsoluteTimeoutSeconds());
    }
}
