<?php

use App\Models\Wallet;
use App\Models\WalletTransaction;
use App\Models\User;
use App\Modules\Wallet\Services\WalletService;

describe('WalletService', function () {

    it('creates wallet for user', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();

        $wallet = $service->getOrCreateWallet($user->id);

        expect($wallet)->not->toBeNull()
            ->and($wallet->user_id)->toBe($user->id)
            ->and((float) $wallet->balance)->toBe(0.00);
    });

    it('credits wallet correctly', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();
        $wallet = $service->getOrCreateWallet($user->id);

        $service->fundWallet($user->id, 5000, 'pay_ref_123');

        $wallet->refresh();
        expect((float) $wallet->balance)->toBe(5000.00);
    });

    it('debits wallet correctly', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();
        $wallet = $service->getOrCreateWallet($user->id);

        $service->fundWallet($user->id, 10000, 'pay_ref_123');
        $service->debitWallet($user->id, 3000, 'Test purchase', 'TXN-123');

        $wallet->refresh();
        expect((float) $wallet->balance)->toBe(7000.00);
    });

    it('prevents overdraft', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();

        $service->getOrCreateWallet($user->id);

        $canDebit = $service->canDebit($user->id, 1000);

        expect($canDebit)->toBeFalse();
    });

    it('throws InsufficientBalanceException on debit when balance is too low', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();

        $service->getOrCreateWallet($user->id);
        $service->fundWallet($user->id, 100, 'pay_ref_123');

        $service->debitWallet($user->id, 500, 'Test purchase', 'TXN-456');
    })->throws(\App\Core\Exceptions\InsufficientBalanceException::class);

    it('refunds wallet correctly', function () {
        $service = app(WalletService::class);
        $user = User::factory()->create();
        $wallet = $service->getOrCreateWallet($user->id);

        $service->fundWallet($user->id, 10000, 'pay_ref_123');
        $service->debitWallet($user->id, 3000, 'Test purchase', 'TXN-123');
        $service->refundWallet($user->id, 3000, 'Refund', 'RFD-123');

        $wallet->refresh();
        expect((float) $wallet->balance)->toBe(10000.00);
    });
});
