<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class LoanPenalty extends Model
{
    protected $fillable = [
        'loan_id',
        'penalty_type',
        'penalty_amount',
        'penalty_rate',
        'penalty_date',
        'reason',
        'status',
        'assessed_by',
        'applied_at',
        'waived_by',
        'waived_at',
        'waiver_notes',
    ];

    protected $casts = [
        'penalty_amount' => 'decimal:2',
        'penalty_rate' => 'decimal:2',
        'penalty_date' => 'date',
        'applied_at' => 'datetime',
        'waived_at' => 'datetime',
    ];

    public function loan(): BelongsTo
    {
        return $this->belongsTo(Loan::class);
    }

    public function assessor(): BelongsTo
    {
        return $this->belongsTo(User::class, 'assessed_by');
    }

    public function waiver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'waived_by');
    }

    public function isPending(): bool
    {
        return $this->status === 'pending';
    }

    public function isApplied(): bool
    {
        return $this->status === 'applied';
    }

    public function isWaived(): bool
    {
        return $this->status === 'waived';
    }

    public function apply(): void
    {
        $this->update([
            'status' => 'applied',
            'applied_at' => now(),
        ]);
    }

    public function waive(User $user, string $notes = null): void
    {
        $this->update([
            'status' => 'waived',
            'waived_by' => $user->id,
            'waived_at' => now(),
            'waiver_notes' => $notes,
        ]);
    }

    /**
     * Calculate penalty amount based on type
     */
    public static function calculatePenalty(Loan $loan, string $type, float $rate = null, float $fixedAmount = null): float
    {
        return match ($type) {
            'fixed' => $fixedAmount ?? 0,
            'percentage' => $loan->outstanding_balance * ($rate / 100),
            'progressive' => self::calculateProgressivePenalty($loan, $rate),
            default => 0,
        };
    }

    /**
     * Calculate progressive penalty based on days overdue
     */
    private static function calculateProgressivePenalty(Loan $loan, float $rate = null): float
    {
        $daysOverdue = $loan->days_overdue ?? 0;
        $baseRate = $rate ?? 0.5; // Default 0.5% per day

        // Progressive rates: 0.5% for first 30 days, 1% for 31-60 days, 2% for 61+ days
        if ($daysOverdue <= 30) {
            $progressiveRate = $baseRate;
        } elseif ($daysOverdue <= 60) {
            $progressiveRate = $baseRate * 2;
        } else {
            $progressiveRate = $baseRate * 4;
        }

        return $loan->outstanding_balance * ($progressiveRate / 100) * $daysOverdue;
    }
}
