<?php

namespace Tests\Feature;

use App\Models\Booking;
use App\Models\PaymentGateway;
use App\Models\Service;
use App\Models\User;
use App\Services\PaymentService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Tests\TestCase;

class PaymentWebhookTest extends TestCase
{
    use RefreshDatabase;

    public function test_stripe_webhook_captures_payment_and_holds_escrow(): void
    {
        \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'provider']);
        \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'customer']);

        $gateway = PaymentGateway::create([
            'name' => 'stripe',
            'display_name' => 'Stripe',
            'mode' => 'test',
            'enabled' => true,
            'webhook_secret' => 'whsec_test',
            'credentials' => ['secret' => 'sk_test'],
        ]);

        $provider = User::factory()->create();
        $provider->assignRole('provider');
        $customer = User::factory()->create();
        $customer->assignRole('customer');

        $service = Service::factory()->create([
            'user_id' => $provider->id,
            'booking_mode' => 'instant',
        ]);

        $booking = Booking::create([
            'service_id' => $service->id,
            'customer_id' => $customer->id,
            'provider_id' => $provider->id,
            'status' => 'draft',
            'booking_mode' => 'instant',
            'scheduling_type' => 'fixed_datetime',
            'delivery_mode' => 'online',
            'amount' => 100,
            'currency' => 'USD',
        ]);

        /** @var PaymentService $payments */
        $payments = app(PaymentService::class);
        $payment = $payments->initiate($booking, $gateway);

        $payload = json_encode([
            'id' => 'evt_'.Str::random(6),
            'type' => 'charge.succeeded',
            'data' => [
                'object' => [
                    'id' => $payment->transaction_id,
                ],
            ],
        ]);

        $timestamp = time();
        $signature = hash_hmac('sha256', $timestamp.'.'.$payload, $gateway->webhook_secret);
        $header = "t={$timestamp},v1={$signature}";

        $request = Request::create(
            "/webhooks/payments/stripe",
            'POST',
            [],
            [],
            [],
            ['HTTP_Stripe-Signature' => $header],
            $payload
        );

        $payments->handleWebhook('stripe', $request);

        $payment->refresh();
        $booking->refresh();

        $this->assertEquals('captured', $payment->status);
        $this->assertEquals('confirmed', $booking->status);
        $this->assertDatabaseHas('escrow_ledgers', ['booking_id' => $booking->id, 'type' => 'hold']);
    }
}
