<?php

namespace Ignite\Core\Entities;

use Ignite\Core\Collections\PermissionsCollection;

/**
 * Ignite\Core\Entities\Permission
 *
 * @property int $id
 * @property string $key
 * @property string|null $description
 * @property bool|null $is_user_defined
 * @property int|null $status
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property-read \Ignite\Core\Collections\GroupsCollection|\Ignite\Core\Entities\Group[] $groups
 * @property-read int|null $groups_count
 * @method static PermissionsCollection|static[] all($columns = ['*'])
 * @method static PermissionsCollection|static[] get($columns = ['*'])
 * @method static \Illuminate\Database\Eloquent\Builder|Permission newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Permission newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Permission query()
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereDescription($value)
 * @method static Builder|Base whereHasPermission(string $permission, ?\Ignite\Core\Entities\User $user = null)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereIsUserDefined($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereKey($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Permission whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class Permission extends Base
{
    public const ACTIVE = 1;
    public const INACTIVE = 0;

    /**
     * The custom table name.
     * @var string
     */
    protected $table = 'core_permission';

    /**
     * @var array
     */
    protected $casts = [
        'is_user_defined' => 'bool',
    ];

    /**
     * Eloquent event listeners.
     */
    public static function boot()
    {
        parent::boot();
        static::saving(function (Permission $model) {
            if (empty($model->status)) {
                $model->status = static::ACTIVE;
            }
        });
        static::saved(function () {
            app('authorization')->forgetPermissions()->registerPermissions();
        });
        static::deleting(function (Permission $model) {
            if (! $model->isUserDefined()) {
                throw new \Exception('You cannot delete a system defined user permission.');
            }
        });
    }

    /**
     * The relationship to the permission group.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function groups()
    {
        return $this->belongsToMany(Group::class, 'core_group_permission', 'permission_id', 'group_id')->withTimestamps();
    }

    /**
     * Create a new Eloquent Collection instance.
     *
     * @param array $models
     * @return \Ignite\Core\Collections\PermissionsCollection
     */
    public function newCollection(array $models = [])
    {
        return new PermissionsCollection($models);
    }

    /**
     * Determine if the group is user-defined.
     *
     * @return bool
     */
    public function isUserDefined()
    {
        return (bool)$this->is_user_defined;
    }

    /**
     * Determine if the group is active.
     *
     * @return bool
     */
    public function isActive()
    {
        return $this->status === static::ACTIVE;
    }

    /**
     * Determine if the group is inactive.
     *
     * @return bool
     */
    public function isInactive()
    {
        return $this->status === static::INACTIVE;
    }
}
