<?php

namespace Database\Factories;

use App\Models\Client;
use App\Models\Company;
use App\Models\Credit;
use App\Models\Installment;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class CreditFactory extends Factory
{
    protected $model = Credit::class;

    public function definition()
    {
        return [
            // Lazy factory references: Laravel only resolves these when the
            // calling test does NOT provide explicit values. When a test
            // supplies collector_user_id, created_by_user_id, etc., no
            // orphaned Company/User records are created as side effects,
            // which prevents Faker unique() pool exhaustion across long runs.
            'company_id' => Company::factory(),
            'client_id' => Client::factory(),
            'collector_user_id' => User::factory(),
            'created_by_user_id' => User::factory(),

            'status' => Credit::STATUS_ACTIVE,
            'amount' => 100_000,
            'interest_rate' => 20,
            'installments_count' => 2,
            'periodicity' => 'biweekly',

            'start_date' => now(),
            'due_date' => now()->addDays(30),
        ];
    }

    /*==========================================================
      1) CRÉDITO TOTALMENTE PAGADO
      ==========================================================*/
    public function fullyPaid(): self
    {
        return $this->afterCreating(function (Credit $credit) {
            $installment = Installment::factory()->create([
                'company_id' => $credit->company_id,
                'credit_id' => $credit->id,
                'installment_number' => 1,
                'status' => 'paid',
                'amount_paid' => 60000,
                'total_amount' => 60000,
                'principal_amount' => 50000,
                'interest_amount' => 10000,
                'due_date' => now()->subDays(10),
            ]);
        });
    }

    /*==========================================================
      2) CRÉDITO VENCIDO
      ==========================================================*/
    public function overdue()
    {
        return $this->state(function () {
            return [
                // credit.due_date DEBE estar vencida
                'due_date' => now()->subDays(2),
            ];
        })->afterCreating(function (Credit $credit) {
            // Cuota con saldo pendiente
            Installment::factory()->create([
                'company_id' => $credit->company_id,
                'credit_id' => $credit->id,
                'installment_number' => 1,
                'status' => 'overdue',
                'amount_paid' => 0,
                'total_amount' => 60000,
                'principal_amount' => 50000,
                'interest_amount' => 10000,
                'due_date' => now()->subDays(5), // cuota vencida
            ]);
        });
    }

    /*==========================================================
      3) CRÉDITO RETRASADO (PAGO PARCIAL)
      ==========================================================*/
    public function delayed(): self
    {
        return $this->state(function () {
            return [
                // El crédito NO está vencido → delayed depende de cuotas vencidas
                'due_date' => now()->addDays(5),
            ];
        })->afterCreating(function (Credit $credit) {
            // Al menos una cuota vencida o partial_paid vencida
            Installment::factory()->create([
                'company_id' => $credit->company_id,
                'credit_id' => $credit->id,
                'installment_number' => 1,
                'status' => 'partial_paid',
                'amount_paid' => 20000,
                'total_amount' => 60000,
                'principal_amount' => 50000,
                'interest_amount' => 10000,
                'due_date' => now()->subDays(2), // cuota vencida
            ]);
        });
    }

    /*==========================================================
      4) CRÉDITO AL DÍA (ACTIVE)
    ==========================================================*/
    public function activeUpToDate(): self
    {
        return $this->state(function () {
            return [
                // Crédito NO vencido
                'due_date' => now()->addDays(10),
            ];
        })->afterCreating(function (Credit $credit) {
            // Todas las cuotas al día
            Installment::factory()->create([
                'company_id' => $credit->company_id,
                'credit_id' => $credit->id,
                'installment_number' => 1,
                'status' => 'pending',
                'amount_paid' => 0,
                'total_amount' => 60000,
                'principal_amount' => 50000,
                'interest_amount' => 10000,
                'due_date' => now()->addDays(5), // futuro → no vencido
            ]);
        });
    }
}
