<?php

namespace App\Models;

use App\Database\Eloquent\CustomerBuilder;
use App\Models\Concerns\NormalizesPhoneNumbers;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Notifications\Notifiable;

class Customer extends Model
{
    use HasFactory, Notifiable, NormalizesPhoneNumbers;

    protected $fillable = [
        'branch_id','customer_number','identity_mode','first_name','middle_name','last_name','gender','date_of_birth','nin','phone',
        'alternative_phone','email','occupation','employer_business','monthly_income','marital_status','photo_path','status','created_by','updated_by',
    ];

    protected function casts(): array { return ['date_of_birth'=>'date','monthly_income'=>'decimal:2']; }

    protected function phoneNumberAttributes(): array
    {
        return ['phone', 'alternative_phone'];
    }

    public function newEloquentBuilder($query)
    {
        return new CustomerBuilder($query);
    }

    public function branch(): BelongsTo { return $this->belongsTo(Branch::class); }
    public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); }
    public function address(): HasOne { return $this->hasOne(CustomerAddress::class); }
    public function nextOfKin(): HasMany { return $this->hasMany(NextOfKin::class); }
    public function guarantors(): HasMany { return $this->hasMany(Guarantor::class); }
    public function documents(): HasMany { return $this->hasMany(CustomerDocument::class); }
    public function blacklistRecords(): HasMany { return $this->hasMany(BlacklistRecord::class); }
    public function riskProfile(): HasOne { return $this->hasOne(CustomerRiskProfile::class); }
    public function creditScoreHistories(): HasMany { return $this->hasMany(CustomerCreditScoreHistory::class)->orderByDesc('calculated_at')->orderByDesc('id'); }
    public function latestCreditScoreHistory(): HasOne { return $this->hasOne(CustomerCreditScoreHistory::class)->latestOfMany('calculated_at'); }
    public function collaterals(): HasMany { return $this->hasMany(Collateral::class); }
    public function loans(): HasMany { return $this->hasMany(Loan::class)->latest('id'); }
    public function loanPayments(): HasMany { return $this->hasMany(LoanPayment::class)->orderByDesc('payment_date'); }
    public function statementEntries(): HasMany { return $this->hasMany(CustomerStatementEntry::class)->orderBy('entry_date')->orderBy('id'); }

    public function getFullNameAttribute(): string
    {
        return trim(collect([$this->first_name,$this->middle_name,$this->last_name])->filter()->join(' '));
    }

    public function hasActiveBlacklist(): bool
    {
        return $this->blacklistRecords()->where('type','blacklist')->where('status','active')->exists();
    }
}
