<?php

use App\Services\Payments\PaymentConfigurationManager;
use App\Services\Payments\ProviderRegistry;

test('can initialize payment providers', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();

    // Check that activation key provider is always registered
    expect($registry->has('activation_key'))->toBeTrue();

    // Other providers should only be registered if configured
    $providers = $registry->getAllProviders();
    expect($providers)->toHaveKey('activation_key');
});

test('can get provider configuration', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $config = $manager->getProviderConfig('activation_key');

    expect($config)->toBeArray();
    expect($config)->toHaveKey('key_prefix');
    expect($config)->toHaveKey('key_length');
});

test('can update provider configuration', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $newConfig = ['key_prefix' => 'TEST-'];
    $manager->updateProviderConfig('activation_key', $newConfig);

    $config = $manager->getProviderConfig('activation_key');
    expect($config['key_prefix'])->toBe('TEST-');
});

test('can validate stripe configuration', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    // Invalid configuration
    $result = $manager->validateProviderConfig('stripe', []);
    expect($result['valid'])->toBeFalse();
    expect($result['errors'])->toContain('Stripe secret key is required');

    // Valid configuration
    $result = $manager->validateProviderConfig('stripe', [
        'secret_key' => 'sk_test_123',
        'publishable_key' => 'pk_test_123',
    ]);
    expect($result['valid'])->toBeTrue();
    expect($result['errors'])->toBeEmpty();
});

test('can validate lemon squeezy configuration', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    // Invalid configuration
    $result = $manager->validateProviderConfig('lemon_squeezy', []);
    expect($result['valid'])->toBeFalse();
    expect($result['errors'])->toContain('Lemon Squeezy API key is required');

    // Valid configuration
    $result = $manager->validateProviderConfig('lemon_squeezy', [
        'api_key' => 'test_key',
        'store_id' => 'test_store',
    ]);
    expect($result['valid'])->toBeTrue();
    expect($result['errors'])->toBeEmpty();
});

test('can validate crypto configuration', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    // Invalid configuration
    $result = $manager->validateProviderConfig('crypto', []);
    expect($result['valid'])->toBeFalse();
    expect($result['errors'])->toContain('Crypto webhook secret is required');

    // Valid configuration
    $result = $manager->validateProviderConfig('crypto', [
        'webhook_secret' => 'test_secret',
    ]);
    expect($result['valid'])->toBeTrue();
    expect($result['errors'])->toBeEmpty();
});

test('activation key configuration is always valid', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $result = $manager->validateProviderConfig('activation_key', []);
    expect($result['valid'])->toBeTrue();
    expect($result['errors'])->toBeEmpty();
});

test('can get provider status', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();
    $status = $manager->getProviderStatus();

    expect($status)->toBeArray();
    expect($status)->toHaveKey('activation_key');

    $activationKeyStatus = $status['activation_key'];
    expect($activationKeyStatus)->toHaveKey('name');
    expect($activationKeyStatus)->toHaveKey('active');
    expect($activationKeyStatus)->toHaveKey('supports_recurring');
    expect($activationKeyStatus)->toHaveKey('supports_one_time');
    expect($activationKeyStatus)->toHaveKey('supported_currencies');
});

test('can sanitize configuration for display', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->updateProviderConfig('test', [
        'secret_key' => 'sk_test_1234567890',
        'public_key' => 'pk_test_1234567890',
        'other_field' => 'visible_value',
    ]);

    $status = $manager->getProviderStatus();

    // Since 'test' is not a real provider, we need to check the sanitize logic indirectly
    $config = $manager->getProviderConfig('test');
    expect($config['secret_key'])->toBe('sk_test_1234567890'); // Original is preserved
});

test('can get default provider', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();
    $defaultProvider = $manager->getDefaultProvider();

    expect($defaultProvider)->toBe('activation_key'); // Should fallback to activation key
});

test('can test provider connectivity', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();

    // Test existing provider
    $result = $manager->testProviderConnectivity('activation_key');
    expect($result['success'])->toBeTrue();
    expect($result['details']['name'])->toBe('activation_key');

    // Test non-existing provider
    $result = $manager->testProviderConnectivity('non_existent');
    expect($result['success'])->toBeFalse();
    expect($result['error'])->toBe('Provider not registered');
});

test('can toggle provider', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();

    // Activation key should be registered
    expect($registry->has('activation_key'))->toBeTrue();

    // Disable activation key
    $result = $manager->toggleProvider('activation_key', false);
    expect($result)->toBeTrue();
    expect($registry->has('activation_key'))->toBeFalse();

    // Re-enable activation key
    $result = $manager->toggleProvider('activation_key', true);
    expect($result)->toBeTrue();
    expect($registry->has('activation_key'))->toBeTrue();
});

test('can refresh configurations', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    // Update a configuration
    $manager->updateProviderConfig('activation_key', ['key_prefix' => 'REFRESH-']);

    // Refresh configurations
    $manager->refreshConfigurations();

    // Configuration should still be available
    $config = $manager->getProviderConfig('activation_key');
    expect($config)->toHaveKey('key_prefix');
});

test('handles unknown provider validation', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $result = $manager->validateProviderConfig('unknown_provider', []);
    expect($result['valid'])->toBeFalse();
    expect($result['errors'])->toContain('Unknown provider: unknown_provider');
});

test('handles unknown provider toggle', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $result = $manager->toggleProvider('unknown_provider', true);
    expect($result)->toBeFalse();
});

test('activation key provider is always available', function () {
    $registry = new ProviderRegistry;
    $manager = new PaymentConfigurationManager($registry);

    $manager->initializeProviders();

    // Even without any configuration, activation key should be available
    expect($registry->has('activation_key'))->toBeTrue();
    expect($registry->get('activation_key')->isActive())->toBeTrue();
});
