<?php

namespace MintyPHP\Tests\Module\Helpdesk\Service;

use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Module\Helpdesk\Service\EffectiveHelpdeskSettingsService;
use MintyPHP\Module\Helpdesk\Service\HelpdeskSettingsGateway;
use MintyPHP\Module\Helpdesk\Service\HelpdeskTenantSettingsGateway;
use PHPUnit\Framework\TestCase;

class EffectiveHelpdeskSettingsServiceTest extends TestCase
{
    private function createResolver(
        int $tenantId = 0,
        bool $overrideEnabled = false,
        ?string $tenantAuthMode = null,
        ?string $tenantOdataUrl = null,
        ?string $tenantCompanyName = null,
    ): EffectiveHelpdeskSettingsService {
        $globalGateway = $this->createMock(HelpdeskSettingsGateway::class);
        $globalGateway->method('getAuthMode')->willReturn(HelpdeskSettingsGateway::AUTH_MODE_BASIC);
        $globalGateway->method('getODataBaseUrl')->willReturn('https://global.example.com/ODataV4');
        $globalGateway->method('getCompanyName')->willReturn('Global Company');
        $globalGateway->method('getBasicUser')->willReturn('global-user');
        $globalGateway->method('getBasicPassword')->willReturn('global-pass');
        $globalGateway->method('getOAuthTenantId')->willReturn(null);
        $globalGateway->method('getOAuthClientId')->willReturn(null);
        $globalGateway->method('getOAuthClientSecret')->willReturn(null);
        $globalGateway->method('getOAuthTokenEndpoint')->willReturn(null);

        $tenantGateway = $this->createMock(HelpdeskTenantSettingsGateway::class);
        $tenantGateway->method('isOverrideEnabled')->willReturn($overrideEnabled);
        $tenantGateway->method('getAuthMode')->willReturn($tenantAuthMode ?? HelpdeskSettingsGateway::AUTH_MODE_OAUTH2);
        $tenantGateway->method('getODataBaseUrl')->willReturn($tenantOdataUrl ?? 'https://tenant.example.com/ODataV4');
        $tenantGateway->method('getCompanyName')->willReturn($tenantCompanyName ?? 'Tenant Company');
        $tenantGateway->method('getBasicUser')->willReturn('tenant-user');
        $tenantGateway->method('getBasicPassword')->willReturn('tenant-pass');
        $tenantGateway->method('getOAuthTenantId')->willReturn('azure-tenant-123');
        $tenantGateway->method('getOAuthClientId')->willReturn('client-abc');
        $tenantGateway->method('getOAuthClientSecret')->willReturn('secret-xyz');
        $tenantGateway->method('getOAuthTokenEndpoint')->willReturn('https://login.microsoftonline.com/tenant/oauth2/v2.0/token');
        $tenantGateway->method('getSystemRecommendationsConfig')->willReturn(null);
        $tenantGateway->method('getControllingRiskConfig')->willReturn(null);

        $sessionStore = $this->createMock(SessionStoreInterface::class);
        $sessionStore->method('all')->willReturn([
            'current_tenant' => $tenantId > 0 ? ['id' => $tenantId] : [],
        ]);

        return new EffectiveHelpdeskSettingsService($globalGateway, $tenantGateway, $sessionStore);
    }

    public function testFallsBackToGlobalWhenNoTenantInSession(): void
    {
        $resolver = $this->createResolver(tenantId: 0);
        $settings = $resolver->resolveForCurrentTenant();

        $this->assertSame('global', $settings->source);
        $this->assertSame('https://global.example.com/ODataV4', $settings->odataBaseUrl);
        $this->assertSame('Global Company', $settings->companyName);
        $this->assertSame('global-user', $settings->basicUser);
    }

    public function testFallsBackToGlobalWhenOverrideDisabled(): void
    {
        $resolver = $this->createResolver(tenantId: 5, overrideEnabled: false);
        $settings = $resolver->resolveForCurrentTenant();

        $this->assertSame('global', $settings->source);
        $this->assertSame('https://global.example.com/ODataV4', $settings->odataBaseUrl);
        $this->assertSame(HelpdeskSettingsGateway::AUTH_MODE_BASIC, $settings->authMode);
    }

    public function testUsesTenantConfigWhenOverrideEnabled(): void
    {
        $resolver = $this->createResolver(tenantId: 5, overrideEnabled: true);
        $settings = $resolver->resolveForCurrentTenant();

        $this->assertSame('tenant', $settings->source);
        $this->assertSame('https://tenant.example.com/ODataV4', $settings->odataBaseUrl);
        $this->assertSame('Tenant Company', $settings->companyName);
        $this->assertSame(HelpdeskSettingsGateway::AUTH_MODE_OAUTH2, $settings->authMode);
        $this->assertSame('client-abc', $settings->oauthClientId);
        $this->assertSame('secret-xyz', $settings->oauthClientSecret);
    }

    public function testResolveForTenantDirectly(): void
    {
        $resolver = $this->createResolver(tenantId: 0, overrideEnabled: true);
        // Calling resolveForTenant directly with a tenant ID, ignoring session
        $settings = $resolver->resolveForTenant(5);

        $this->assertSame('tenant', $settings->source);
        $this->assertSame('Tenant Company', $settings->companyName);
    }

    public function testResolveForTenantFallsBackForZeroId(): void
    {
        $resolver = $this->createResolver(tenantId: 0, overrideEnabled: true);
        $settings = $resolver->resolveForTenant(0);

        $this->assertSame('global', $settings->source);
    }

    public function testProxyMethodsReturnResolvedValues(): void
    {
        $resolver = $this->createResolver(tenantId: 5, overrideEnabled: true);

        $this->assertSame(HelpdeskSettingsGateway::AUTH_MODE_OAUTH2, $resolver->getAuthMode());
        $this->assertSame('https://tenant.example.com/ODataV4', $resolver->getODataBaseUrl());
        $this->assertSame('Tenant Company', $resolver->getCompanyName());
        $this->assertSame('client-abc', $resolver->getOAuthClientId());
        $this->assertSame('secret-xyz', $resolver->getOAuthClientSecret());
        $this->assertTrue($resolver->isConfigured());
    }

    public function testBuildEntityUrlUsesResolvedConfig(): void
    {
        $resolver = $this->createResolver(tenantId: 5, overrideEnabled: true, tenantCompanyName: 'Acme');
        $url = $resolver->buildEntityUrl('Customers');

        $this->assertStringContainsString('tenant.example.com', $url);
        $this->assertStringContainsString('Acme', $url);
        $this->assertStringContainsString('Customers', $url);
    }

    public function testValueObjectIsConfiguredWithBasicAuth(): void
    {
        $resolver = $this->createResolver(
            tenantId: 5,
            overrideEnabled: true,
            tenantAuthMode: HelpdeskSettingsGateway::AUTH_MODE_BASIC,
        );
        $settings = $resolver->resolveForCurrentTenant();

        // Tenant basic user/password are set, so it should be configured
        $this->assertTrue($settings->isConfigured());
        $this->assertSame([], $settings->validateConfiguration());
    }
}
