<?php

namespace App\Packages\v4\User\Extensions\Auth;

use App\Packages\User\Models\User;
use App\Packages\User\Models\UserToken;
use Illuminate\Http\Request;
use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;

/**
 * @TODO: Refactore
 *
 * Class AccessTokenGuard
 * @package App\Extensions\Auth
 */
class AccessTokenGuard implements Guard
{
	use GuardHelpers;

	private $inputKey = '';

	private $storageKey = '';

	private $request;

	/**
	 * AccessTokenGuard constructor.
	 *
	 * @param UserProvider $provider
	 * @param Request $request
	 * @param $configuration
	 */
	public function __construct(UserProvider $provider, Request $request, $configuration)
	{
		$this->provider = $provider;
		$this->request = $request;
		// key to check in request
		$this->inputKey = isset($configuration['input_key']) ? $configuration['input_key'] : 'access_token';
		// key to check in database
		$this->storageKey = isset($configuration['storage_key']) ? $configuration['storage_key'] : 'access_token';
	}

	/**
	 * @return \Illuminate\Contracts\Auth\Authenticatable|null
	 */
	public function user()
	{
		if (!is_null($this->user)) {
			return $this->user;
		}
		$user = null;
		// retrieve via token
		$token = $this->getTokenForRequest();
		if (!empty($token)) {
			// the token was found, how you want to pass?
            /** @var User $user */
			$user = $this->provider->retrieveByToken($this->storageKey, $token);
		}

		return $this->user = $user;
	}

	/**
	 * Get the token for the current request.
	 * @return string
	 */
	public function getTokenForRequest()
	{
		$token = $this->request->query($this->inputKey);
		if (empty($token)) {
			$token = $this->request->input($this->inputKey);
		}
		if (empty($token)) {
			$token = $this->request->bearerToken();
		}

//		if (empty($token)) {
//		    $token = UserToken::query()->orderByRaw('random()')->first()->access_token;
//        }

		return $token;
	}

	/**
	 * Validate a user's credentials.
	 *
	 * @param  array $credentials
	 *
	 * @return bool
	 */
	public function validate(array $credentials = [])
	{
		if (empty($credentials[$this->inputKey])) {
			return false;
		}

		$credentials = [$this->storageKey => $credentials[$this->inputKey]];

		if ($this->provider->retrieveByCredentials($credentials)) {
			return true;
		}

		return false;
	}
}