<?php

namespace Tests\Feature;

use App\Models\ApiClient;
use App\Models\VerificationLog;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class BusinessChargeApiTest extends TestCase
{
    use RefreshDatabase;

    protected ApiClient $client;
    protected string $plainKey;

    protected function setUp(): void
    {
        parent::setUp();

        // Create a test client with custom charges
        $this->plainKey = 'dv_test_business_key_12345';
        $hashedKey = hash('sha256', $this->plainKey);

        $this->client = ApiClient::create([
            'name' => 'Acme Test Corp',
            'api_key' => $hashedKey,
            'is_active' => true,
            'wallet_balance' => 100.00,
            'obf_charge' => 5.50,
            'user_creation_charge' => 12.00,
        ]);
    }

    /**
     * Test authentication fails when API key is missing.
     */
    public function test_charge_endpoints_fail_when_api_key_is_missing(): void
    {
        $response1 = $this->postJson('/api/v1/charge/obf', ['order_id' => '123']);
        $response1->assertStatus(401);

        $response2 = $this->postJson('/api/v1/charge/user-creation', ['username' => 'test']);
        $response2->assertStatus(401);
    }

    /**
     * Test successful OBF charging.
     */
    public function test_obf_charge_success(): void
    {
        $response = $this->withHeaders([
            'X-API-Key' => $this->plainKey,
        ])->postJson('/api/v1/charge/obf', [
            'order_id' => 'OBF-2026-999',
            'status' => 'accepted',
            'customer' => 'Alice Smith'
        ]);

        $response->assertStatus(200);
        $response->assertJson([
            'success' => true,
            'charged_amount' => 5.50,
            'remaining_balance' => 94.50,
        ]);

        // Assert database values
        $this->client->refresh();
        $this->assertEquals(94.50, $this->client->wallet_balance);

        $this->assertDatabaseHas('verification_logs', [
            'api_client_id' => $this->client->id,
            'verification_type' => 'obf',
            'status' => 'success',
            'charged_amount' => 5.50,
        ]);

        $log = VerificationLog::first();
        $this->assertEquals('OBF-2026-999', $log->input_parameters['order_id']);
    }

    /**
     * Test OBF charging even when status is not 'accepted' (direct, unconditional billing).
     */
    public function test_obf_charge_unconditional(): void
    {
        $response = $this->withHeaders([
            'X-API-Key' => $this->plainKey,
        ])->postJson('/api/v1/charge/obf', [
            'order_id' => 'OBF-2026-999',
            'status' => 'pending',
        ]);

        $response->assertStatus(200);
        $response->assertJson([
            'success' => true,
            'charged_amount' => 5.50,
            'remaining_balance' => 94.50,
        ]);

        $this->client->refresh();
        $this->assertEquals(94.50, $this->client->wallet_balance);
    }

    /**
     * Test successful User Creation charging.
     */
    public function test_user_creation_charge_success(): void
    {
        $response = $this->withHeaders([
            'X-API-Key' => $this->plainKey,
        ])->postJson('/api/v1/charge/user-creation', [
            'username' => 'testuser',
            'email' => 'test@example.com'
        ]);

        $response->assertStatus(200);
        $response->assertJson([
            'success' => true,
            'charged_amount' => 12.00,
            'remaining_balance' => 88.00,
        ]);

        // Assert database values
        $this->client->refresh();
        $this->assertEquals(88.00, $this->client->wallet_balance);

        $this->assertDatabaseHas('verification_logs', [
            'api_client_id' => $this->client->id,
            'verification_type' => 'user_creation',
            'status' => 'success',
            'charged_amount' => 12.00,
        ]);
    }

    /**
     * Test payment required when balance is insufficient.
     */
    public function test_charge_fails_when_balance_is_insufficient(): void
    {
        // Set low balance
        $this->client->update(['wallet_balance' => 3.00]);

        $response = $this->withHeaders([
            'X-API-Key' => $this->plainKey,
        ])->postJson('/api/v1/charge/obf', [
            'order_id' => 'OBF-123'
        ]);

        $response->assertStatus(402);
        $response->assertJson([
            'success' => false,
            'message' => 'Insufficient wallet balance. Please recharge.',
        ]);

        // Check balance remains same
        $this->client->refresh();
        $this->assertEquals(3.00, $this->client->wallet_balance);
    }
}
