<?php

namespace App\Repositories\Core\Auth;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

use Laratrust\Traits\LaratrustUserTrait;
use LangleyFoxall\LaravelNISTPasswordRules\PasswordRules;

use App\Models\Core\Auth\User;
use App\Models\Core\Auth\RoleUser;

use App\Repositories\Core\Upload;

class Users
{
    use LaratrustUserTrait;

    public static function isAdmin()
    {
        return (self::hasRole('admin')) ? true : false;
    }

    public static function getInfo($id = false)
    {
        $id = $id ? $id : self::getId();
        if (!$id) {
            return false;
        }
        $user = self::get($id);
        $data = $user->toArray();
        $data['name'] = $user->name;
        $data['avatar'] = self::getAvatar($id);
        $data['roles'] = $user->roles->pluck('id')->toArray();
        $data['permissions'] = $user->allPermissions()->pluck('id')->toArray();
        return $data;
    }

    public static function store($data)
    {
        if ($data['id'] ?? false) {
            unset($data['password']);
        }
        $user = ($data['id'] ?? false) ? self::update($data) : self::create($data);
        $user->roles()->sync(array_keys($data['roles'] ?? []));
        return $user;
    }

    public static function create($data)
    {
        $data['password'] = $data['password'] ?? Hash::make($data['password']);
        $data['remember_token'] = Str::random(32);
        $data['active'] = true;
        $user = User::create($data);
        PasswordSecurities::create($user->id);
        return $user;
    }

    public static function update($data, $id = false)
    {
        $id = $id ? $id : $data['id'];
        $user = self::get($id);
        $ret = $user->update($data);
        return $user;
    }

    public static function get($id = false)
    {
        $id = $id ? $id : self::getId();
        return User::findOrFail($id);
    }

    public static function getId()
    {
        $user = self::getUser();
        return $user ? $user->id : false;
    }

    public static function getName($id = false)
    {
        $user = $id ? self::get($id) : self::getUser();
        return $user->first_name . ' ' . $user->last_name;
    }

    public static function getUsername($id = false)
    {
        return $id ? self::get($id)->username : self::getUser()->username;
    }

    public static function getUser()
    {
        return Auth::user();
    }

    public static function isConnected()
    {
        return Auth::check();
    }

    public static function getOptions()
    {
        return User::orderBy('name')->pluck('name', 'id')->toArray();
    }

    public static function delete($id)
    {
        $ret = RoleUser::byUser($id)->delete();
        return User::destroy($id);
    }

    public static function getListByRole($role)
    {
        return self::selectOptions()->orderBy('name')->whereRoleIs($role)->get();
    }

    public static function hasRole($role, $user = false)
    {
        $user = $user ? $user : self::getUser();
        return $user ? $user->hasRole($role) : false;
    }

    public static function hasPermission($permission, $user = false)
    {
        if (self::isAdmin()) {
            return true;
        }
        $user = $user ? $user : self::getUser();
        $permissions = self::getPermissions($user);
        return $user ? self::checkPermission($permissions, $permission) : false;
        // TODO why is posing problem ???
            // return $user ? $user->hasPermission($permission) : false;
    }

    public static function checkPermission($permissions, $permission)
    {
        if (!strpos($permission, '*')) {
            return in_array($permission, $permissions);
        }
        $permission = str_replace('*', '', $permission);
        foreach ($permissions as $item) {
            if (stripos($item, $permission) !== false) {
                return true;
            }
        }
        return false;
    }

    public static function getRoles($user = false)
    {
        $user = $user ? $user : self::getUser();
        return $user ? $user->roles->pluck('name')->toArray() : false;
    }

    public static function getRolesToEdit()
    {
        return Roles::getListByRights();
    }
    
    public static function getPermissions($user = false)
    {
        $user = $user ? $user : self::getUser();
        return $user ? $user->allPermissions()->pluck('name')->toArray() : false;
    }

    public static function getByTeam($id)
    {
        return User::byTeam($id)->get();
    }

    public static function getByUniqueTeam($id)
    {
        return User::byTeam($id)->byUniqueTeam()->get();
    }

    public static function destroyByUniqueTeam($id)
    {
        return User::byTeam($id)->byUniqueTeam()->delete();
    }

    public static function getAvatar($user_id)
    {
        $avatar = self::get($user_id)->avatar;
        if (!$avatar) {
            return '/assets/img/no-avatar.png';
        }
        $path = '/images/avatars/';
        return $path . $avatar;
    }

    public static function selectOptions()
    {
        return User::select('id', DB::raw("concat(last_name,' ',first_name) as name"));
    }

    public static function count()
    {
        return User::count();
    }

    public static function select_all_by_status_id($status_id)
    {
        return User::byStatus($status_id);
    }

    public static function select_by_id($user_id)
    {
        return User::with('status')->find($user_id)->toArray();
    }

    public static function select_by_name($name)
    {
        return self::getByName($name)->toArray();
    }

    public static function getByUsername($username)
    {
        return User::byUsername($username)->withTrashed()->first();
    }

    public static function toggle_active($id, $active)
    {
        return self::get($id)->update(['active' => $active]);
    }

    public static function uploadAvatar($request)
    {
        $targetDir = 'uploads';
        $file = $request->file('avatar_file');
        $data = Upload::getData($file);
        $file_uploaded = Upload::store($file, $targetDir);
        $tab = pathinfo($file_uploaded);
        $response['name'] = $tab['basename'];
        return $response;
    }

    public static function update_avatar($id, $avatar)
    {
        return User::find($id)->update(['avatar' => $avatar]);
    }

    public static function update_password($id, $password)
    {
        $password = Hash::make($password);
        return User::find($id)->update(['password' => $password]);
    }

    public static function validate($username, $field = 'current_password')
    {
        return PasswordRules::changePassword($username, $field);
    }
}
