<?php

namespace Tests\Feature;

use App\Models\Raffle;
use App\Models\Ticket;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class TilopayPaymentTest extends TestCase
{
    use RefreshDatabase;

    public function test_tilopay_callback_approves_purchase_and_sells_reserved_tickets(): void
    {
        $user = User::factory()->create();
        $raffle = Raffle::create([
            'title' => 'Sorteo de prueba',
            'description' => 'Sorteo para pruebas',
            'commercial_value' => 1000000,
            'fiscal_value' => 1000000,
            'draw_date' => now()->addWeek(),
            'total_tickets' => 2,
            'status' => 'active',
            'type' => 'main',
        ]);

        $transaction = Transaction::create([
            'user_id' => $user->id,
            'amount' => 1500,
            'type' => 'purchase',
            'payment_method' => 'card',
            'provider' => 'tilopay',
            'provider_order_number' => 'WINCAR-TEST-ORDER',
            'status' => 'pending',
        ]);

        Ticket::where('raffle_id', $raffle->id)
            ->where('ticket_number', '0000')
            ->update([
                'status' => 'reserved',
                'user_id' => $user->id,
                'transaction_id' => $transaction->id,
                'reserved_at' => now(),
                'expires_at' => now()->addHours(10),
            ]);

        $response = $this->getJson('/api/payments/tilopay/callback?'.http_build_query([
            'code' => 1,
            'description' => 'Transaction is approved.',
            'auth' => '123456',
            'order' => 'WINCAR-TEST-ORDER',
            'tpt' => '4300',
            'tilopay-transaction' => '4300',
            'returnData' => base64_encode(json_encode([
                'transaction_id' => $transaction->id,
                'user_id' => $user->id,
                'order_number' => 'WINCAR-TEST-ORDER',
            ])),
        ]));

        $response->assertOk()
            ->assertJson([
                'approved' => true,
                'status' => 'approved',
            ]);

        $this->assertDatabaseHas('transactions', [
            'id' => $transaction->id,
            'status' => 'approved',
            'payment_reference' => '123456',
            'provider_transaction_id' => '4300',
        ]);

        $this->assertDatabaseHas('tickets', [
            'raffle_id' => $raffle->id,
            'ticket_number' => '0000',
            'status' => 'sold',
            'user_id' => $user->id,
            'transaction_id' => $transaction->id,
        ]);

        $this->assertSame(1, $raffle->fresh()->sold_tickets);
    }

    public function test_tilopay_callback_approves_wallet_recharge_and_credits_balance(): void
    {
        $user = User::factory()->create(['wallet_balance' => 1000]);

        $transaction = Transaction::create([
            'user_id' => $user->id,
            'amount' => 5000,
            'type' => 'deposit',
            'payment_method' => 'card',
            'provider' => 'tilopay',
            'provider_order_number' => 'WALLET-TEST-ORDER',
            'status' => 'pending',
        ]);

        $response = $this->getJson('/api/payments/tilopay/callback?'.http_build_query([
            'code' => 1,
            'description' => 'Transaction is approved.',
            'auth' => '654321',
            'order' => 'WALLET-TEST-ORDER',
            'tilopay-transaction' => '9900',
            'returnData' => base64_encode(json_encode([
                'transaction_id' => $transaction->id,
                'user_id' => $user->id,
                'order_number' => 'WALLET-TEST-ORDER',
            ])),
        ]));

        $response->assertOk()
            ->assertJson([
                'approved' => true,
                'status' => 'approved',
            ]);

        $this->assertDatabaseHas('transactions', [
            'id' => $transaction->id,
            'type' => 'deposit',
            'status' => 'approved',
        ]);

        $this->assertSame(6000.0, (float) $user->fresh()->wallet_balance);
    }
}
