<?php
namespace App\Models;

use App\Traits\VisibleToAdmin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Loan extends Model
{
    use HasFactory;
    use VisibleToAdmin;

    // This tells the trait how to reach the user who controls visibility
    protected function adminVisibilityRelation(): string
    {
        return 'user';
    }
    protected $fillable = [
        'idempotency_key',
        'user_id',
        'account_id',
        'amount',
        'duration',
        'credit_facility',
        'purpose',
        'interest_rate',
        'total_interest',
        'monthly_repayment',
        'principal_outstanding',
        'interest_outstanding',
        'penalty_outstanding',
        'total_paid',
        'status',
        'approved_at',
        'rejected_at',
        'completed_at',
        'first_due_date',
        'last_due_date',
        'auto_debit_enabled',
        'grace_period_days',
    ];

    protected $casts = [
        'approved_at' => 'datetime',
        'rejected_at' => 'datetime',
        'completed_at' => 'datetime',
        'first_due_date' => 'date',
        'last_due_date' => 'date',
        'auto_debit_enabled' => 'boolean',
    ];

    /* =====================
     | Relationships
     ===================== */

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function account()
    {
        return $this->belongsTo(Account::class);
    }

    public function installments()
    {
        return $this->hasMany(LoanInstallment::class);
    }

    public function transactions()
    {
        return $this->hasMany(Transaction::class);
    }

    /* =====================
     | Helpers
     ===================== */

    public function getTotalRepaymentAttribute()
    {
        return bcadd($this->amount, $this->total_interest, 2);
    }

    public function getRemainingBalanceAttribute()
    {
        return bcadd(
            bcadd($this->principal_outstanding, $this->interest_outstanding, 2),
            $this->penalty_outstanding,
            2
        );
    }

    public function isOverdue(): bool
    {
        return $this->installments()
            ->where('status', 'overdue')
            ->exists();
    }

    public function markCompletedIfPaid(): void
    {
        if ($this->remaining_balance === '0.00') {
            $this->update([
                'status' => 'completed',
                'completed_at' => now(),
            ]);
        }
    }

    /* =====================
     | Scopes
     ===================== */

    public function scopePending(Builder $query)
    {
        return $query->where('status', 'pending');
    }

    public function scopeApproved(Builder $query)
    {
        return $query->where('status', 'approved');
    }

    public function scopeOverdue(Builder $query)
    {
        return $query->where('status', 'overdue');
    }

    public function scopeCompleted(Builder $query)
    {
        return $query->where('status', 'completed');
    }

    public function scopeDefaulted(Builder $query)
    {
        return $query->where('status', 'defaulted');
    }


}
