<?php

namespace MintyPHP\Tests\Module\Security\Service;

use MintyPHP\Module\Security\Service\SecurityBcSettingsGateway;
use MintyPHP\Service\Settings\SettingsCryptoGatewayInterface;
use MintyPHP\Service\Settings\SettingsMetadataGateway;
use PHPUnit\Framework\TestCase;

class SecurityBcSettingsGatewayTest extends TestCase
{
    /**
     * @param array<string, string> $values
     */
    private function makeGateway(array $values = []): SecurityBcSettingsGateway
    {
        $metadata = $this->createMock(SettingsMetadataGateway::class);
        $metadata->method('getValue')->willReturnCallback(static fn (string $key): ?string => $values[$key] ?? null);
        $metadata->method('set')->willReturn(true);

        $crypto = $this->createMock(SettingsCryptoGatewayInterface::class);
        $crypto->method('encryptString')->willReturnCallback(static fn (string $v): string => 'enc:' . $v);
        $crypto->method('decryptString')->willReturnCallback(static fn (string $v): string => str_replace('enc:', '', $v));

        return new SecurityBcSettingsGateway($metadata, $crypto);
    }

    public function testAuthModeDefaultsToBasic(): void
    {
        $gateway = $this->makeGateway();

        $this->assertSame(SecurityBcSettingsGateway::AUTH_MODE_BASIC, $gateway->getAuthMode());
    }

    public function testAuthModeReturnsOauth2WhenSet(): void
    {
        $gateway = $this->makeGateway([SecurityBcSettingsGateway::KEY_AUTH_MODE => 'oauth2']);

        $this->assertSame(SecurityBcSettingsGateway::AUTH_MODE_OAUTH2, $gateway->getAuthMode());
    }

    public function testBuildEntityUrlComposesCompanyAndEntity(): void
    {
        $gateway = $this->makeGateway([
            SecurityBcSettingsGateway::KEY_ODATA_BASE_URL => 'https://bc.example.com/ODataV4/',
            SecurityBcSettingsGateway::KEY_COMPANY_NAME => 'Acme GmbH',
        ]);

        $url = $gateway->buildEntityUrl('Integration_Customer_Card');

        $this->assertSame("https://bc.example.com/ODataV4/Company('Acme%20GmbH')/Integration_Customer_Card", $url);
    }

    public function testValidateConfigurationReportsMissingBasicCredentials(): void
    {
        $gateway = $this->makeGateway([
            SecurityBcSettingsGateway::KEY_ODATA_BASE_URL => 'https://bc.example.com',
            SecurityBcSettingsGateway::KEY_COMPANY_NAME => 'Acme',
        ]);

        $missing = $gateway->validateConfiguration();

        $this->assertNotEmpty($missing);
        $this->assertFalse($gateway->isConfigured());
    }

    public function testIsConfiguredWhenBasicComplete(): void
    {
        $gateway = $this->makeGateway([
            SecurityBcSettingsGateway::KEY_ODATA_BASE_URL => 'https://bc.example.com',
            SecurityBcSettingsGateway::KEY_COMPANY_NAME => 'Acme',
            SecurityBcSettingsGateway::KEY_BASIC_USER => 'svc',
            SecurityBcSettingsGateway::KEY_BASIC_PASSWORD_ENC => 'enc:secret',
        ]);

        $this->assertTrue($gateway->isConfigured());
        $this->assertSame('secret', $gateway->getBasicPassword());
    }

    public function testSetODataBaseUrlRejectsNonHttps(): void
    {
        $gateway = $this->makeGateway();

        $this->assertFalse($gateway->setODataBaseUrl('http://insecure.example.com'));
    }
}
