<?php

use App\Services\Payments\Providers\CryptoProvider;

test('crypto provider has correct name and capabilities', function () {
    $provider = new CryptoProvider;

    expect($provider->getName())->toBe('crypto');
    expect($provider->supportsRecurring())->toBeTrue();
    expect($provider->supportsOneTime())->toBeTrue();
    expect($provider->getSupportedCurrencies())->toBe(['USD']);
});

test('crypto provider is inactive without webhook secret', function () {
    $provider = new CryptoProvider;

    expect($provider->isActive())->toBeFalse();
});

test('crypto provider is active with webhook secret', function () {
    $provider = new CryptoProvider(['webhook_secret' => 'test-secret']);

    expect($provider->isActive())->toBeTrue();
});

test('can convert usd to crypto', function () {
    $provider = new CryptoProvider;

    $btcAmount = $provider->convertUsdToCrypto(100.00, 'BTC');
    expect($btcAmount)->toBeFloat();
    expect($btcAmount)->toBeGreaterThan(0);

    $ethAmount = $provider->convertUsdToCrypto(100.00, 'ETH');
    expect($ethAmount)->toBeFloat();
    expect($ethAmount)->toBeGreaterThan(0);

    $usdtAmount = $provider->convertUsdToCrypto(100.00, 'USDT');
    expect($usdtAmount)->toBeFloat();
    expect($usdtAmount)->toBe(100.00); // USDT should be 1:1

    $ltcAmount = $provider->convertUsdToCrypto(100.00, 'LTC');
    expect($ltcAmount)->toBeFloat();
    expect($ltcAmount)->toBeGreaterThan(0);
});

test('can calculate fees correctly', function () {
    $provider = new CryptoProvider;

    $fees = $provider->calculateFees(100.00);

    expect($fees['fixed_fee'])->toBe(0);
    expect($fees['percentage_fee'])->toBe(1.5); // 1% network + 0.5% service
    expect($fees['total_fee'])->toBe(1.5);
    expect($fees['net_amount'])->toBe(98.5);
});

test('crypto provider has correct refund method', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('processRefund');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(3);
});

test('can get configuration', function () {
    $config = [
        'webhook_secret' => 'test-secret',
        'confirmation_timeout_minutes' => 45,
    ];
    $provider = new CryptoProvider($config);

    expect($provider->getConfiguration())->toHaveKey('webhook_secret', 'test-secret');
    expect($provider->getConfiguration())->toHaveKey('confirmation_timeout_minutes', 45);
});

test('crypto provider has correct cancellation terms', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('getCancellationTerms');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(1);
});

test('crypto provider has correct upcoming invoice method', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('getUpcomingInvoice');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(1);
});

test('crypto provider has correct export data method', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('exportSubscriptionData');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(1);
});

test('crypto provider has correct import data method', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('importSubscriptionData');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(2);
});

test('crypto provider does not support trials', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('startTrial');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(2);
});

test('crypto provider has correct coupon methods', function () {
    $provider = new CryptoProvider;

    // Test that the methods exist and return expected structure
    $reflection = new ReflectionClass($provider);
    $applyMethod = $reflection->getMethod('applyCoupon');
    $removeMethod = $reflection->getMethod('removeCoupon');

    expect($applyMethod)->not->toBeNull();
    expect($applyMethod->getNumberOfParameters())->toBe(2);
    expect($removeMethod)->not->toBeNull();
    expect($removeMethod->getNumberOfParameters())->toBe(1);
});

test('crypto provider has correct customer portal method', function () {
    $provider = new CryptoProvider;

    // Test that the method exists and returns expected structure
    $reflection = new ReflectionClass($provider);
    $method = $reflection->getMethod('createCustomerPortalSession');

    expect($method)->not->toBeNull();
    expect($method->getNumberOfParameters())->toBe(1);
});
