<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\Company;
use App\Models\Income;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\Test;
use RuntimeException;
use Tests\TestCase;

/**
 * #73 — La integridad de Income se valida en el hook `creating` del modelo,
 * NO solo en FinanceAutoLogger. Esto cubre la creación desde Filament
 * (`CreateIncomes` → `Income::create()`), que no pasa por FinanceAutoLogger.
 */
class IncomeIntegrityTest extends TestCase
{
    use DatabaseTransactions;

    private Company $company;

    private User $user;

    protected function setUp(): void
    {
        parent::setUp();
        $this->company = Company::factory()->create();
        $this->user = User::factory()->create(['company_id' => $this->company->id]);
    }

    /** @return array<string, mixed> */
    private function base(array $overrides = []): array
    {
        return array_merge([
            'company_id' => $this->company->id,
            'user_id' => $this->user->id,
            'amount' => 1000,
            'operation_date' => now()->toDateString(),
        ], $overrides);
    }

    #[Test]
    public function operational_income_cannot_have_a_credit_id(): void
    {
        $this->expectException(RuntimeException::class);

        // service_fee es operativo → no puede tener credit_id (regla del modelo).
        Income::create($this->base([
            'category' => 'service_fee',
            'credit_id' => 999,
        ]));
    }

    #[Test]
    public function payment_linked_income_requires_payment_id(): void
    {
        $this->expectException(RuntimeException::class);

        // loan_payment_principal es payment-linked → requiere payment_id + credit_id.
        Income::create($this->base([
            'category' => 'loan_payment_principal',
            'credit_id' => 999,
            // payment_id ausente a propósito
        ]));
    }

    #[Test]
    public function valid_operational_income_is_created(): void
    {
        $income = Income::create($this->base([
            'category' => 'service_fee',
        ]));

        $this->assertTrue($income->exists);
        $this->assertNull($income->credit_id);
    }
}
