<?php

namespace Tests\Feature;

use App\Enums\JournalSource;
use App\Exceptions\Accounting\UnbalancedJournalException;
use App\Models\Account;
use App\Models\User;
use App\Services\Accounting\JournalService;
use Database\Seeders\ChartOfAccountsSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class JournalBalanceTest extends TestCase
{
    use RefreshDatabase;

    public function test_balanced_journal_entry_posts_successfully(): void
    {
        $this->seed(ChartOfAccountsSeeder::class);
        $user = User::factory()->create();

        $cash = Account::query()->where('code', '1001')->firstOrFail();
        $revenue = Account::query()->where('code', '4001')->firstOrFail();

        $entry = app(JournalService::class)->post([
            'date' => now()->toDateString(),
            'description' => 'Balanced test entry',
            'source' => JournalSource::ManualAdjustment->value,
            'posted_by' => $user->id,
        ], [
            ['account_id' => $cash->id, 'debit_amount' => 250, 'credit_amount' => 0],
            ['account_id' => $revenue->id, 'debit_amount' => 0, 'credit_amount' => 250],
        ]);

        $this->assertSame('250.00', number_format((float) $entry->lines->sum('debit_amount'), 2, '.', ''));
        $this->assertSame('250.00', number_format((float) $entry->lines->sum('credit_amount'), 2, '.', ''));
    }

    public function test_unbalanced_journal_entry_is_rejected(): void
    {
        $this->seed(ChartOfAccountsSeeder::class);
        $user = User::factory()->create();

        $cash = Account::query()->where('code', '1001')->firstOrFail();
        $revenue = Account::query()->where('code', '4001')->firstOrFail();

        $this->expectException(UnbalancedJournalException::class);

        app(JournalService::class)->post([
            'date' => now()->toDateString(),
            'description' => 'Unbalanced test entry',
            'source' => JournalSource::ManualAdjustment->value,
            'posted_by' => $user->id,
        ], [
            ['account_id' => $cash->id, 'debit_amount' => 250, 'credit_amount' => 0],
            ['account_id' => $revenue->id, 'debit_amount' => 0, 'credit_amount' => 200],
        ]);
    }
}