<?php

namespace App\Models;

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\SoftDeletes;
use Kalnoy\Nestedset\NodeTrait;

/**
 * @property int $id
 * @property string $scope
 * @property string $description
 * @property int $bits
 * @property int|null $parent_id
 * @property int $_lft
 * @property int $_rgt
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $deleted_at
 * @property-read \Kalnoy\Nestedset\Collection<int, Permission> $children
 * @property-read int|null $children_count
 * @property-read Permission|null $parent
 * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\UserTypePermission> $userTypePermissions
 * @property-read int|null $user_type_permissions_count
 * @method static \Kalnoy\Nestedset\Collection<int, static> all($columns = ['*'])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission ancestorsAndSelf($id, array $columns = [])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission ancestorsOf($id, array $columns = [])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission applyNestedSetScope(?string $table = null)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission countErrors()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission d()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission defaultOrder(string $dir = 'asc')
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission descendantsAndSelf($id, array $columns = [])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission descendantsOf($id, array $columns = [], $andSelf = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission fixSubtree($root)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission fixTree($root = null)
 * @method static \Kalnoy\Nestedset\Collection<int, static> get($columns = ['*'])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission getNodeData($id, $required = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission getPlainNodeData($id, $required = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission getTotalErrors()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission hasChildren()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission hasParent()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission isBroken()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission leaves(array $columns = [])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission makeGap(int $cut, int $height)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission moveNode($key, $position)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission newModelQuery()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder<static>|Permission onlyTrashed()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission orWhereAncestorOf(bool $id, bool $andSelf = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission orWhereDescendantOf($id)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission orWhereNodeBetween($values)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission orWhereNotDescendantOf($id)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission query()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission rebuildSubtree($root, array $data, $delete = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission rebuildTree(array $data, $delete = false, $root = null)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission reversed()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission root(array $columns = [])
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereAncestorOf($id, $andSelf = false, $boolean = 'and')
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereAncestorOrSelf($id)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereBits($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereCreatedAt($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereDeletedAt($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereDescendantOf($id, $boolean = 'and', $not = false, $andSelf = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereDescendantOrSelf(string $id, string $boolean = 'and', string $not = false)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereDescription($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereId($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereIsAfter($id, $boolean = 'and')
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereIsBefore($id, $boolean = 'and')
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereIsLeaf()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereIsRoot()
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereLft($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereNodeBetween($values, $boolean = 'and', $not = false, $query = null)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereNotDescendantOf($id)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereParentId($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereRgt($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereScope($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission whereUpdatedAt($value)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission withDepth(string $as = 'depth')
 * @method static \Illuminate\Database\Eloquent\Builder<static>|Permission withTrashed(bool $withTrashed = true)
 * @method static \Kalnoy\Nestedset\QueryBuilder<static>|Permission withoutRoot()
 * @method static \Illuminate\Database\Eloquent\Builder<static>|Permission withoutTrashed()
 * @mixin \Eloquent
 */
class Permission extends Model
{
    use HasFactory, NodeTrait, SoftDeletes;

    protected $guarded = ['id'];

    /**
     * The attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'parent_id' => 'integer',
            'bits'      => 'integer',
        ];
    }

    public function children(): HasMany
    {
        return $this->hasMany(Permission::class, 'parent_id');
    }

    public function parent(): BelongsTo
    {
        return $this->belongsTo(Permission::class, 'parent_id');
    }

    public function userTypePermissions(): HasMany
    {
        return $this->hasMany(UserTypePermission::class);
    }
}
