<?php

namespace App\Models;

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\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;

class Branch extends Model
{
    use HasFactory, NormalizesPhoneNumbers;

    protected $fillable = [
        'business_id', 'name', 'code', 'location', 'address', 'region', 'district',
        'phone', 'email', 'manager_user_id', 'opening_date', 'status',
    ];

    protected static function booted(): void
    {
        static::creating(function (Branch $branch): void {
            if (blank($branch->code)) $branch->code = static::generateCode((int) $branch->business_id);
        });
        static::updating(function (Branch $branch): void {
            if ($branch->isDirty('code')) $branch->code = $branch->getOriginal('code');
        });
    }

    public static function generateCode(int $businessId): string
    {
        do { $code = 'BR-'.Str::upper(Str::random(6)); }
        while (static::query()->where('business_id', $businessId)->where('code', $code)->exists());
        return $code;
    }

    protected function casts(): array { return ['opening_date' => 'date']; }
    public function business(): BelongsTo { return $this->belongsTo(Business::class); }
    public function manager(): BelongsTo { return $this->belongsTo(User::class, 'manager_user_id'); }
    public function users(): BelongsToMany { return $this->belongsToMany(User::class)->withPivot('is_primary')->withTimestamps(); }
    public function loanProducts(): BelongsToMany { return $this->belongsToMany(LoanProduct::class, 'branch_loan_product'); }
    public function collaterals(): HasMany { return $this->hasMany(Collateral::class); }
    public function loans(): HasMany { return $this->hasMany(Loan::class); }

    public function allowsLoanProduct(LoanProduct $loanProduct): bool
    {
        if ((int) $loanProduct->business_id !== (int) $this->business_id || $loanProduct->status !== 'active') {
            return false;
        }

        if ($this->relationLoaded('loanProducts')) {
            return $this->loanProducts->isEmpty() || $this->loanProducts->contains('id', $loanProduct->id);
        }

        if (! $this->loanProducts()->exists()) {
            return true;
        }

        return $this->loanProducts()->whereKey($loanProduct->id)->exists();
    }
}
