<?php

declare(strict_types=1);

namespace Tests\Feature\Credits;

use App\Models\Client;
use App\Models\Company;
use App\Models\Credit;
use App\Support\CreditNumberBackfill;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;

/**
 * Numeración de créditos por empresa (company_credit_number).
 *
 * Regla de dominio: cada crédito recibe un número secuencial (1, 2, 3…)
 * independiente por empresa, asignado en el hook `creating` del modelo.
 * Se expone como código legible con padding de 3 dígitos (001).
 */
class CreditNumberingTest extends TestCase
{
    use DatabaseTransactions;

    /**
     * Crea un crédito para la empresa indicada (con su propio cliente).
     */
    private function makeCredit(Company $company): Credit
    {
        $client = Client::factory()->create(['company_id' => $company->id]);

        return Credit::factory()->create([
            'company_id' => $company->id,
            'client_id' => $client->id,
        ]);
    }

    public function test_company_credit_number_is_sequential_per_company(): void
    {
        $companyA = Company::factory()->create();
        $companyB = Company::factory()->create();

        $a1 = $this->makeCredit($companyA);
        $b1 = $this->makeCredit($companyB);
        $a2 = $this->makeCredit($companyA);
        $a3 = $this->makeCredit($companyA);

        $this->assertSame(1, $a1->company_credit_number);
        $this->assertSame(2, $a2->company_credit_number);
        $this->assertSame(3, $a3->company_credit_number);

        // Independiente por empresa: B empieza en 1 sin importar el orden global.
        $this->assertSame(1, $b1->company_credit_number);
    }

    public function test_formatted_code_is_zero_padded(): void
    {
        $company = Company::factory()->create();

        $credit = $this->makeCredit($company);

        $this->assertSame('001', $credit->code);
    }

    public function test_backfill_assigns_chronological_numbers_per_company(): void
    {
        $company = Company::factory()->create();

        $c1 = $this->makeCredit($company);
        $c2 = $this->makeCredit($company);
        $c3 = $this->makeCredit($company);

        // Simula créditos preexistentes sin numerar, con fechas de creación
        // distintas y no correlacionadas con el orden de inserción.
        // 'created_at' no está en $fillable de Credit, así que se asigna por
        // propiedad directa (bypassa el filtro de mass-assignment) en vez de
        // updateQuietly(['created_at' => ...]), que lo descartaría en silencio.
        foreach ([[$c1, 3], [$c2, 1], [$c3, 2]] as [$credit, $daysAgo]) {
            $credit->company_credit_number = null;
            $credit->created_at = now()->subDays($daysAgo);
            $credit->saveQuietly();
        }

        CreditNumberBackfill::run();

        $this->assertSame(1, $c1->refresh()->company_credit_number);
        $this->assertSame(3, $c2->refresh()->company_credit_number);
        $this->assertSame(2, $c3->refresh()->company_credit_number);
    }
}
