<?php

use App\Models\ActivationKey;
use App\Models\User;
use App\Services\Payments\PaymentConfigurationManager;
use App\Services\Payments\PaymentOrchestrator;
use App\Services\Payments\ProviderRegistry;

test('can redeem activation key', function () {
    $user = User::factory()->create();

    // Create an activation key
    $activationKey = ActivationKey::factory()->create([
        'activation_key' => 'TEST-KEY-123',
        'is_activated' => false,
    ]);

    $response = actingAs($user)
        ->postJson('/api/activation-keys/redeem', [
            'activation_key' => 'TEST-KEY-123',
        ]);

    expect($response->status())->toBe(200);
    $data = $response->json();
    expect($data['success'])->toBeTrue();
    expect($data['data'])->toHaveKey('subscription_id');

    // Verify the key is now activated
    $activationKey->refresh();
    expect($activationKey->is_activated)->toBeTrue();
});

test('requires authentication to redeem activation key', function () {
    $response = postJson('/api/activation-keys/redeem', [
        'activation_key' => 'TEST-KEY-123',
    ]);

    expect($response->status())->toBe(401);
});

test('can validate activation key', function () {
    // Create an activation key
    $activationKey = ActivationKey::factory()->create([
        'activation_key' => 'VALIDATE-KEY-123',
        'is_activated' => false,
    ]);

    $response = getJson('/api/activation-keys/validate/VALIDATE-KEY-123');

    expect($response->status())->toBe(200);
    $data = $response->json();
    expect($data['valid'])->toBeTrue();
    expect($data['is_activated'])->toBeFalse();
});

test('returns invalid for non-existent activation key', function () {
    $response = getJson('/api/activation-keys/validate/NON-EXISTENT');

    expect($response->status())->toBe(200);
    $data = $response->json();
    expect($data['valid'])->toBeFalse();
    expect($data['reason'])->toBe('Activation key not found');
});

test('can get crypto exchange rate', function () {
    $response = getJson('/api/crypto/rates/btc');

    expect($response->status())->toBe(200);
    $response->assertJsonStructure([
        'crypto',
        'rate_usd_per_crypto',
        'rate_crypto_per_usd',
        'updated_at',
    ]);

    $data = $response->json();
    expect($data['crypto'])->toBe('BTC');
    expect($data['rate_usd_per_crypto'])->toBeNumeric();
    expect($data['rate_crypto_per_usd'])->toBeNumeric();
});

test('can convert usd to crypto', function () {
    $response = getJson('/api/crypto/convert?usd_amount=100&crypto=btc');

    expect($response->status())->toBe(200);
    $response->assertJsonStructure([
        'usd_amount',
        'crypto',
        'crypto_amount',
        'fees',
        'net_crypto_amount',
        'updated_at',
    ]);

    $data = $response->json();
    expect($data['usd_amount'])->toBe(100.0);
    expect($data['crypto'])->toBe('BTC');
    expect($data['crypto_amount'])->toBeNumeric();
    expect($data['fees'])->toHaveKey('total_fee');
});

test('validates crypto conversion parameters', function () {
    // Invalid crypto type
    $response = getJson('/api/crypto/convert?usd_amount=100&crypto=invalid');

    expect($response->status())->toBe(422);

    // Invalid amount
    $response = getJson('/api/crypto/convert?usd_amount=0&crypto=btc');

    expect($response->status())->toBe(422);
});

test('payment routes exist', function () {
    // Test that basic payment routes exist
    $response = getJson('/api/payment/success');
    expect($response->status())->toBe(200);

    $response = getJson('/api/payment/cancel');
    expect($response->status())->toBe(200);
});

test('can create simple provider registry', function () {
    $registry = new ProviderRegistry;
    expect($registry)->toBeInstanceOf(ProviderRegistry::class);
    expect($registry->getAllProviders())->toHaveCount(0);
});

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

    expect($configManager)->toBeInstanceOf(PaymentConfigurationManager::class);

    // Test that activation key is always available
    $configManager->initializeProviders();
    expect($registry->has('activation_key'))->toBeTrue();
});

test('can create payment orchestrator', function () {
    $registry = new ProviderRegistry;
    $configManager = new PaymentConfigurationManager($registry);
    $orchestrator = new PaymentOrchestrator($registry, $configManager);

    expect($orchestrator)->toBeInstanceOf(PaymentOrchestrator::class);
    expect($orchestrator->getRegistry())->toBe($registry);
});
