<?php

namespace Tests\Feature\Api\V1;

use App\Models\Appointment;
use App\Models\PaymentTransaction;
use App\Models\User;
use Database\Seeders\ClinicDemoSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class PaymentLifecycleTest extends TestCase
{
    use RefreshDatabase;

    public function test_partial_full_refund_and_waiver_statuses_are_transaction_backed(): void
    {
        $this->seed(ClinicDemoSeeder::class);
        $assistant = User::where('email', 'assistant.one@smartclinic.test')->firstOrFail();
        $admin = User::where('email', 'admin@smartclinic.test')->firstOrFail();
        $appointment = Appointment::query()->where('final_fee', 2500)->firstOrFail();

        Sanctum::actingAs($assistant);
        $this->postJson("/api/v1/appointments/{$appointment->id}/payments", [
            'amount' => 1000,
            'method' => 'cash',
            'idempotency_key' => 'partial-1',
        ])->assertCreated();
        $this->assertSame('partially_paid', $appointment->fresh()->payment_status->value);

        $payment = $this->postJson("/api/v1/appointments/{$appointment->id}/payments", [
            'amount' => 1000,
            'method' => 'cash',
            'idempotency_key' => 'partial-2',
        ])->assertCreated()->json('data');

        Sanctum::actingAs($admin);
        $this->postJson("/api/v1/appointments/{$appointment->id}/waiver", [
            'amount' => 500,
            'reason' => 'Approved support waiver',
        ])->assertCreated();
        $this->assertSame('paid', $appointment->fresh()->payment_status->value);

        Sanctum::actingAs($assistant);
        $this->postJson('/api/v1/transactions/'.$payment['id'].'/refund', [
            'amount' => 500,
            'reason' => 'Partial refund',
            'idempotency_key' => 'refund-1',
        ])->assertCreated();

        $this->assertSame('partially_paid', $appointment->fresh()->payment_status->value);
        $this->assertSame(4, PaymentTransaction::where('appointment_id', $appointment->id)->count());
    }

    public function test_payment_method_comes_from_organization_settings(): void
    {
        $this->seed(ClinicDemoSeeder::class);
        $assistant = User::where('email', 'assistant.one@smartclinic.test')->firstOrFail();
        Sanctum::actingAs($assistant);
        $appointment = Appointment::firstOrFail();

        $this->postJson("/api/v1/appointments/{$appointment->id}/payments", [
            'amount' => 100,
            'method' => 'crypto',
            'idempotency_key' => 'invalid-method',
        ])->assertStatus(422);
    }
}
