<?php

namespace MintyPHP\Tests\Service\Settings;

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

class SettingsUserLifecycleGatewayTest extends TestCase
{
    public function testSetUserInactivityDeleteDaysRequiresDeactivatePolicy(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            if ($key === 'user_inactivity_deactivate_days') {
                return '0';
            }
            return null;
        });
        $settings->expects($this->never())->method('set');

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertFalse($gateway->setUserInactivityDeleteDays(30));
    }

    public function testSetUserInactivityDeactivateDaysSetsDeleteToZeroWhenDisabled(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->expects($this->exactly(2))->method('set')->willReturn(true);

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertTrue($gateway->setUserInactivityDeactivateDays(0));
    }

    public function testSetUserInactivityDeactivateDaysReturnsFalseWhenDeleteResetFails(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->expects($this->once())
            ->method('set')
            ->with('user_inactivity_delete_days', '0', 'setting.user_inactivity_delete_days')
            ->willReturn(false);

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertFalse($gateway->setUserInactivityDeactivateDays(0));
    }

    public function testGetUserInactivityDeleteDaysReturnsZeroWhenDeactivateDisabled(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            if ($key === 'user_inactivity_deactivate_days') {
                return '0';
            }
            if ($key === 'user_inactivity_delete_days') {
                return '180';
            }
            return null;
        });

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(0, $gateway->getUserInactivityDeleteDays());
    }

    public function testGetUserInactivityDeleteDaysFallsBackWhenStoredValueIsInvalid(): void
    {
        $settings = $this->createMock(SettingRepositoryInterface::class);
        $settings->method('getValue')->willReturnCallback(static function (string $key): ?string {
            if ($key === 'user_inactivity_deactivate_days') {
                return '180';
            }
            if ($key === 'user_inactivity_delete_days') {
                return '99999';
            }
            return null;
        });

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertSame(365, $gateway->getUserInactivityDeleteDays());
    }

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

        $gateway = new SettingsUserLifecycleGateway(new SettingsMetadataGateway($settings));
        $this->assertFalse($gateway->setUserInactivityDeleteDays(3651));
    }
}
