<?php

namespace App\Traits;

use App\Role;
use App\Permission;

trait HasRolesAndPermissions
{
    /**
     * @return mixed
     */
    public function roles()
    {
        return $this->belongsToMany(Role::class, 'users_roles');
    }

    /**
     * @return mixed
     */
    public function permissions()
    {
        return $this->belongsToMany(Permission::class, 'users_permissions');
    }

    /**
     * @param mixed ...$roles
     *
     * @return bool
     */
    public function hasRole(...$roles)
    {
        foreach ($roles as $role) {
            if ($this->roles->contains('slug', $role)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param $permission
     *
     * @return bool
     */
    protected function hasPermission($permission)
    {
        return (bool) $this->permissions->where('slug', $permission->slug)->count();
    }

    protected function hasPermissions($permission)
    {
        return (bool) $this->permissions->whereIn('slug', $permission)->count();
    }

    /**
     * @param $permission
     *
     * @return bool
     */
    protected function hasPermissionTo($permission)
    {
        return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
    }

    /**
     * @param $permission
     *
     * @return bool
     */
    public function hasPermissionThroughRole($permission)
    {
        foreach ($permission->roles as $role) {
            if ($this->roles->contains($role)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return mixed
     */
    protected function getAllPermissions(array $permissions)
    {
        return Permission::whereIn('slug', $permissions)->get();
    }

    /**
     * @param mixed ...$permissions
     *
     * @return $this
     */
    public function givePermissionsTo(...$permissions)
    {
        $permissions = $this->getAllPermissions($permissions);
        if ($permissions === null) {
            return $this;
        }
        $this->permissions()->saveMany($permissions);

        return $this;
    }

    /**
     * @param mixed ...$permissions
     *
     * @return $this
     */
    public function deletePermissions(...$permissions)
    {
        $permissions = $this->getAllPermissions($permissions);
        $this->permissions()->detach($permissions);

        return $this;
    }

    /**
     * @param mixed ...$permissions
     *
     * @return HasRolesAndPermissions
     */
    public function refreshPermissions(...$permissions)
    {
        $this->permissions()->detach();

        return $this->givePermissionsTo($permissions);
    }

    // public function checkPermission($permission)
    // {dd($this->permissions);
    //     return (bool) $this->permissions->where('slug', $permission)->count();
    // }
    public function checkPermission($permission_slug)
    {
        $permission = Permission::where('slug', $permission_slug)->first();
        if ($permission) {
            foreach ($permission->roles as $role) {
                if ($this->roles->contains($role)) {
                    return true;
                }
            }

            return $this->hasPermission($permission);
        }

        return false;
    }

    public function checkPermissions($permission_slug)
    {
        $permissions = Permission::whereIn('slug', $permission_slug)->with('roles')->get();

        if ($permissions) {
            foreach ($permissions as $permission) {
                foreach ($permission->roles as $role) {
                    if ($this->roles->contains($role)) {
                        return true;
                    }
                    // return  $this->hasPermissions($permissions->pluck('slug')->toArray());
                }
            }

            // return $this->hasPermissions($permissions->pluck('slug')->toArray());
        }

        // return 'false';
        return false;
    }

    public function userPermissions()
    {
        $roles = auth()->user()->roles()->pluck('role_id');
        // $roles = [2];
        $permissions = Permission::whereHas('roles', function ($query) use ($roles) {
            $query->whereIn('role_id', $roles);
        })->select('slug')->get();

        if ($permissions) {
            return $permissions;
        }

        return collect([]);
    }


    public function userRoles()
    {
        $userRoles = auth()->user()->roles()->pluck('role_id');
        // $roles = [2];
        $roles = Role::whereIn('id', $userRoles)->select('slug')->get();

        if ($roles) {
            return $roles;
        }

        return collect([]);
    }
}
