<?php

use App\Models\Company;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Carbon;
use Livewire\Volt\Volt;

test('guests are redirected to the login page', function () {
    $response = $this->get(route('transaction-review'));
    $response->assertRedirect(route('login'));
});

test('authenticated users can view transaction review', function () {
    $this->actingAs(User::factory()->create());

    $response = $this->get(route('transaction-review'));

    $response->assertOk();
});

test('transaction review filters by search and updates selection', function () {
    $this->actingAs(User::factory()->create());

    $acme = Company::factory()->create(['name' => 'Acme', 'legal_name' => 'Acme Investigations AG']);
    $globex = Company::factory()->create(['name' => 'Globex', 'legal_name' => 'Globex Risk GmbH']);

    $priority = Transaction::factory()->for($acme)->requiresReview()->status(Transaction::STATUS_TRUE_POSITIVE)->create([
        'reference' => 'REF-ACME-001',
        'counterparty' => 'Alpha Logistics',
        'amount' => 125000.75,
        'risk_score' => 95,
        'executed_at' => Carbon::parse('2024-01-11 12:00:00'),
    ]);

    $match = Transaction::factory()->for($globex)->requiresReview()->status(Transaction::STATUS_FALSE_POSITIVE)->create([
        'reference' => 'REF-GLOBEX-001',
        'counterparty' => 'Beta Holdings',
        'amount' => 45000.50,
        'risk_score' => 72,
        'executed_at' => Carbon::parse('2024-01-10 09:00:00'),
    ]);

    Transaction::factory()->for($globex)->requiresReview(false)->status(Transaction::STATUS_CLEARED)->create([
        'reference' => 'REF-GLOBEX-002',
        'counterparty' => 'Gamma Partners',
        'amount' => 32000.25,
        'risk_score' => 40,
        'executed_at' => Carbon::parse('2024-01-09 08:15:00'),
    ]);

    $component = Volt::test('transaction-review');

    expect($component->get('selectedTransactionId'))->toBe($priority->id);

    $component->set('search', 'Beta');

    /** @var LengthAwarePaginator $transactions */
    $transactions = $component->get('transactions');

    expect($transactions->total())->toBe(1)
        ->and($transactions->items()[0]->id)->toBe($match->id)
        ->and($component->get('selectedTransactionId'))->toBe($match->id);
});

test('transaction review metrics aggregate totals by status', function () {
    $this->actingAs(User::factory()->create());

    $acme = Company::factory()->create();
    $globex = Company::factory()->create();

    $truePositive = Transaction::factory()->for($acme)->requiresReview()->status(Transaction::STATUS_TRUE_POSITIVE)->create([
        'amount' => 90000.00,
        'risk_score' => 88,
        'executed_at' => Carbon::parse('2024-01-08 10:00:00'),
    ]);

    $falsePositive = Transaction::factory()->for($globex)->requiresReview()->status(Transaction::STATUS_FALSE_POSITIVE)->create([
        'amount' => 15000.00,
        'risk_score' => 65,
        'executed_at' => Carbon::parse('2024-01-08 09:00:00'),
    ]);

    Transaction::factory()->for($globex)->requiresReview(false)->status(Transaction::STATUS_CLEARED)->create([
        'amount' => 6000.00,
        'risk_score' => 35,
        'executed_at' => Carbon::parse('2024-01-07 08:00:00'),
    ]);

    $component = Volt::test('transaction-review');

    $metrics = $component->get('metrics');

    expect($metrics['total']['count'])->toBe(3)
        ->and($metrics['by_status'][Transaction::STATUS_TRUE_POSITIVE]['count'])->toBe(1)
        ->and($metrics['by_status'][Transaction::STATUS_TRUE_POSITIVE]['amount'])->toEqualWithDelta(90000, 0.001)
        ->and($metrics['by_status'][Transaction::STATUS_FALSE_POSITIVE]['count'])->toBe(1)
        ->and($metrics['by_status'][Transaction::STATUS_FALSE_POSITIVE]['amount'])->toEqualWithDelta(15000, 0.001)
        ->and($metrics['by_status'][Transaction::STATUS_CLEARED]['count'])->toBe(1);

    $component->set('status', Transaction::STATUS_FALSE_POSITIVE);

    $filteredMetrics = $component->get('metrics');

    expect($filteredMetrics['total']['count'])->toBe(1)
        ->and($filteredMetrics['total']['amount'])->toEqualWithDelta(15000, 0.001)
        ->and($component->get('selectedTransactionId'))->toBe($falsePositive->id);
});
