<?php

namespace MintyPHP\Tests\Service\Settings;

use MintyPHP\Repository\Access\RoleRepositoryInterface;
use MintyPHP\Repository\Org\DepartmentRepositoryInterface;
use MintyPHP\Repository\Settings\SettingRepositoryInterface;
use MintyPHP\Repository\Tenant\TenantRepositoryInterface;
use MintyPHP\Service\Settings\SettingsDefaultsGateway;
use MintyPHP\Service\Settings\SettingsMetadataGateway;
use PHPUnit\Framework\TestCase;

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

        $tenantRepository = $this->createMock(TenantRepositoryInterface::class);
        $tenantRepository->expects($this->once())->method('find')->with(99)->willReturn(null);

        $gateway = $this->newGateway($settings, $tenantRepository);
        $this->assertFalse($gateway->setDefaultTenantId(99));
    }

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

        $roleRepository = $this->createMock(RoleRepositoryInterface::class);
        $roleRepository->expects($this->once())->method('find')->with(55)->willReturn(null);

        $gateway = $this->newGateway($settings, null, $roleRepository);
        $this->assertFalse($gateway->setDefaultRoleId(55));
    }

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

        $departmentRepository = $this->createMock(DepartmentRepositoryInterface::class);
        $departmentRepository->expects($this->once())->method('find')->with(77)->willReturn(null);

        $gateway = $this->newGateway($settings, null, null, $departmentRepository);
        $this->assertFalse($gateway->setDefaultDepartmentId(77));
    }

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

        $tenantRepository = $this->createMock(TenantRepositoryInterface::class);
        $tenantRepository->method('find')->willReturn(['id' => 5]);

        $roleRepository = $this->createMock(RoleRepositoryInterface::class);
        $roleRepository->method('find')->willReturn(['id' => 6]);

        $departmentRepository = $this->createMock(DepartmentRepositoryInterface::class);
        $departmentRepository->method('find')->willReturn(['id' => 7]);

        $gateway = $this->newGateway($settings, $tenantRepository, $roleRepository, $departmentRepository);
        $this->assertTrue($gateway->setDefaultTenantId(5));
        $this->assertTrue($gateway->setDefaultRoleId(6));
        $this->assertTrue($gateway->setDefaultDepartmentId(7));
    }

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

        $gateway = $this->newGateway($settings);
        $this->assertTrue($gateway->setDefaultTenantId(null));
        $this->assertTrue($gateway->setDefaultRoleId(null));
        $this->assertTrue($gateway->setDefaultDepartmentId(null));
    }

    private function newGateway(
        SettingRepositoryInterface $settingRepository,
        ?TenantRepositoryInterface $tenantRepository = null,
        ?RoleRepositoryInterface $roleRepository = null,
        ?DepartmentRepositoryInterface $departmentRepository = null
    ): SettingsDefaultsGateway {
        $tenantRepository = $tenantRepository ?? $this->createMock(TenantRepositoryInterface::class);
        $roleRepository = $roleRepository ?? $this->createMock(RoleRepositoryInterface::class);
        $departmentRepository = $departmentRepository ?? $this->createMock(DepartmentRepositoryInterface::class);

        return new SettingsDefaultsGateway(
            new SettingsMetadataGateway($settingRepository),
            $tenantRepository,
            $roleRepository,
            $departmentRepository
        );
    }
}
