<?php

namespace Tests\Feature;

use App\Models\Category;
use App\Models\Transaction;
use App\Models\User;
use App\Services\TransactionService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mockery;
use Tests\TestCase;

class SmeplugWebhookIdempotencyTest extends TestCase
{
    use RefreshDatabase;

    public function test_duplicate_smeplug_webhook_event_is_processed_once(): void
    {
        config()->set('vtu.webhooks.smeplug.secret', 'secret-123');

        $user = User::factory()->create();
        $category = Category::create(['name' => 'Data SME', 'slug' => 'data_sme']);
        $transaction = Transaction::create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'VTU-TEST-001',
            'amount_charged' => 500,
            'status' => 'pending',
            'meta_json' => ['category_slug' => 'data_sme'],
        ]);

        $mock = Mockery::mock(TransactionService::class);
        $mock->shouldReceive('applyWebhookStatusUpdate')
            ->once()
            ->andReturnUsing(function (Transaction $tx, string $status, array $payload) {
                $tx->update(['status' => 'success', 'webhook_received_at' => now()]);

                return $tx->fresh();
            });
        $this->app->instance(TransactionService::class, $mock);

        $payload = [
            'transaction' => [
                'status' => 'success',
                'reference' => 'SP-REF-001',
                'customer_reference' => 'VTU-TEST-001',
                'type' => 'data',
                'beneficiary' => '08030000000',
                'memo' => 'Delivered',
                'price' => 480,
            ],
        ];

        $first = $this->postJson('/api/webhooks/smeplug?secret=secret-123', $payload);
        $second = $this->postJson('/api/webhooks/smeplug?secret=secret-123', $payload);

        $first->assertOk()->assertJson(['ok' => true, 'matched' => true]);
        $second->assertOk()->assertJson(['ok' => true, 'duplicate' => true]);

        $this->assertDatabaseCount('webhook_events', 1);
    }
}

