<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\Company;
use App\Models\Credit;
use App\Models\Installment;
use App\Models\User;
use App\Services\Metrics\CollectionMetricsService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Cache;
use PHPUnit\Framework\Attributes\Test;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

/**
 * Regresión #72: el aging por cuota del cobrador (getOverdueAging) clasificaba
 * el rango 1–30 días bajo la key/etiqueta '8_30' / "8–30 días" / min_days 8, lo
 * que ocultaba las cuotas vencidas 1–7 días bajo una etiqueta incorrecta.
 * Ahora el primer bucket es '1_30' / "1–30 días" / min_days 1.
 */
class CollectorAgingBucketsTest extends TestCase
{
    use DatabaseTransactions;

    private function bucketsByKey(array $aging): array
    {
        $map = [];
        foreach ($aging['buckets'] as $b) {
            $map[$b['key']] = $b;
        }

        return $map;
    }

    #[Test]
    public function an_installment_overdue_5_days_lands_in_the_1_30_bucket_with_correct_label(): void
    {
        Role::firstOrCreate(['name' => 'collector', 'guard_name' => 'web']);
        $company = Company::factory()->create();
        $collector = User::factory()->create(['company_id' => $company->id]);
        $collector->assignRole('collector');

        $credit = Credit::factory()->create([
            'company_id' => $company->id,
            'collector_user_id' => $collector->id,
            'status' => Credit::STATUS_ACTIVE,
        ]);

        // Cuota vencida hace 5 días (antes caía en '8_30' mal rotulada).
        Installment::factory()->create([
            'company_id' => $company->id,
            'credit_id' => $credit->id,
            'installment_number' => 1,
            'status' => Installment::STATUS_PENDING,
            'due_date' => now()->subDays(5),
            'total_amount' => 60000,
            'amount_paid' => 0,
        ]);

        // Cuota vencida hace 45 días → bucket 31_60.
        Installment::factory()->create([
            'company_id' => $company->id,
            'credit_id' => $credit->id,
            'installment_number' => 2,
            'status' => Installment::STATUS_PENDING,
            'due_date' => now()->subDays(45),
            'total_amount' => 30000,
            'amount_paid' => 0,
        ]);

        Cache::flush();

        $aging = app(CollectionMetricsService::class)->getOverdueAging($company->id, $collector->id);
        $buckets = $this->bucketsByKey($aging);

        // El bucket de 1–30 días existe, está bien rotulado y cuenta la cuota de 5 días.
        $this->assertArrayHasKey('1_30', $buckets);
        $this->assertArrayNotHasKey('8_30', $buckets, 'El bucket mal rotulado 8_30 no debe existir.');
        $this->assertSame('1–30 días', $buckets['1_30']['label']);
        $this->assertSame(1, $buckets['1_30']['min_days']);
        $this->assertSame(30, $buckets['1_30']['max_days']);
        $this->assertSame(1, $buckets['1_30']['count']);

        // La cuota de 45 días cae en 31_60.
        $this->assertSame(1, $buckets['31_60']['count']);

        $this->assertSame(2, $aging['total_count']);
    }
}
