<?php

namespace Tests\Feature\Payments;

use App\Models\Payment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RazorpayPaymentVerificationTest extends TestCase
{
    use RefreshDatabase;

    public function test_valid_razorpay_signature_marks_payment_captured_and_unlocks_user(): void
    {
        config([
            'services.razorpay.key' => 'rzp_test_key',
            'services.razorpay.secret' => 'test_secret',
        ]);

        $user = User::factory()->create([
            'questionnaire_completed_at' => now(),
            'access_unlocked_at' => null,
        ]);

        $orderId = 'order_valid123';
        $paymentId = 'pay_valid123';
        $signature = hash_hmac('sha256', "{$orderId}|{$paymentId}", 'test_secret');

        $payment = Payment::query()->create([
            'user_id' => $user->id,
            'provider' => 'razorpay',
            'razorpay_order_id' => $orderId,
            'amount_paise' => 199900,
            'currency' => 'INR',
            'status' => Payment::STATUS_CREATED,
        ]);

        $response = $this
            ->actingAs($user)
            ->postJson(route('payment.verify'), [
                'razorpay_order_id' => $orderId,
                'razorpay_payment_id' => $paymentId,
                'razorpay_signature' => $signature,
            ]);

        $response
            ->assertOk()
            ->assertJson([
                'message' => 'Payment verified.',
                'redirect_url' => route('resume.show'),
            ]);

        $payment->refresh();

        $this->assertSame(Payment::STATUS_CAPTURED, $payment->status);
        $this->assertSame($paymentId, $payment->razorpay_payment_id);
        $this->assertSame($signature, $payment->razorpay_signature);
        $this->assertNotNull($payment->verified_at);
        $this->assertNotNull($payment->unlocked_at);
        $this->assertNotNull($user->fresh()->access_unlocked_at);
    }

    public function test_invalid_razorpay_signature_fails_payment_without_unlocking_user(): void
    {
        config([
            'services.razorpay.key' => 'rzp_test_key',
            'services.razorpay.secret' => 'test_secret',
        ]);

        $user = User::factory()->create([
            'questionnaire_completed_at' => now(),
            'access_unlocked_at' => null,
        ]);

        $orderId = 'order_invalid123';
        $paymentId = 'pay_invalid123';

        $payment = Payment::query()->create([
            'user_id' => $user->id,
            'provider' => 'razorpay',
            'razorpay_order_id' => $orderId,
            'amount_paise' => 199900,
            'currency' => 'INR',
            'status' => Payment::STATUS_CREATED,
        ]);

        $response = $this
            ->actingAs($user)
            ->postJson(route('payment.verify'), [
                'razorpay_order_id' => $orderId,
                'razorpay_payment_id' => $paymentId,
                'razorpay_signature' => str_repeat('0', 64),
            ]);

        $response
            ->assertStatus(422)
            ->assertJson([
                'message' => 'Payment verification failed.',
            ]);

        $payment->refresh();

        $this->assertSame(Payment::STATUS_FAILED, $payment->status);
        $this->assertSame($paymentId, $payment->razorpay_payment_id);
        $this->assertNotNull($payment->failed_at);
        $this->assertNull($payment->verified_at);
        $this->assertNull($payment->unlocked_at);
        $this->assertNull($user->fresh()->access_unlocked_at);
    }
}
