<?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;
    }
}
