<?php

namespace App\Models;

use Illuminate\Support\Str;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    protected $table = "users";

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        "name",
        "surname",
        "username",
        "password",
        "email",
        "country_code",
        "mobile_number",
        "role_id"
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        "password",
        "remember_token",
        "is_active"
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [];


    public function role()
    {
        return $this->belongsTo(Role::class);
    }

    public function userProfile()
    {
        return $this->hasOne(UserProfile::class);
    }

    public function post()
    {
        return $this->hasMany(Post::class);
    }

    public function comments()
    {
        return $this->hasManyThrough(Comment::class, Post::class);
    }

    public function hasPermission($permission, $id = null, $any = false)
    {

        $userPermissions = null;
        $flag = null;

        if ($id != null) $userPermissions = User::find($id)->role->permission->pluck("name");
        else $userPermissions = $this->role->permission->pluck("name");

        if ($any) {
            foreach ($permission as $p) {
                if ($this->hasPermission($p)) {
                    return true;
                }
            }
            return false;
        }

        if (is_string($permission)) {
            return $userPermissions->contains($permission);
        }

        if (is_array($permission)) {
            foreach ($permission as $p) {
                if ($this->hasPermission($p)) {
                    $flag = true;
                } else {
                    $flag = false;
                    break;
                }
            }
        }

        return $flag;
    }

    public function hasAllPermissions(array $permissions = array(), $id = null, $any = false)
    {
        return $this->hasPermission($permissions, $id, $any);
    }

    public function hasAnyPermission(array $permissions = array(), $id = null, $any = true)
    {
        return $this->hasPermission($permissions, $id, $any);
    }

    public function hasRole($role)
    {
        return $role === $this->role->name;
    }

    public function isAdmin()
    {
        return $this->hasRole("admin");
    }

    public function isAdminOrEditor()
    {
        return $this->hasRole("admin") || $this->hasRole("editor");
    }

    public function getFullName($id = null)
    {

        if ($id != null) {
            $user = User::find($id);
            return $user->name . " " . $user->surname;
        }

        return $this->name . " " . $this->surname;
    }

    public function getPostsCount($id)
    {
        return Post::where("user_id", $id)->count();
    }

    public function generateTemporaryPassword($length = 20)
    {
        return bcrypt(Str::random($length));
    }

    public function generateSecurityCode($min = 10000, $max = 99999)
    {
        return rand($min, $max);
    }

    public function generateVerifyToken($length = 32)
    {
        return Str::random($length);
    }

    public function generateProfileLink($name, $surname)
    {

        $profileLinks = UserProfile::pluck("profile_link")->toArray();
        $link = strtolower($name) . strtolower($surname);

        foreach ($profileLinks as $profileLink) {
            if ($profileLink == $link) {
                $link .= "-" . strtolower(Str::random(10));
                break;
            }
        }

        return $link;
    }

    public function generateTechnoblogEmail($name, $surname)
    {

        $emails = UserProfile::pluck("technoblog_email")->toArray();
        $newEmail = strtolower($name) . "." . strtolower($surname) . "@technoblog.com";

        foreach ($emails as $email) {
            if ($email == $newEmail) {
                $position = strlen($name) + strlen($surname) + 1;
                $id = UserProfile::latest("id")->first()->id + 1;
                $newEmail = substr_replace($newEmail, "." . $id, $position, 0);
                break;
            }
        }

        return $newEmail;
    }
}
