<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Loan extends Model
{
    use HasFactory;

    protected $table = 'loanform';
    protected $primaryKey = 'loanid';

    protected $fillable = [
        'productid', 'customerid', 'product', 'amount', 'duration', 'rate',
        'status', 'disburseddate', 'maturitydate', 'collectiondate',
        'loannumber', 'applicationno', 'branchid', 'companyid'
    ];

    protected $casts = [
        'disburseddate' => 'datetime',
        'maturitydate' => 'datetime',
        'collectiondate' => 'datetime',
        'amount' => 'decimal:2',
        'rate' => 'decimal:2',
    ];

    /**
     * Relationship with Customer
     */
    public function customer()
    {
        return $this->belongsTo(Customer::class, 'customerid', 'id');
    }

    /**
     * Relationship with LoanType (product)
     */
    public function loanProduct()
    {
        return $this->belongsTo(LoanType::class, 'productid', 'id');
    }

    /**
     * Relationship with Repayments
     */
    public function repayments()
    {
        return $this->hasMany(Repayment::class, 'rloanid', 'loanid');
    }

    /**
     * Relationship with InterestIncome
     */
    public function interestIncome()
    {
        return $this->hasMany(InterestIncome::class, 'iloanid', 'loanid');
    }

    /**
     * Scope for active loans
     */
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    /**
     * Scope for disbursed loans
     */
    public function scopeDisbursed($query)
    {
        return $query->whereNotNull('disburseddate');
    }

    /**
     * Get loan status badge color
     */
    public function getStatusColorAttribute()
    {
        return match($this->status) {
            'active' => 'green',
            'disbursed' => 'blue',
            'closed' => 'gray',
            'defaulted' => 'red',
            'written_off' => 'orange',
            default => 'gray'
        };
    }

    /**
     * Calculate total interest charged for this loan
     */
    public function getTotalInterestChargedAttribute()
    {
        return $this->interestIncome()->sum('charge');
    }

    /**
     * Calculate total amount repaid (principal + interest)
     */
    public function getTotalRepaidAttribute()
    {
        return $this->repayments()->successful()->sum('rtotal');
    }

    /**
     * Calculate principal repaid
     */
    public function getPrincipalRepaidAttribute()
    {
        return $this->repayments()->successful()->sum('rprincipal');
    }

    /**
     * Calculate interest repaid
     */
    public function getInterestRepaidAttribute()
    {
        return $this->repayments()->successful()->sum('rinterest');
    }

    /**
     * Calculate total amount to be repaid (principal + total interest)
     */
    public function getTotalRepaymentAttribute()
    {
        $totalInterestCharged = $this->getTotalInterestChargedAttribute();
        return $this->amount + $totalInterestCharged;
    }

    /**
     * Calculate outstanding balance
     */
    public function getOutstandingBalanceAttribute()
    {
        $totalRepayment = $this->getTotalRepaymentAttribute();
        $totalRepaid = $this->getTotalRepaidAttribute();
        
        return max(0, $totalRepayment - $totalRepaid);
    }

    /**
     * Calculate collection progress percentage
     */
    public function getCollectionProgressAttribute()
    {
        $totalRepayment = $this->getTotalRepaymentAttribute();
        $totalRepaid = $this->getTotalRepaidAttribute();
        
        if ($totalRepayment <= 0) {
            return 0;
        }

        $progress = ($totalRepaid / $totalRepayment) * 100;
        return min(100, round($progress, 2));
    }

    /**
     * Get next payment due date
     */
    public function getNextPaymentDueDateAttribute()
    {
        // Find the latest repayment date and calculate next due date
        $lastRepayment = $this->repayments()
            ->successful()
            ->latest('rdate')
            ->first();

        if ($lastRepayment && $this->disburseddate) {
            return $lastRepayment->rdate->addMonth();
        }

        return $this->disburseddate ? $this->disburseddate->addMonth() : null;
    }

    /**
     * Check if loan is overdue
     */
    public function getIsOverdueAttribute()
    {
        $nextDueDate = $this->getNextPaymentDueDateAttribute();
        return $nextDueDate && $nextDueDate->lt(now());
    }

    /**
     * Get days overdue
     */
    public function getDaysOverdueAttribute()
    {
        if (!$this->is_overdue) {
            return 0;
        }

        $nextDueDate = $this->getNextPaymentDueDateAttribute();
        return $nextDueDate->diffInDays(now());
    }
}