<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Carbon\Carbon;

class Loan extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'loan_number',
        'member_id',
        'loan_type',
        'loan_amount',
        'interest_rate',
        'duration_months',
        'installment_count',
        'monthly_installment',
        'total_interest',
        'total_payable',
        'remaining_balance',
        'paid_amount',
        'due_amount',
        'loan_date',
        'start_date',
        'end_date',
        'purpose',
        'guarantor1_id',
        'guarantor2_id',
        'status',
        'approved_by',
        'approved_date',
        'disbursed_by',
        'disbursed_date',
        'notes',
        'created_by',
    ];

    protected $casts = [
        'loan_amount' => 'decimal:2',
        'interest_rate' => 'decimal:2',
        'total_interest' => 'decimal:2',
        'total_payable' => 'decimal:2',
        'remaining_balance' => 'decimal:2',
        'paid_amount' => 'decimal:2',
        'due_amount' => 'decimal:2',
        'loan_date' => 'date',
        'start_date' => 'date',
        'end_date' => 'date',
        'approved_date' => 'datetime',
        'disbursed_date' => 'datetime',
    ];

    protected $appends = [
        'formatted_loan_amount',
        'formatted_total_payable',
        'formatted_total_interest',
        'formatted_monthly_interest',
        'status_in_bangla',
        'loan_type_in_bangla',
        'formatted_monthly_installment',
        'formatted_remaining_balance',
        'formatted_paid_amount',
        'formatted_due_amount',
        'next_due_date',
        'loan_summary',
        'monthly_interest_amount',
        'installment_schedule',
        'status_class',
        'calculation_details',
    ];

    // Boot method for auto-generating loan number
    protected static function boot()
    {
        parent::boot();

        // Generate loan number before creating - FIXED VERSION
        static::creating(function ($loan) {
            // Generate unique loan number
            if (empty($loan->loan_number)) {
                $loan->loan_number = self::generateUniqueLoanNumber();
            }
            
            // Set default values
            if (empty($loan->status)) {
                $loan->status = 'pending';
            }
            
            // Fix interest rate at 6%
            if (empty($loan->interest_rate)) {
                $loan->interest_rate = 6;
            }
            
            // Fix duration at 3 months
            if (empty($loan->duration_months)) {
                $loan->duration_months = 3;
                $loan->installment_count = 3;
            }
            
            // start_date এবং loan_date সিঙ্ক রাখুন
            if (empty($loan->start_date) && !empty($loan->loan_date)) {
                $loan->start_date = $loan->loan_date;
            }
            if (empty($loan->loan_date) && !empty($loan->start_date)) {
                $loan->loan_date = $loan->start_date;
            }
            
            if (empty($loan->start_date) && empty($loan->loan_date)) {
                $loan->start_date = now()->format('Y-m-d');
                $loan->loan_date = now()->format('Y-m-d');
            }
            
            // Calculate loan details according to your business rules
            if ($loan->loan_amount) {
                $loan->calculateLoanDetails();
            }
            
            // Set initial balances
            if (empty($loan->remaining_balance) && $loan->total_payable) {
                $loan->remaining_balance = $loan->total_payable;
            }
            
            if (empty($loan->paid_amount)) {
                $loan->paid_amount = 0;
            }
            
            if (empty($loan->due_amount) && $loan->total_payable) {
                $loan->due_amount = $loan->total_payable;
            }
            
            // Calculate monthly installment (average for reporting)
            if ($loan->total_payable) {
                $loan->monthly_installment = $loan->total_payable / 3;
            }
        });

        // After loan is created, create installments according to business rules
        static::created(function ($loan) {
            if ($loan->installment_count > 0) {
                $loan->createInstallmentsForBusinessRules();
            }
        });

        // Update remaining balance when loan is updated
        static::updated(function ($loan) {
            // Recalculate balances
            $loan->recalculateBalances();
        });
    }

    /**
     * Generate a unique loan number - IMPROVED VERSION
     */
    public static function generateUniqueLoanNumber()
    {
        $prefix = 'LN';
        $yearMonth = date('Ym'); // 202512 format
        
        // Try multiple approaches to get a unique number
        for ($attempt = 1; $attempt <= 10; $attempt++) {
            // Approach 1: Use timestamp with random part
            $timestamp = substr(time(), -6);
            $random = str_pad(rand(0, 999), 3, '0', STR_PAD_LEFT);
            $loanNumber1 = $prefix . $yearMonth . $timestamp . $random;
            
            if (!self::where('loan_number', $loanNumber1)->exists()) {
                return $loanNumber1;
            }
            
            // Approach 2: Use count-based with year-month
            $count = self::where('loan_number', 'like', $prefix . $yearMonth . '%')->count();
            $loanNumber2 = $prefix . $yearMonth . str_pad($count + 1, 5, '0', STR_PAD_LEFT);
            
            if (!self::where('loan_number', $loanNumber2)->exists()) {
                return $loanNumber2;
            }
            
            // Approach 3: Use microtime
            usleep(1000); // Wait 1ms to get different microtime
            $microtime = substr(str_replace('.', '', microtime(true)), -8);
            $loanNumber3 = $prefix . $microtime;
            
            if (!self::where('loan_number', $loanNumber3)->exists()) {
                return $loanNumber3;
            }
            
            // Approach 4: Simple increment from max
            $maxLoan = self::orderByDesc(DB::raw('CAST(loan_number AS UNSIGNED)'))->first();
            if ($maxLoan && is_numeric(substr($maxLoan->loan_number, 2))) {
                $maxNumber = (int) substr($maxLoan->loan_number, 2);
                $loanNumber4 = $prefix . str_pad($maxNumber + 1, 8, '0', STR_PAD_LEFT);
                
                if (!self::where('loan_number', $loanNumber4)->exists()) {
                    return $loanNumber4;
                }
            }
        }
        
        // Last resort: Use UUID format
        return $prefix . uniqid();
    }

    /**
     * Generate loan number for admin panel (Controller will use this)
     */
    public static function generateLoanNumber()
    {
        return self::generateUniqueLoanNumber();
    }

    /**
     * Generate alternative loan number (if duplicate)
     */
    public static function generateLoanNumberAlternative()
    {
        return self::generateUniqueLoanNumber();
    }

    /**
     * Calculate loan details according to your business rules:
     * 1. All loans are for 3 months
     * 2. Interest rate fixed at 6%
     * 3. First month: only interest (6% of principal)
     * 4. Second month: only interest (6% of principal)
     * 5. Third month: interest (6% of principal) + principal
     */
    public function calculateLoanDetails()
    {
        try {
            $principal = (float) $this->loan_amount;
            $rate = (float) $this->interest_rate; // Should be 6
            $months = 3; // Fixed at 3 months
            
            // Calculate monthly interest (6% of principal per month)
            $monthlyInterest = ($principal * $rate) / 100;
            
            // Calculate total interest for 3 months
            $this->total_interest = $monthlyInterest * $months;
            
            // Calculate total payable
            $this->total_payable = $principal + $this->total_interest;
            
            // Calculate end date if start_date is set
            if ($this->start_date && !$this->end_date) {
                $startDate = Carbon::parse($this->start_date);
                $this->end_date = $startDate->addMonths(3)->format('Y-m-d');
            }
            
            // Set monthly installment for reporting (average)
            $this->monthly_installment = $this->total_payable / $months;
            
            // Set remaining balance and due amount
            $this->remaining_balance = $this->total_payable;
            $this->due_amount = $this->total_payable;
            
            return true;
        } catch (\Exception $e) {
            \Log::error('Error calculating loan details: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Create installments according to your business rules
     */
    public function createInstallmentsForBusinessRules()
    {
        try {
            $principal = (float) $this->loan_amount;
            $monthlyInterest = ($principal * (float) $this->interest_rate) / 100;
            $startDate = Carbon::parse($this->start_date);
            
            $installments = [];
            
            // First month: Only interest
            $installments[] = [
                'loan_id' => $this->id,
                'installment_number' => 1,
                'due_date' => $startDate->copy()->addMonth(),
                'total_amount' => $monthlyInterest,
                'principal_amount' => 0,
                'interest_amount' => $monthlyInterest,
                'amount' => $monthlyInterest,
                'paid_amount' => 0,
                'status' => 'pending',
                'description' => 'প্রথম মাস - শুধু মুনাফা',
                'created_at' => now(),
                'updated_at' => now(),
            ];
            
            // Second month: Only interest
            $installments[] = [
                'loan_id' => $this->id,
                'installment_number' => 2,
                'due_date' => $startDate->copy()->addMonths(2),
                'total_amount' => $monthlyInterest,
                'principal_amount' => 0,
                'interest_amount' => $monthlyInterest,
                'amount' => $monthlyInterest,
                'paid_amount' => 0,
                'status' => 'pending',
                'description' => 'দ্বিতীয় মাস - শুধু মুনাফা',
                'created_at' => now(),
                'updated_at' => now(),
            ];
            
            // Third month: Interest + Principal
            $installments[] = [
                'loan_id' => $this->id,
                'installment_number' => 3,
                'due_date' => $startDate->copy()->addMonths(3),
                'total_amount' => $monthlyInterest + $principal,
                'principal_amount' => $principal,
                'interest_amount' => $monthlyInterest,
                'amount' => $monthlyInterest + $principal,
                'paid_amount' => 0,
                'status' => 'pending',
                'description' => 'তৃতীয় মাস - মুনাফা + আসল',
                'created_at' => now(),
                'updated_at' => now(),
            ];
            
            // Insert all installments at once
            DB::table('loan_installments')->insert($installments);
            
            \Log::info('Installments created for loan:', [
                'loan_id' => $this->id,
                'loan_number' => $this->loan_number,
                'installment_1' => $monthlyInterest,
                'installment_2' => $monthlyInterest,
                'installment_3' => $monthlyInterest + $principal,
            ]);
            
            return true;
        } catch (\Exception $e) {
            \Log::error('Error creating installments: ' . $e->getMessage());
            return false;
        }
    }

    // Recalculate balances
    public function recalculateBalances()
    {
        try {
            // Check if loan_installments table exists
            if (!Schema::hasTable('loan_installments')) {
                $this->save();
                return true;
            }
            
            // Calculate total paid amount
            $totalPaid = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'paid')
                ->sum('paid_amount');
            
            $totalPayable = (float) $this->total_payable;
            
            $this->paid_amount = (float) $totalPaid;
            $this->remaining_balance = max(0, $totalPayable - $totalPaid);
            
            // Calculate due amount (overdue installments)
            $dueAmount = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->where('due_date', '<', now())
                ->sum('total_amount');
            
            $this->due_amount = (float) $dueAmount;
            
            // Update loan status based on payments
            if ($this->remaining_balance <= 0 && in_array($this->status, ['active', 'disbursed'])) {
                $this->status = 'completed';
            } elseif ($this->due_amount > 0 && $this->status == 'active') {
                // Check if overdue for more than 30 days
                $maxOverdue = DB::table('loan_installments')
                    ->where('loan_id', $this->id)
                    ->where('status', 'pending')
                    ->where('due_date', '<', now())
                    ->select(DB::raw('MAX(DATEDIFF(NOW(), due_date)) as max_days'))
                    ->first();
                
                if ($maxOverdue && $maxOverdue->max_days > 30) {
                    $this->status = 'defaulted';
                }
            }
            
            $this->save();
            
            return true;
            
        } catch (\Exception $e) {
            \Log::error('Error in recalculateBalances for loan ' . $this->id . ': ' . $e->getMessage());
            return false;
        }
    }

    // Relationships
    public function member()
    {
        return $this->belongsTo(Member::class, 'member_id', 'member_id');
    }

    public function guarantor1()
    {
        return $this->belongsTo(Member::class, 'guarantor1_id', 'member_id');
    }

    public function guarantor2()
    {
        return $this->belongsTo(Member::class, 'guarantor2_id', 'member_id');
    }

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

    public function approver()
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    public function disburser()
    {
        return $this->belongsTo(User::class, 'disbursed_by');
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    // Accessors
    public function getFormattedLoanAmountAttribute()
    {
        return number_format((float) $this->loan_amount, 2);
    }

    public function getFormattedTotalPayableAttribute()
    {
        return number_format((float) $this->total_payable, 2);
    }

    public function getFormattedTotalInterestAttribute()
    {
        return number_format((float) $this->total_interest, 2);
    }

    public function getFormattedMonthlyInterestAttribute()
    {
        $monthlyInterest = ((float) $this->loan_amount * (float) $this->interest_rate) / 100;
        return number_format($monthlyInterest, 2);
    }

    public function getFormattedMonthlyInstallmentAttribute()
    {
        return number_format((float) $this->monthly_installment, 2);
    }

    public function getFormattedRemainingBalanceAttribute()
    {
        return number_format((float) $this->remaining_balance, 2);
    }

    public function getFormattedPaidAmountAttribute()
    {
        return number_format((float) $this->paid_amount, 2);
    }

    public function getFormattedDueAmountAttribute()
    {
        return number_format((float) $this->due_amount, 2);
    }

    public function getDurationMonthsAttribute()
    {
        return $this->attributes['duration_months'] ?? 3;
    }

    public function getRemainingBalanceAttribute()
    {
        if (isset($this->attributes['remaining_balance'])) {
            return (float) $this->attributes['remaining_balance'];
        }
        
        // If not in database, calculate it
        $totalPayable = (float) $this->total_payable;
        $paidAmount = (float) $this->paid_amount;
        return max(0, $totalPayable - $paidAmount);
    }

    public function getPaidAmountAttribute()
    {
        if (isset($this->attributes['paid_amount'])) {
            return (float) $this->attributes['paid_amount'];
        }
        
        return 0;
    }

    public function getDueAmountAttribute()
    {
        if (isset($this->attributes['due_amount'])) {
            return (float) $this->attributes['due_amount'];
        }
        
        return 0;
    }

    public function getMonthlyInterestAmountAttribute()
    {
        // Calculate monthly interest (6% of principal)
        return ((float) $this->loan_amount * (float) $this->interest_rate) / 100;
    }

    public function getNextDueDateAttribute()
    {
        try {
            if (!Schema::hasTable('loan_installments')) {
                return null;
            }
            
            $nextDue = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->where('due_date', '>', now())
                ->orderBy('due_date', 'asc')
                ->first();
                
            return $nextDue ? $nextDue->due_date : null;
            
        } catch (\Exception $e) {
            \Log::error('Error getting next due date: ' . $e->getMessage());
            return null;
        }
    }

    public function getStatusInBanglaAttribute()
    {
        $statuses = [
            'pending' => 'মুলতুবি',
            'approved' => 'অনুমোদিত',
            'rejected' => 'প্রত্যাখ্যাত',
            'disbursed' => 'বিতরণকৃত',
            'active' => 'চলমান',
            'completed' => 'সম্পন্ন',
            'defaulted' => 'ডিফল্ট',
            'cancelled' => 'বাতিল',
        ];
        
        return $statuses[$this->status] ?? $this->status;
    }

    public function getLoanTypeInBanglaAttribute()
    {
        $types = [
            'regular' => 'নিয়মিত',
            'emergency' => 'জরুরী',
            'business' => 'ব্যবসায়িক',
            'agriculture' => 'কৃষি',
            'education' => 'শিক্ষা',
            'medical' => 'চিকিৎসা',
            'housing' => 'গৃহ নির্মাণ',
            'vehicle' => 'যানবাহন',
        ];
        
        return $types[$this->loan_type] ?? $this->loan_type;
    }

    public function getStatusClassAttribute()
    {
        $classes = [
            'pending' => 'badge bg-warning',
            'approved' => 'badge bg-info',
            'disbursed' => 'badge bg-primary',
            'active' => 'badge bg-success',
            'completed' => 'badge bg-secondary',
            'defaulted' => 'badge bg-danger',
            'cancelled' => 'badge bg-dark',
            'rejected' => 'badge bg-danger',
        ];
        
        return $classes[$this->status] ?? 'badge bg-light';
    }

    public function getInstallmentScheduleAttribute()
    {
        $schedule = [];
        $principal = (float) $this->loan_amount;
        $monthlyInterest = ($principal * (float) $this->interest_rate) / 100;
        
        if ($this->start_date) {
            $startDate = Carbon::parse($this->start_date);
            
            // First month
            $schedule[] = [
                'installment_number' => 1,
                'month' => $startDate->copy()->addMonth()->translatedFormat('F Y'),
                'type' => 'শুধু মুনাফা',
                'amount' => $monthlyInterest,
                'principal' => 0,
                'interest' => $monthlyInterest,
                'due_date' => $startDate->copy()->addMonth()->format('Y-m-d'),
            ];
            
            // Second month
            $schedule[] = [
                'installment_number' => 2,
                'month' => $startDate->copy()->addMonths(2)->translatedFormat('F Y'),
                'type' => 'শুধু মুনাফা',
                'amount' => $monthlyInterest,
                'principal' => 0,
                'interest' => $monthlyInterest,
                'due_date' => $startDate->copy()->addMonths(2)->format('Y-m-d'),
            ];
            
            // Third month
            $schedule[] = [
                'installment_number' => 3,
                'month' => $startDate->copy()->addMonths(3)->translatedFormat('F Y'),
                'type' => 'মুনাফা + আসল',
                'amount' => $monthlyInterest + $principal,
                'principal' => $principal,
                'interest' => $monthlyInterest,
                'due_date' => $startDate->copy()->addMonths(3)->format('Y-m-d'),
            ];
        }
        
        return $schedule;
    }

    public function getCalculationDetailsAttribute()
    {
        $principal = (float) $this->loan_amount;
        $monthlyInterest = ($principal * 6) / 100; // 6% monthly
        
        return [
            'loan_amount' => $principal,
            'interest_rate' => '6%',
            'duration' => '3 মাস',
            'monthly_interest' => $monthlyInterest,
            'total_interest' => $monthlyInterest * 3,
            'total_payable' => $principal + ($monthlyInterest * 3),
            'installment_1' => $monthlyInterest,
            'installment_2' => $monthlyInterest,
            'installment_3' => $monthlyInterest + $principal,
        ];
    }

    public function getLoanSummaryAttribute()
    {
        try {
            $totalInstallments = 3;
            
            if (!Schema::hasTable('loan_installments')) {
                return [
                    'total_installments' => $totalInstallments,
                    'paid_installments' => 0,
                    'pending_installments' => $totalInstallments,
                    'overdue_installments' => 0,
                    'completion_percentage' => 0,
                    'remaining_months' => $totalInstallments,
                ];
            }
            
            // Get counts using DB queries
            $paidInstallments = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'paid')
                ->count();
            
            $pendingInstallments = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->count();
            
            $overdueInstallments = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->where('due_date', '<', now())
                ->count();
            
            return [
                'total_installments' => $totalInstallments,
                'paid_installments' => $paidInstallments,
                'pending_installments' => $pendingInstallments,
                'overdue_installments' => $overdueInstallments,
                'completion_percentage' => $totalInstallments > 0 ? ($paidInstallments / $totalInstallments) * 100 : 0,
                'remaining_months' => max(0, $totalInstallments - $paidInstallments),
            ];
            
        } catch (\Exception $e) {
            \Log::error('Error getting loan summary: ' . $e->getMessage());
            return [
                'total_installments' => 3,
                'paid_installments' => 0,
                'pending_installments' => 0,
                'overdue_installments' => 0,
                'completion_percentage' => 0,
                'remaining_months' => 3,
            ];
        }
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->whereIn('status', ['approved', 'disbursed', 'active']);
    }

    public function scopeOverdue($query)
    {
        return $query->where('status', 'active')
                    ->whereHas('installments', function($q) {
                        $q->where('due_date', '<', now())
                          ->where('status', 'pending');
                    });
    }

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

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

    public function scopeByMember($query, $memberId)
    {
        return $query->where('member_id', $memberId);
    }

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

    // Business Logic Methods
   public function canBeApproved()
{
    // Simple direct checks without loading relations
    if ($this->status !== 'pending') {
        return false;
    }
    
    if (!$this->guarantor1_id || !$this->guarantor2_id) {
        return false;
    }
    
    // Use DB query to check member status without loading full model
    try {
        $memberStatus = DB::table('members')
            ->where('member_id', $this->member_id)
            ->value('status');
            
        return $memberStatus === 'active';
        
    } catch (\Exception $e) {
        \Log::error('Error checking member status for loan approval: ' . $e->getMessage());
        return false;
    }
}

    public function canBeDisbursed()
    {
        return $this->status === 'approved' && 
               $this->approved_by && 
               $this->approved_date;
    }

    public function isOverdue()
    {
        try {
            if (!Schema::hasTable('loan_installments')) {
                return false;
            }
            
            return DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->where('due_date', '<', now())
                ->exists();
        } catch (\Exception $e) {
            \Log::error('Error checking overdue: ' . $e->getMessage());
            return false;
        }
    }

    // Record a payment
    public function recordPayment($amount, $paymentDate = null)
    {
        DB::beginTransaction();
        
        try {
            if (!Schema::hasTable('loan_installments')) {
                throw new \Exception('loan_installments table does not exist');
            }
            
            // Find pending installments using DB query
            $pendingInstallments = DB::table('loan_installments')
                ->where('loan_id', $this->id)
                ->where('status', 'pending')
                ->orderBy('due_date', 'asc')
                ->get();
            
            $remainingAmount = (float) $amount;
            
            foreach ($pendingInstallments as $installment) {
                if ($remainingAmount <= 0) break;
                
                $installmentAmount = (float) $installment->total_amount;
                
                if ($remainingAmount >= $installmentAmount) {
                    // Full payment for this installment
                    DB::table('loan_installments')
                        ->where('id', $installment->id)
                        ->update([
                            'status' => 'paid',
                            'payment_date' => $paymentDate ?? now(),
                            'paid_amount' => $installmentAmount,
                        ]);
                    $remainingAmount -= $installmentAmount;
                } else {
                    // Partial payment
                    DB::table('loan_installments')
                        ->where('id', $installment->id)
                        ->update([
                            'paid_amount' => $remainingAmount,
                            'status' => 'partially_paid',
                            'payment_date' => $paymentDate ?? now(),
                        ]);
                    $remainingAmount = 0;
                }
            }
            
            // Recalculate balances
            $this->recalculateBalances();
            
            // Update loan status to active if first payment and not already active
            if ($this->status == 'disbursed') {
                $this->update(['status' => 'active']);
            }
            
            DB::commit();
            
            return true;
            
        } catch (\Exception $e) {
            DB::rollback();
            \Log::error('Error recording payment: ' . $e->getMessage());
            throw $e;
        }
    }

    // Approve the loan
    public function approve($approvedBy, $remarks = null)
    {
        if (!$this->canBeApproved()) {
            throw new \Exception('এই লোনটি অনুমোদনের উপযুক্ত নয়।');
        }
        
        $this->update([
            'status' => 'approved',
            'approved_by' => $approvedBy,
            'approved_date' => now(),
            'notes' => ($this->notes ?? '') . "\nঅনুমোদন মন্তব্য: " . ($remarks ?? ''),
        ]);
        
        return $this;
    }

    // Disburse the loan
    public function disburse($disbursedBy, $remarks = null)
    {
        if (!$this->canBeDisbursed()) {
            throw new \Exception('এই লোনটি বিতরণের উপযুক্ত নয়।');
        }
        
        $this->update([
            'status' => 'disbursed',
            'disbursed_by' => $disbursedBy,
            'disbursed_date' => now(),
            'notes' => ($this->notes ?? '') . "\nবিতরণ মন্তব্য: " . ($remarks ?? ''),
        ]);
        
        return $this;
    }

    /**
     * Ensure numeric values are properly cast
     */
    public function setLoanAmountAttribute($value)
    {
        $this->attributes['loan_amount'] = (float) $value;
    }

    public function setInterestRateAttribute($value)
    {
        $this->attributes['interest_rate'] = (float) $value;
    }

    public function setTotalInterestAttribute($value)
    {
        $this->attributes['total_interest'] = (float) $value;
    }

    public function setTotalPayableAttribute($value)
    {
        $this->attributes['total_payable'] = (float) $value;
    }

    public function setRemainingBalanceAttribute($value)
    {
        $this->attributes['remaining_balance'] = (float) $value;
    }

    public function setPaidAmountAttribute($value)
    {
        $this->attributes['paid_amount'] = (float) $value;
    }

    public function setDueAmountAttribute($value)
    {
        $this->attributes['due_amount'] = (float) $value;
    }

    public function setMonthlyInstallmentAttribute($value)
    {
        $this->attributes['monthly_installment'] = (float) $value;
    }

    /**
     * Get the next available loan number without creating a loan
     */
    public static function getNextLoanNumber()
    {
        return self::generateUniqueLoanNumber();
    }
    
    /**
     * Validate if loan number already exists
     */
    public static function validateLoanNumber($loanNumber)
    {
        return !self::where('loan_number', $loanNumber)->exists();
    }
    
    /**
     * Reset loan number sequence (for testing only)
     */
    public static function resetLoanNumberSequence()
    {
        // This is just for testing - in production, you should handle duplicates differently
        \Log::warning('Loan number sequence was reset - this should only be done in development');
    }
}