<?php

namespace Modules\Accounts\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Modules\Accounts\Models\Traits\AccountRelationshipTrait;
use Modules\Core\Enums\StatusEnum;
use Modules\Core\Traits\AuditableTrait;
use Modules\Core\Traits\HasStatus;

class ChartOfAccount extends Model
{
    use AccountRelationshipTrait,
        HasStatus,
        AuditableTrait,
        SoftDeletes;

    protected $fillable = [
        'account_code',
        'account_name',
        'parent_id',
        'is_group',
        'account_type',
        'is_cash',
        'is_bank',
        'description',
        'default',
        'is_system_generated',
        'status',
        'created_by',
        'updated_by',
    ];

    protected function casts(): array
    {
        return [
            'account_code' => 'integer',
            'parent_id' => 'integer',
            'is_group' => 'boolean',
            'is_cash' => 'boolean',
            'is_bank' => 'boolean',
            'default' => 'boolean',
            'is_system_generated' => 'boolean',
        ];
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('status', StatusEnum::ACTIVE);
    }

    public function scopeByType(Builder $query, ?string $type): Builder
    {
        return $type ? $query->where('account_type', $type) : $query;
    }

    public function scopeAccountCode(Builder $query, int $accountCode): Builder
    {
        return $query->where('account_code', $accountCode);
    }

    public function scopeGroup(Builder $query): Builder
    {
        return $query->where('is_group', true);
    }

    public function scopeIsGroup(Builder $query, bool|int $isGroup): Builder
    {
        return $query->where('is_group', $isGroup);
    }

    public function scopeLedger(Builder $query): Builder
    {
        return $query->where('is_group', false);
    }

    public function scopeRoots(Builder $query): Builder
    {
        return $query->whereNull('parent_id');
    }

    public function scopeParent(Builder $query, $parentId): Builder
    {
        return $query->where('parent_id', $parentId);
    }

    public function scopeSearch(Builder $query, ?string $search): Builder
    {
        if (blank($search)) {
            return $query;
        }

        return $query->where(function ($q) use ($search) {
            $like = "%{$search}%";

            $q->where('account_code', 'LIKE', $like)
                ->orWhere('account_name', 'LIKE', $like);
        });
    }

    public function scopeCash(Builder $query): Builder
    {
        return $query->where('is_cash', true);
    }

    public function scopeBank(Builder $query): Builder
    {
        return $query->where('is_bank', true);
    }
    
    public function scopeCashOrBank(Builder $query): Builder
    {
        return $query->where(function (Builder $q) {
            $q->cash()->orWhere(fn(Builder $sub) => $sub->bank());
        });
    }
}
